在Unity应用程序启动时阅读Android intent额外数据

时间:2016-03-19 05:54:18

标签: c# android android-intent unity3d android-implicit-intent

我正在使用自定义隐式意图从另一个Android应用程序启动Unity应用程序。这工作正常,但我无法弄清楚如何读取Unity中的意图额外数据?

ANDROID打算推出UNITY APP

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_new, container, false);

    //Get all text fields
    conditionWrapper = (TextInputLayout) view.findViewById(R.id.input_condition_wrapper);
    ageWrapper = (TextInputLayout) view.findViewById(R.id.input_age_wrapper);

    //Listener for create button
    createButton = (Button) view.findViewById(R.id.input_submit);
    createButton.setOnClickListener(this);

    // Inflate the layout for this fragment
    return view;
}

//Create/submit button click
@Override
public void onClick(View v) {
    //Get input values
    String condition = conditionWrapper.getEditText().getText().toString();
    String age = ageWrapper.getEditText().getText().toString();

    //If all the validation passes, submit the form. Else, show errors
    if (!isEmpty(condition) & !isEmpty(age)) {
        //Submit form data
    } else {
        if (isEmpty(condition)) {
            conditionWrapper.setError("Condition required");
        } else {
            conditionWrapper.setErrorEnabled(false);
        }

        if (isEmpty(age)) {
            ageWrapper.setError("Age required");
        } else {
            ageWrapper.setErrorEnabled(false);
        }
    }
}

//Check if a string is empty
public boolean isEmpty(String string) {
    if (string.equals("")) {
        return true;
    } else {
        return false;
    }
}

UNITY APP AndroidManifest.xml

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

我的场景中有一个附带脚本的GameObject。在start方法中,我有这个代码来尝试读取与intent

一起传递的额外数据
<intent-filter>
     <action android:name="com.company.unityapp.MyMethod" />
     <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

这不起作用,参数总是空的。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:10)

我花了很长时间才弄明白这一点。在线发现的所有解决方案只是部分完成。下面是使用自定义隐式Intent从另一个Android应用程序启动Unity应用程序的完整解决方案,以及如何访问Unity内部Intent发送的额外数据。

要完成此操作,您需要创建一个Android插件,Unity将使用该插件访问Intent额外数据。

ANDROID PLUGIN:

您需要将classes.jar从Unity安装文件夹复制到android插件文件夹/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

这里重要的是使用的包名: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构建文件:

将以下内容添加到app gradle构建文件中,以便能够创建与Unity一起使用的.jar

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)

将创建的AndroidPlugin.jar复制到Unity Assets / Plugins / Android

UNITY APP:

PlayerSettings中的包标识符设置为与Android插件中设置的相同 - com.company.plugin

在Assets / Plugins / Android

中创建自定义AndroidManifest.xml文件

这里重要的是使用插件中使用的相同package名称。 另请注意意图名称: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>

创建一个名为AccessManager的统一脚本,并将脚本附加到场景中的游戏对象。 OnAccessToken是接收从android插件发送的消息的方法,将包含从intent发送的额外数据。

public class accessManager : MonoBehaviour {

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

ANDROID APP:

创建一个标准的Android应用程序,它将启动Unity应用程序并发送Intent额外数据

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);
}

答案 1 :(得分:0)

您不需要插件即可实现此目的。像这样从Android上获取您的意图:

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");
}

然后在您的统一Monobehaviour课程中,像这样收到它

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;
}

信用:https://wenrongdev.com/get-android-intent-data-for-unity/