如果应用程序已通过深层链接打开,则Android深层链接无效

时间:2016-03-11 02:14:04

标签: android deep-linking

如果已通过深层链接打开该应用,则深层链接无效。

但是,如果我打开应用程序不是通过触发深层链接,例如单击应用程序图标打开应用程序。然后触发深层链接将始终有效。

详细信息如下:

所以我在AndroidManifest中设置了这样的活动,即LaunchActivity。

<activity
    android:name="some.package.name.LaunchActivity"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.SomeTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <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="dlscheme" android:host="dlhost" />
    </intent-filter>
</activity>

在LaunchActivity中,我会在onCreate()中打印一个日志,表明它已存在。

我用过

adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name

测试深层链接。

随着应用被杀,我使用了上面的命令。它可以打开应用程序并路由到正确的活动,没问题。 并有以下日志。

adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name
Starting: Intent { act=android.intent.action.VIEW dat=dlscheme://dlhost/param pkg=some.package.name }
Status: ok
Activity: some.package.name/.activity.LaunchActivity
ThisTime: 898
TotalTime: 898
WaitTime: 919
Complete

但是,如果我再次输入相同的命令,而不会杀死应用程序。 它只会打开应用程序,但不会打开正确的活动,并生成以下日志。

adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name
Starting: Intent { act=android.intent.action.VIEW dat=dlscheme://dlhost/param pkg=some.package.name }
Warning: Activity not started, its current task has been brought to the front
Status: ok
Activity: some.package.name/.activity.LaunchActivity
ThisTime: 0
TotalTime: 0
WaitTime: 6
Complete

使用这个额外的行

Warning: Activity not started, its current task has been brought to the front

我实际上也尝试过使用这个chrome意图的网站:

intent://dlhost/param#Intent;scheme=dlscheme;package=some.package.name;end

它会表现得一样。

8 个答案:

答案 0 :(得分:8)

在LaunchActivity活动代码

中的清单中添加android:launchMode="singleTop"

答案 1 :(得分:6)

在项目的清单文件中,您需要将跟随添加到主要活动中。

android:launchMode="singleTask"

并处理onNewIntent()

中的深层链接
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recipe);
    onNewIntent(getIntent());
}

protected void onNewIntent(Intent intent) {
    String action = intent.getAction();
    String data = intent.getDataString();
    if (Intent.ACTION_VIEW.equals(action) && data != null) {
        String recipeId = data.substring(data.lastIndexOf("/") + 1);
        Uri contentUri = RecipeContentProvider.CONTENT_URI.buildUpon()
                .appendPath(recipeId).build();
        showRecipe(contentUri);
    }
}

答案 2 :(得分:6)

我发现添加android:launchMode="singleTask"有效。 singleTop对我不起作用。

答案 3 :(得分:5)

在项目的清单文件中,您需要将跟随添加到主要活动中。

android:launchMode="singleTask"

所以,在清单中,你会有类似下面的内容:

<activity android:name="some.package.name.LaunchActivity" 
      android:launchMode="singleTask">
      android:screenOrientation="portrait"
      android:theme="@style/Theme.SomeTheme">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
          <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="dlscheme" android:host="dlhost" />
          </intent-filter>
 </activity>

基本上它的作用是创建一个新任务,一个新实例将作为根任务推送到任务。但是,如果任何任务中存在任何活动实例,系统会通过onNewIntent()方法调用将意图路由到该活动实例。在此模式下,活动实例可以推送到同一任务。如果用户从当前活动中单击BACK键,系统将使用户返回上一个活动。

另一方面,在singleTop中,如果活动实例已存在于当前任务的顶部且系统路由意图此活动,则不会创建新实例,因为它将触发onNewIntent( )方法而不是创建新对象。

可以找到更多信息here

答案 4 :(得分:4)

Mainefest文件看起来像这个样本

<activity
                    android:name=".user.HomeActivity"
                    android:screenOrientation="portrait"
                    android:exported="true"
                    android:launchMode="singleTop"
                    android:windowSoftInputMode="stateAlwaysHidden"
                    android:theme="@style/AppTheme.NoActionBar" >
                    <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="example"/>
                        <data android:host="example.com"
                            android:pathPrefix="/deeplink"/>
                        <action android:name="android.intent.action.MAIN" />
                    </intent-filter>
                </activity>

HomeActivity

@Override
            protected void onNewIntent(Intent intent) {
                super.onNewIntent(intent);
                Uri data = intent.getData();
                if (data != null)
                    callDeep(data);
                setIntent(intent);
                Log.d("DeepLinking", "new intent value==>" + data + "==== value===>");
            }
        //or in on create 
        @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_home);
          Uri data = intent.getData();
                Log.d("DeepLinking", "intent value==>" + data + "==== value===>" + bundle + "===action==>" + action);
        }

答案 5 :(得分:2)

“使用您的活动”

在清单中添加android:launchMode =“singleTop”
  

如果你的启动模式是默认的,那么这个警告出现“警告:活动没有启动,它的当前任务已被带到前面”,因为每次创建活动的新实例时,如果你使用单顶启动模式然后onNewIntent调用()方法而不是创建新对象

答案 6 :(得分:2)

从日志中说出&#34;警告:活动未启动,其当前任务已被带到前面&#34;,因此未创建活动的新实例。在这种情况下,新意图将重定向到活动的onNewIntent(意图意图)。

在您的情况下,我怀疑您没有覆盖此方法,并将从活动的onCreate()方法中提取信息。

而是创建一个类似extractDataFromIntentAndProcess(Intent intent)的方法,并从oncreate方法调用它(extractDataFromIntentAndProcess(getIntent()))&amp;也来自您活动的onNewIntent方法(extractDataFromIntentAndProcess(intent))。

答案 7 :(得分:0)

我在NavigationUI和AppLink集成方面遇到了类似的问题。我正在遵循单一活动架构,因此,如果该应用程序已存在于任务堆栈中,并且我想使用AppLink打开单独的片段,则它将无法与launchMode =“ singleTask”一起使用。我什至尝试了finishOnTaskLaunch,但似乎没有任何作用。

然后遍历文档(我应该首先完成),我知道在上述情况下,意图是在活动类的 onNewIntent()中收到的,将意图从当前片段重定向到我们需要调用的所需片段:

//获取活动类的navController实例,然后

navController.handleDeepLink(intent)

这解决了我在任务中已有其他片段时通过AppLink / DeepLink打开所需片段的问题。

希望我能够提供帮助。