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.
You don't need a plugin to achieve this. Do your intent from Android like this:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.game");
launchIntent.putExtra("my_text", "Some data params");
if(launchIntent != null){
startActivity(launchIntent);
}else{
Log.d("Unity", "Couldnt start unity game");
}
Then in your unity Monobehaviour Class, receive it like this
private void Awake () {
getIntentData ();
}
private bool getIntentData () {
#if (!UNITY_EDITOR && UNITY_ANDROID)
return CreatePushClass (new AndroidJavaClass ("com.unity3d.player.UnityPlayer"));
#endif
return false;
}
public bool CreatePushClass (AndroidJavaClass UnityPlayer) {
#if UNITY_ANDROID
AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity");
AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject> ("getIntent");
AndroidJavaObject extras = GetExtras (intent);
if (extras != null) {
string ex = GetProperty (extras, "my_text");
return true;
}
#endif
return false;
}
private AndroidJavaObject GetExtras (AndroidJavaObject intent) {
AndroidJavaObject extras = null;
try {
extras = intent.Call<AndroidJavaObject> ("getExtras");
} catch (Exception e) {
Debug.Log (e.Message);
}
return extras;
}
private string GetProperty (AndroidJavaObject extras, string name) {
string s = string.Empty;
try {
s = extras.Call<string> ("getString", name);
} catch (Exception e) {
Debug.Log (e.Message);
}
return s;
}
Credit: https://wenrongdev.com/get-android-intent-data-for-unity/
(updated) https://wenrongdev.com/posts/get-android-intent-data-for-unity/
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With