Skip to content

Commit

Permalink
First commit of android_intent plugin. (flutter#99)
Browse files Browse the repository at this point in the history
* First commit of android_intent plugin.

* Comments and formatting fixes

* Add back the iOS dummy code for android_intent as per discussion on github.com/flutter/flutter/issues/10530.

* Review comments

* missing meta dependency. Caught by pub publish --dryrun
  • Loading branch information
mehmetf authored Jun 6, 2017
1 parent c58d066 commit 807205a
Show file tree
Hide file tree
Showing 68 changed files with 1,609 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/android_intent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.DS_Store
.atom/
.idea
.packages
.pub/
build/
ios/.generated/
packages
pubspec.lock
3 changes: 3 additions & 0 deletions packages/android_intent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.0.1

* Initial release
27 changes: 27 additions & 0 deletions packages/android_intent/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 changes: 43 additions & 0 deletions packages/android_intent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Android Intent Plugin for Flutter

This plugin allows Flutter apps to launch arbitrary intents when the platform
is Android. If the plugin is invoked on iOS, it will crash your app. In checked
mode, we assert that the platform should be Android.

Use it by specifying action, category, data and extra arguments for the intent.
It does not support returning the result of the launched activity. Sample usage:

```
if (platform.isAndroid) {
AndroidIntent intent = new AndroidIntent(
action: 'action_view',
data: 'https://play.google.com/store/apps/details?'
'id=com.google.android.apps.myapp',
arguments: {'authAccount': currentUserEmail},
);
await intent.launch();
}
```

See documentation on the AndroidIntent class for details on each parameter.

Action parameter can be any action including a custom class name to be invoked.
If a standard android action is required, the recommendation is to add support
for it in the plugin and use an action constant to refer to it. For instance:

`'action_view'` translates to `android.os.Intent.ACTION_VIEW`

Feel free to add support for additional Android intents.

> Note that a similar method does not currently exist for iOS. Instead, the
system plugin ([UrlLauncher](https://docs.flutter.io/flutter/services/UrlLauncher-class.html))
can be used for deep linking. UrlLauncher can also be used for creating
ACTION_VIEW intents for Android, however this intent plugin also allows
clients to set extra parameters for the intent.

## Getting Started

For help getting started with Flutter, view our online
[documentation](http://flutter.io/).

For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code).
12 changes: 12 additions & 0 deletions packages/android_intent/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

/gradle
/gradlew
/gradlew.bat
32 changes: 32 additions & 0 deletions packages/android_intent/android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
group 'io.flutter.plugins.androidintent'
version '1.0-SNAPSHOT'

buildscript {
repositories {
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}

allprojects {
repositories {
jcenter()
}
}

apply plugin: 'com.android.library'

android {
compileSdkVersion 25
buildToolsVersion '25.0.3'

defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
lintOptions {
disable 'InvalidPackage'
}
}
1 change: 1 addition & 0 deletions packages/android_intent/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.gradle.jvmargs=-Xmx1536M
1 change: 1 addition & 0 deletions packages/android_intent/android/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'android_intent'
7 changes: 7 additions & 0 deletions packages/android_intent/android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.plugins.androidintent"
android:versionCode="1"
android:versionName="0.0.1">

<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.androidintent;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import java.util.Map;

/** AndroidIntentPlugin */
@SuppressWarnings("unchecked")
public class AndroidIntentPlugin implements MethodCallHandler {
private final Context context;

/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel =
new MethodChannel(registrar.messenger(), "plugins.flutter.io/android_intent");
channel.setMethodCallHandler(new AndroidIntentPlugin(registrar.activity()));
}

private AndroidIntentPlugin(Activity activity) {
this.context = activity;
}

private String convertAction(String action) {
switch (action) {
case "action_view":
return Intent.ACTION_VIEW;
case "action_voice":
return Intent.ACTION_VOICE_COMMAND;
default:
return action;
}
}

private Bundle convertArguments(Map<String, ?> arguments) {
Bundle bundle = new Bundle();
for (String key : arguments.keySet()) {
Object value = arguments.get(key);
if (value instanceof Integer) {
bundle.putInt(key, (Integer) value);
} else if (value instanceof String) {
bundle.putString(key, (String) value);
} else if (value instanceof Boolean) {
bundle.putBoolean(key, (Boolean) value);
} else if (value instanceof Double) {
bundle.putDouble(key, (Double) value);
} else if (value instanceof Long) {
bundle.putLong(key, (Long) value);
} else {
throw new UnsupportedOperationException("Unsupported type " + value);
}
}
return bundle;
}

@Override
public void onMethodCall(MethodCall call, Result result) {
String action = convertAction((String) call.argument("action"));
// Build intent
Intent intent = new Intent(action);
if (call.argument("category") != null) {
intent.addCategory((String) call.argument("category"));
}
if (call.argument("data") != null) {
intent.setData(Uri.parse((String) call.argument("data")));
}
if (call.argument("arguments") != null) {
intent.putExtras(convertArguments((Map) call.argument("arguments")));
}
Log.i("android_intent plugin", "Sending intent " + intent);
context.startActivity(intent);
result.success(null);
}
}
15 changes: 15 additions & 0 deletions packages/android_intent/android_intent.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="FLUTTER_MODULE_TYPE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/packages" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart Packages" level="project" />
<orderEntry type="library" name="Dart SDK" level="project" />
</component>
</module>
12 changes: 12 additions & 0 deletions packages/android_intent/android_intent_android.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/android">
<sourceFolder url="file://$MODULE_DIR$/android/app/src/main/java" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Flutter for Android" level="project" />
</component>
</module>
10 changes: 10 additions & 0 deletions packages/android_intent/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.DS_Store
.atom/
.idea
.packages
.pub/
build/
ios/.generated/
packages
pubspec.lock
.flutter-plugins
8 changes: 8 additions & 0 deletions packages/android_intent/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# android_intent_example

Demonstrates how to use the android_intent plugin.

## Getting Started

For help getting started with Flutter, view our online
[documentation](http://flutter.io/).
12 changes: 12 additions & 0 deletions packages/android_intent/example/android.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/android">
<sourceFolder url="file://$MODULE_DIR$/android/app/src/main/java" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Flutter for Android" level="project" />
</component>
</module>
13 changes: 13 additions & 0 deletions packages/android_intent/example/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
GeneratedPluginRegistrant.java

/gradle
/gradlew
/gradlew.bat
49 changes: 49 additions & 0 deletions packages/android_intent/example/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withInputStream { stream ->
localProperties.load(stream)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 25
buildToolsVersion '25.0.3'

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "io.flutter.plugins.androidintentexample"
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}

flutter {
source '../..'
}

dependencies {
androidTestCompile 'com.android.support:support-annotations:25.0.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.plugins.androidintentexample"
android:versionCode="1"
android:versionName="0.0.1">

<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />

<!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>

<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application android:name="io.flutter.app.FlutterApplication" android:label="android_intent_example" android:icon="@mipmap/ic_launcher">
<activity android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Loading

0 comments on commit 807205a

Please sign in to comment.