Android 通过短信跳转到APP指定页面

实现思路

点击短信链接 --> 系统6.0+? (否)--> 弹出提示框 --> APP

​ (是)--> VerifyOk? (否) --> 弹出提示框 --> APP

​ (是)--> VerifyOk? (是) --> APP

大致分为两种启动方式:Deep_Link、App_Link

Deep_Link

Android系统中点击链接会发送一条 action = View 的隐式意图,只需要在APP的对应页面添加Intent过滤器去满足这条规则即可。

 <activity
     android:name=".WelcomeActivity">
     
     <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="http"/>
     </intent-filter>
 </activity>

添加以上代码,应用就可以响应以http开头的链接。

上面代码只能说能用,但是没有达到我们要求,不是只唤醒我们自己的APP还响应了其他内容。

跳转指定页面

解决办法就是定义scheme,用不一样的链接协议,链接必须要遵循 URL schema

URL schema的相应属性有Hostportpathquery比方说下面的链接

zmonster://mine/setting?type=2&&id=1

根据协议就可以知道host=minescheme=zmonsterpath=settingquery=type=2&&id=1

编写一个测试样例

<!DOCTYPE html>
<html>
    <head>
      <title>Android跳转测试</title>
    </head>
    <body>
      <a href="zmonster://mine/setting?type=2&&id=1">打开</a></br>
    </body>
</html>

然后,在AndroidManifest中,对WelcomeActivity,添加如下data

<data 
      android:scheme="liubike"
      android:host="mine"
      android:pathPrefix="/setting"/>

如果跳转页面未知,则只需要填写scheme属性,其他参数在WelcomeActivityonCreate方法中,实现跳转数据接收。

if(intent.getDate !=null){
    Uri uri = intent.getData();
    uri.getScheme();//获取scheme
    uri.getHost();//获取Host
    uri.getAuthority();//获取authority
    String type = uri.getQueryParameter("type");//获取传递参数
    String id = uri.getQueryParameter("id");
    String name = uri.getQueryParameter("name");
    //TODO 在这里可以跳转到指定页面
    //标题转UTF-8码
    if (!TextUtils.isEmpty(name)){
        try{
            name = URLDecoder.decode(name, "UTF-8");
        } catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
    }
}

App_Link

App_Link是谷歌在Android M(6.0)退出的一种软件关联方式,不会弹出对话框,直接就可以打开App

首先需要添加一个重要属性

android:autoVerify="true"

这段代码是通知Android系统,app在安装时需要对于安全host验证,验证通过后拉起app就不需要弹框安全提示,而是直接跳转app了。

具体原理分析

Android DEPPLINK、APPLink原理简析 - 掘金 (juejin.cn)

坑和经验

问题来了,很多app的首页activity都是在显示完SplashActivity后再启动的,首页activity的launchMode都是设置为singleTask,确保实例的唯一性,当我们的app已经启动了的情况下,再次通过外链的方式启动首页activity是无法启动的。

从android的task堆栈角度来说,浏览器activity所在task是在浏览器的process当中的,而起启动SplashActivity后此activity是在浏览器所在的task,此时在SplashActivity中启动app的首页activity,而首页activity是在另外的process的task当中,故无法切换这个task到前台。

此时的解决方案是在启动首页activity的intent对象中添加FLAG_ACTIVITY_NEW_TASK,在浏览器器task中通过FLAG_ACTIVITY_NEW_TASK启动首页activity,此时系统会寻找和首页activity具有相同的taskAffinity的task,即找到app的process中首页所在的task,将此task推到前台,到此实现了通过外链的方式再次现身app首页activity的功能。

总结一下,FLAG_ACTIVITY_NEW_TASK针对启动的activity是否在同一个process中处理方式不一样,因为默认情况下相同应用中所有的activity的taskAffinity都相同,故如果是存在且在同一应用中,直接将被启动的activity入栈,否则新建一个task并入栈,故在我们的开发中,对于activity间的切换以及task间的切换需要深入理解才能做出优秀的软件。

参考目录

最后修改:2022 年 07 月 07 日
如果觉得我的文章对你有用,请随意赞赏