深层链接和多个应用实例

Har*_*Ram 48 android deep-linking

我在我的应用中实现了深层链接.我在清单文件中添加了此intent过滤器,并且深层链接正在运行.

<intent-filter>
    <action android:name="android.intent.action.VIEW" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
    <category android:name="android.intent.category.BROWSABLE" /> 
    <category android:name="android.intent.category.VIEW" /> 
    <data
        android:host="www.mywebsite.com"
        android:pathPrefix="/something"
        android:scheme="http" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)

问题是通过深度链接,我的应用程序将在当前应用程序之上启动.如果我在Gmail中并点击了一个链接,那么我的应用就会在Gmail上启动.我想以不同方式启动我的应用程序.

如果我的应用已经在后台运行,我点击Gmail中的一个重定向到我的应用的链接,我将同时运行两个应用实例; 一个在后台,另一个在Gmail之上.我想一次只运行我的应用程序的一个实例,因此它不在当前应用程序(Gmail)之上.我怎样才能做到这一点?

Mic*_*cky 73

你需要为你的Manifest中的Activity做一些事情.

android:launchMode="singleTask"
Run Code Online (Sandbox Code Playgroud)

这告诉系统始终启动Activity的现有实例(如果已创建).

然后你可以通过覆盖方法来处理Intent

onNewIntent 
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅http://developer.android.com/guide/topics/manifest/activity-element.html.

  • 如果活动B设置了`singleTask`,那么如果已经创建了B,那么堆栈中的所有活动都将被销毁.因此活动A将被销毁.如果活动B尚未在堆栈中,它将在活动A之上打开. (5认同)
  • 如果该应用程序已打开并且当前显示在活动A,但深层链接指向活动B,该怎么办? (3认同)

use*_*281 10

接受的答案对我不起作用,这是做了什么:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
Run Code Online (Sandbox Code Playgroud)

来自官方文件:

如果已设置,并且正在启动的活动已在当前任务中运行,则不会启动该活动的新实例,而是将关闭其上的所有其他活动,并将此Intent传递给(现在开启) top)旧活动作为新的意图.

  • 不工作......它仍在创建我的应用活动的两个实例 (5认同)

小智 5

好吧,我们在深层链接方面遇到了几个问题。喜欢:

  1. 同一个链接只点击两次,第一次点击触发正确的视图
  2. 打开多个实例
  3. 由于他们的网络浏览器,whatsapp 或 facebook 中的链接在 whatsapp 本身中打开了一个视图。
  4. 在 android 6 上只打开一个实例,但只处理第一个意图,第二个和第三个打开应用程序但没有动作,因为意图数据没有以某种方式改变。

因此,以下不是问题的明确答案,而是我们遇到的几个问题的全面解决方案。

我们的解决方案:

a) 创建了一个新的 FragmentActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2); //well can be anything some "loading screen"

    Intent intent = getIntent();
    String intentUrl = intent.getDataString();
    Intent newIntent = new Intent(this, MainActivity.class);
    newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    newIntent.putExtra("intentUrl",intentUrl);
    newIntent.setAction(Long.toString(System.currentTimeMillis()));

    startActivity(newIntent);
    finish();
}
Run Code Online (Sandbox Code Playgroud)

b) 清单:

    <activity
        android:name="YOUR.NEW.FRAGMENT.ACTIVITY"
        android:label="@string/app_name"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data android:scheme="http" />
            <data android:scheme="https" />
            <data android:scheme="scheme1" /> <!-- sheme1://-->
            <data android:host="yourdomain.com" />
            <data android:host="www.yourdomain.com" />
        </intent-filter>
    </activity>
Run Code Online (Sandbox Code Playgroud)

c) 通过调用以下示例函数来处理活动 onCreate() 和 onResume() 中传递的新意图:

private void handleUrl(Intent i){
    String intentUrl = null;
    if (i != null) {
        intentUrl = i.getStringExtra("intentUrl");
        if (intentUrl == null){
            //hmm intent is damaged somehow
        } else {
            //because of onResume()
            if ( i.getBooleanExtra("used",false) ) {
                return;
            }
            i.putExtra("used", true);

           //DO SOMETHING WITH YOUR URL HERE
    }       
}
Run Code Online (Sandbox Code Playgroud)