Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/android_intent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.3.6

* Marks the `action` parameter as optional
* Adds an assertion to ensure the intent receives an action, component or both.

## 0.3.5+1

* Make the pedantic dev_dependency explicit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public IntentSender(@Nullable Activity activity, @Nullable Context applicationCo
* back to {@code applicationContext} and adds {@link Intent#FLAG_ACTIVITY_NEW_TASK} to the intent
* before launching it.
*
* @param action the Intent action, such as {@code ACTION_VIEW}.
* @param action the Intent action, such as {@code ACTION_VIEW} if non-null.
* @param flags forwarded to {@link Intent#addFlags(int)} if non-null.
* @param category forwarded to {@link Intent#addCategory(String)} if non-null.
* @param data forwarded to {@link Intent#setData(Uri)} if non-null and 'type' parameter is null.
Expand All @@ -57,7 +57,7 @@ public IntentSender(@Nullable Activity activity, @Nullable Context applicationCo
* Intent#setDataAndType(Uri, String)}
*/
void send(
String action,
@Nullable String action,
@Nullable Integer flags,
@Nullable String category,
@Nullable Uri data,
Expand All @@ -70,8 +70,11 @@ void send(
return;
}

Intent intent = new Intent(action);
Intent intent = new Intent();

if (action != null) {
intent.setAction(action);
}
if (flags != null) {
intent.addFlags(flags);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
}

private static String convertAction(String action) {
if (action == null) {
return null;
}

switch (action) {
case "action_view":
return Intent.ACTION_VIEW;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,34 @@ public void onMethodCall_setsComponentName() {
Intent intent = shadowOf((Application) context).getNextStartedActivity();
assertNotNull(intent);
assertNotNull(intent.getComponent());
assertEquals(expectedComponent.getPackageName(), intent.getPackage());
assertEquals(expectedComponent.flattenToString(), intent.getComponent().flattenToString());
assertEquals("foo", intent.getAction());
assertEquals("io.flutter.plugins.androidintent", intent.getPackage());
assertEquals(
"io.flutter.plugins.androidintent/MainActivity", intent.getComponent().flattenToString());
}

@Test
public void onMethodCall_setsOnlyComponentName() {
sender.setApplicationContext(context);
Map<String, Object> args = new HashMap<>();
ComponentName expectedComponent =
new ComponentName("io.flutter.plugins.androidintent", "MainActivity");
args.put("package", expectedComponent.getPackageName());
args.put("componentName", expectedComponent.getClassName());
Result result = mock(Result.class);
ShadowPackageManager shadowPm =
shadowOf(ApplicationProvider.getApplicationContext().getPackageManager());
shadowPm.addActivityIfNotPresent(expectedComponent);

methodCallHandler.onMethodCall(new MethodCall("launch", args), result);

verify(result, times(1)).success(null);
Intent intent = shadowOf((Application) context).getNextStartedActivity();
assertNotNull(intent);
assertNotNull(intent.getComponent());
assertEquals("io.flutter.plugins.androidintent", intent.getPackage());
assertEquals(
"io.flutter.plugins.androidintent/MainActivity", intent.getComponent().flattenToString());
}

@Test
Expand Down
16 changes: 11 additions & 5 deletions packages/android_intent/lib/android_intent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AndroidIntent {
/// If not null, then [package] but also be provided.
/// [type] refers to the type of the intent, can be null.
const AndroidIntent({
@required this.action,
this.action,
this.flags,
this.category,
this.data,
Expand All @@ -38,25 +38,28 @@ class AndroidIntent {
this.componentName,
Platform platform,
this.type,
}) : assert(action != null),
}) : assert(action != null || componentName != null,
'action or component (or both) must be specified'),
_channel = const MethodChannel(_kChannelName),
_platform = platform ?? const LocalPlatform();

/// This constructor is only exposed for unit testing. Do not rely on this in
/// app code, it may break without warning.
@visibleForTesting
AndroidIntent.private({
@required this.action,
@required Platform platform,
@required MethodChannel channel,
this.action,
this.flags,
this.category,
this.data,
this.arguments,
this.package,
this.componentName,
this.type,
}) : _channel = channel,
}) : assert(action != null || componentName != null,
'action or component (or both) must be specified'),
_channel = channel,
_platform = platform;

/// This is the general verb that the intent should attempt to do. This
Expand Down Expand Up @@ -131,7 +134,10 @@ class AndroidIntent {
if (!_platform.isAndroid) {
return;
}
final Map<String, dynamic> args = <String, dynamic>{'action': action};
final Map<String, dynamic> args = <String, dynamic>{};
if (action != null) {
args['action'] = action;
}
if (flags != null) {
args['flags'] = convertFlags(flags);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/android_intent/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: android_intent
description: Flutter plugin for launching Android Intents. Not supported on iOS.
homepage: https://github.com/flutter/plugins/tree/master/packages/android_intent
version: 0.3.5+1
version: 0.3.6

flutter:
plugin:
Expand Down
40 changes: 34 additions & 6 deletions packages/android_intent/test/android_intent_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void main() {
setUp(() {
mockChannel = MockMethodChannel();
});

group('AndroidIntent', () {
test('pass right params', () async {
androidIntent = AndroidIntent.private(
Expand All @@ -32,26 +33,53 @@ void main() {
'type': 'video/*',
}));
});
test('pass null value to action param', () async {

test('raises error if neither an action nor a component is provided', () {
try {
androidIntent = AndroidIntent(data: 'https://flutter.io');
fail('should raise an AssertionError');
} on AssertionError catch (e) {
expect(e.message, 'action or component (or both) must be specified');
} catch (e) {
fail('should raise an AssertionError');
}
});
test('can send Intent with an action and no component', () async {
androidIntent = AndroidIntent.private(
action: null,
channel: mockChannel,
platform: FakePlatform(operatingSystem: 'android'));
action: 'action_view',
channel: mockChannel,
platform: FakePlatform(operatingSystem: 'android'),
);
await androidIntent.launch();
verify(mockChannel.invokeMethod<void>('launch', <String, Object>{
'action': null,
'action': 'action_view',
}));
});

test('can send Intent with a component and no action', () async {
androidIntent = AndroidIntent.private(
package: 'packageName',
componentName: 'componentName',
channel: mockChannel,
platform: FakePlatform(operatingSystem: 'android'),
);
await androidIntent.launch();
verify(mockChannel.invokeMethod<void>('launch', <String, Object>{
'package': 'packageName',
'componentName': 'componentName',
}));
});

test('call in ios platform', () async {
androidIntent = AndroidIntent.private(
action: null,
action: 'action_view',
channel: mockChannel,
platform: FakePlatform(operatingSystem: 'ios'));
await androidIntent.launch();
verifyZeroInteractions(mockChannel);
});
});

group('convertFlags ', () {
androidIntent = const AndroidIntent(
action: 'action_view',
Expand Down