Android短信Deep Link启动应用:如何在新任务中打开
Hey Tony, 我完全懂你这个困扰——通过短信里的Deep Link唤起应用时,它居然和短信在同一个任务栈里,按返回键直接回到短信,完全不像点击桌面图标启动那样有独立的任务栈。这种外部唤起的场景确实和App内部跳转Activity的情况不一样,得从Manifest配置+代码逻辑两方面入手解决,下面给你两种可行的方案:
方案一:通过Manifest配置直接指定任务栈行为
这是最直接的方法,给处理Deep Link的Activity配置合适的属性,让它启动时自动进入应用专属的任务栈:
打开你的
AndroidManifest.xml,找到处理Deep Link的Activity标签,添加以下属性:android:launchMode="singleTask":确保该Activity在应用的任务栈中只会存在一个实例,并且如果应用已经在后台有任务栈,会直接把这个任务栈调到前台(和点击桌面图标效果一致)。android:taskAffinity="${applicationId}":明确指定该Activity的任务亲和性为你的应用包名(这其实是默认值,但如果之前修改过taskAffinity,一定要显式加上),这样系统会把它放到应用自己的任务栈里,而不是短信的任务栈。
示例配置代码:
<activity android:name=".activities.DeepLinkHandlerActivity" android:launchMode="singleTask" android:taskAffinity="${applicationId}"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 这里替换成你的Deep Link Scheme和Host --> <data android:scheme="myapp" android:host="product" /> </intent-filter> </activity>如果你的Deep Link是直接唤起主Activity,那只需要确保主Activity的
launchMode保持默认的standard,同时在它的intent-filter里加上Deep Link的配置即可,这样外部唤起时会自动使用应用的任务栈。
方案二:通过代码逻辑纠正任务栈(适合复杂场景)
如果Manifest配置无法满足你的需求(比如需要动态处理不同的Deep Link场景),可以在处理Deep Link的Activity中加入逻辑,强制将页面切换到应用的任务栈:
在处理Deep Link的Activity的onCreate方法中,检查当前Activity是否处于任务栈的根位置,如果不是,就启动主Activity并传递Deep Link数据,然后结束当前Activity:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 检查当前Activity是否是任务栈的根(如果不是,说明是被外部应用嵌套唤起的) if (!isTaskRoot()) { Intent incomingIntent = getIntent(); if (Intent.ACTION_VIEW.equals(incomingIntent.getAction())) { // 构建启动主Activity的Intent,传递Deep Link的所有数据 Intent mainIntent = new Intent(this, MainActivity.class); mainIntent.setAction(incomingIntent.getAction()); mainIntent.setData(incomingIntent.getData()); mainIntent.putExtras(incomingIntent.getExtras()); // 标记为新任务,并清除主Activity之上的所有页面(和点击图标启动的逻辑一致) mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(mainIntent); } // 结束当前在外部任务栈中的Activity finish(); return; } // 这里写正常的Deep Link处理逻辑 handleDeepLink(getIntent()); }
这样处理后,用户点击短信里的Deep Link时,会直接打开应用自己的任务栈(如果应用已经在后台就调到前台,没启动就新建),完全和点击桌面图标启动的体验一致。
内容的提问来源于stack exchange,提问作者Tony_89

