Read Android intent extra data on Unity app launch

Hardy Le Roux picture Hardy Le Roux · Mar 19, 2016 · Viewed 8.5k times · Source

I am launching an Unity application from another Android application using a custom implicit intent. This is working fine, but I cannot figure out how to read the intent extra data in Unity?

ANDROID INTENT TO LAUNCH UNITY APP

i=new Intent();
i.setAction("com.company.unityapp.MyMethod");
i.putExtra("KEY","This is the message string");
startActivity(i);

UNITY APP AndroidManifest.xml

<intent-filter>
     <action android:name="com.company.unityapp.MyMethod" />
     <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

I have a GameObject in my scene with a script attached. Inside the start method I have this code to try and read the extra data that was passed along with the intent

AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");
bool hasExtra = intent.Call<bool> ("hasExtra", "arguments");

if (hasExtra) {
 AndroidJavaObject extras = intent.Call<AndroidJavaObject> ("getExtras");
 arguments = extras.Call<string> ("getString", "arguments");
}

This is not working and arguments is always empty. Any help would be appreciated.

Answer

Hardy Le Roux picture Hardy Le Roux · Mar 24, 2016

It took me quite some time to figure this out. All solutions found online were only partly complete. Below is the full solution for launching a Unity application from another android application using a custom implicit Intent and also how to access the extra data sent with the Intent inside Unity.

To accomplish this you need to create a Android plugin that will be used by Unity to access the Intent extra data.

ANDROID PLUGIN:


You need to copy the classes.jar from Unity installation folder to the android plugin folder /lib/classes.jar

public class MainActivity extends UnityPlayerActivity {

  @Override
  protected void onNewIntent(Intent intent) {
      super.onNewIntent(intent);
      handleNewIntent(intent);
  }

  private void handleNewIntent(Intent intent){
      String text = intent.getStringExtra("KEY");
      UnityPlayer.UnitySendMessage("AccessManager","OnAccessToken", text);
  }
}

AndroidManifest.xml

Important here is the package name used: com.company.plugin

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.plugin">
    <application
        android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
        android:supportsRtl="true" android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Gradle build file:

Add the following to the app gradle build file to be able to create a .jar to be used with Unity

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    sourceSets {
        main {
            java {
                srcDir 'src/main/java'
            }
        }
    }       
...
...

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
    compile files('libs/classes.jar')
}

//task to delete the old jar
task deleteOldJar(type: Delete) {
    delete 'release/AndroidPlugin.jar'
}

//task to export contents as jar
task exportJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('release/')
    include('classes.jar')
    ///Rename the jar
    rename('classes.jar', 'AndroidPlugin.jar')
}

exportJar.dependsOn(deleteOldJar, build)

Copy the created AndroidPlugin.jar to Unity Assets/Plugins/Android

UNITY APP:


Set the bundle identifier in PlayerSettings to be the same as set in the Android Plugin - com.company.plugin

Create custom AndroidManifest.xml file in Assets/Plugins/Android

Important here is to use the same package name as used in the plugin. Also note the Intent name: com.company.plugin.do

AndroidManifest.XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.plugin"
      android:versionCode="1" android:versionName="1.0">
    <uses-sdk android:minSdkVersion="9" />
    <application android:label="@string/app_name">
        <activity android:name=".MainActivity" android:label="@string/app_name"
          android:launchMode="singleTask" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="sensor">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.company.plugin.do" />
                <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

Create a unity script named AccessManager and attach the script to a game object in the scene. OnAccessToken is the method that will receive the message sent from the android plugin and will contain the extra data sent from the intent.

public class accessManager : MonoBehaviour {

    public void OnAccessToken(string accessToken)
    {
        Debug.Log("Message Received!!!! :" + accessToken);
    }
}

ANDROID APP:

Create a standard Android application that will launch the Unity Application and send the Intent extra data

public void LaunchUnityApp(){
    Intent i=new Intent();
    i.setAction("com.company.plugin.do");
    i.setType("text/plain");
    i.putExtra("KEY","This is the text message sent from Android");
    startActivity(i);
}