Add support for structured values (#249)
diff --git a/packages/android_intent/README.md b/packages/android_intent/README.md index afa88ce..144ffbb 100644 --- a/packages/android_intent/README.md +++ b/packages/android_intent/README.md
@@ -29,6 +29,12 @@ Feel free to add support for additional Android intents. +The Dart values supported for the arguments parameter, and their corresponding +Android values, are listed [here](https://flutter.io/platform-channels/#codec). +On the Android side, the arguments are used to populate an Android `Bundle` +instance. This process currently restricts the use of lists to homogeneous lists +of integers or strings. + > Note that a similar method does not currently exist for iOS. Instead, the [url_launcher](https://pub.dartlang.org/packages/url_launcher) plugin can be used for deep linking. Url launcher can also be used for creating
diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java index f757b47..5c35f7a 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java
@@ -15,6 +15,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; +import java.util.ArrayList; import java.util.Map; /** AndroidIntentPlugin */ @@ -58,6 +59,20 @@ bundle.putDouble(key, (Double) value); } else if (value instanceof Long) { bundle.putLong(key, (Long) value); + } else if (value instanceof byte[]) { + bundle.putByteArray(key, (byte[]) value); + } else if (value instanceof int[]) { + bundle.putIntArray(key, (int[]) value); + } else if (value instanceof long[]) { + bundle.putLongArray(key, (long[]) value); + } else if (value instanceof double[]) { + bundle.putDoubleArray(key, (double[]) value); + } else if (isTypedArrayList(value, Integer.class)) { + bundle.putIntegerArrayList(key, (ArrayList<Integer>) value); + } else if (isTypedArrayList(value, String.class)) { + bundle.putStringArrayList(key, (ArrayList<String>) value); + } else if (isStringKeyedMap(value)) { + bundle.putBundle(key, convertArguments((Map<String, ?>) value)); } else { throw new UnsupportedOperationException("Unsupported type " + value); } @@ -65,6 +80,32 @@ return bundle; } + private boolean isTypedArrayList(Object value, Class<?> type) { + if (!(value instanceof ArrayList)) { + return false; + } + ArrayList list = (ArrayList) value; + for (Object o : list) { + if (!(o == null || type.isInstance(o))) { + return false; + } + } + return true; + } + + private boolean isStringKeyedMap(Object value) { + if (!(value instanceof Map)) { + return false; + } + Map map = (Map) value; + for (Object key : map.keySet()) { + if (!(key == null || key instanceof String)) { + return false; + } + } + return true; + } + @Override public void onMethodCall(MethodCall call, Result result) { String action = convertAction((String) call.argument("action"));
diff --git a/packages/android_intent/example/android/app/src/main/AndroidManifest.xml b/packages/android_intent/example/android/app/src/main/AndroidManifest.xml index 81c36a7..ac963f7 100644 --- a/packages/android_intent/example/android/app/src/main/AndroidManifest.xml +++ b/packages/android_intent/example/android/app/src/main/AndroidManifest.xml
@@ -10,6 +10,7 @@ to allow setting breakpoints, to provide hot reload, etc. --> <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/> <!-- io.flutter.app.FlutterApplication is an android.app.Application that calls FlutterMain.startInitialization(this); in its onCreate method.
diff --git a/packages/android_intent/example/lib/main.dart b/packages/android_intent/example/lib/main.dart index 48a67b6..f2e2a8e 100644 --- a/packages/android_intent/example/lib/main.dart +++ b/packages/android_intent/example/lib/main.dart
@@ -25,30 +25,36 @@ } class MyHomePage extends StatelessWidget { + void _createAlarm() { + final AndroidIntent intent = const AndroidIntent( + action: 'android.intent.action.SET_ALARM', + arguments: const <String, dynamic>{ + 'android.intent.extra.alarm.DAYS': const <int>[2, 3, 4, 5, 6], + 'android.intent.extra.alarm.HOUR': 21, + 'android.intent.extra.alarm.MINUTES': 30, + 'android.intent.extra.alarm.SKIP_UI': true, + 'android.intent.extra.alarm.MESSAGE': 'Create a Flutter app', + }, + ); + intent.launch(); + } + @override Widget build(BuildContext context) { Widget body; if (const LocalPlatform().isAndroid) { - body = new GestureDetector( - child: const Center( - child: const Text( - 'Click here to launch play store with New York Times app.')), - onTap: () { - final AndroidIntent intent = const AndroidIntent( - action: 'action_view', - data: - 'https://play.google.com/store/apps/details?id=com.nytimes.android'); - intent.launch(); - }); + body = new InkWell( + child: const Text('Tap here to set an alarm\non weekdays at 9:30pm.'), + onTap: _createAlarm, + ); } else { - body = const Center( - child: const Text('This plugin only works with Android')); + body = const Text('This plugin only works with Android'); } return new Scaffold( appBar: new AppBar( title: const Text('Plugin example app'), ), - body: body, + body: new Center(child: body), ); } }