admin管理员组

文章数量:1534201

需求:

分享内容页面中有一个按钮,点击跳转到APP中的指定的某个页面,例如分享了一个文章页面,点击按钮跳转到APP的文章详情页面

页面跳转逻辑分析:

情景1:用户未安装APP,点击跳转直接跳转下载链接即可

情景2:用户安装了APP且已经打开APP(或者APP挂在后台),点击跳转按钮直接跳转至文章详情页,点击返回就返回到APP之前所处的页面

情景3:用户安装了APP未打开APP(冷启动),点击跳转按钮直接跳转至文章详情页,点击返回就返回到APP首页

实现:

步骤1:在目标Activity清单文件中添加配置信息

首先需要用到需要使用到 Android Activity中的 <intent-filter>,可以用APP启动页面作为解析跳转的Activity,配置如下:

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <data
    //app唯一标记
    android:scheme="testscheme"/>
</intent-filter>

现在这个 Activity 就具备外部唤醒的能力了,注意下 <data> 中的相关配置,如上配置,外部的链接形式应该就是这样的了:testscheme://xxx 

步骤2:跳转处理,主要处理情景2和情景3

情景1:用户未安装APP,点击跳转直接跳转到下载链接即可,如需带参数安装,安装完成跳转到指定页面可接第三方平台,此处不做过多解释,第三方平台很多,比如友盟、openinstall、shareinstall、xinstall 等

情景2:已经安装APP,且已经打开(或运行在后台)

在目标Activity的onCreate方法中匹配H5规则, 获取业务数据

Intent intent = getIntent();
Uri uri = null;
if(intent != null) {
    uri = intent.getData();  //获取H5规则, 可携带数据
    String scheme = getIntent().getScheme();
    Log.i("TAG","scheme" + scheme);
}

if (uri != null) {
    isFromBrowser = true; //区分是否从浏览器唤起的标记,自行定义成员变量
    String test_param = uri.getQueryParameter("test_param");//自定义携带参数
}

首先确认APP有一个必须要启动的页面,一般是APP的首页,进而判断APP是否处于运行状态,思路是判断首页是否在栈内,判断方法如下:

    public static boolean isLaunchedActivity(@NonNull Context context, Class<?> clazz) {
        Intent intent = new Intent(context, clazz);
        ComponentName cmpName = intent.resolveActivity(context.getPackageManager());
        boolean flag = false;
        if (cmpName != null) {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> taskInfoList = am.getRunningTasks(10);
            for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
                if (taskInfo.baseActivity.equals(cmpName)) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

接下来结合isFromBrowser=true和isLaunchedActivity=true判断APP已经启动,并且是由外部浏览唤醒,则直接启动详情页:

Intent intent = new Intent(context, ArticleContentActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//加上Intent.FLAG_ACTIVITY_NEW_TASK的Flag,不然就在浏览器所在的堆栈里面了
startActivity(intent);

如果此时已经启动了详情页,再次从浏览器唤醒到APP的时候就会打开2个重复的详情页,解决方法:

android:launchMode="singleTop"//如果是多个页面复用一个webview, 则此方式不适用

情景三:已经安装APP,且没有启动APP

这里需要用到一次启动多个Activity的知识,这里可以直接使用startActivities来启动多个Activity

Intent intentLauncher = new Intent(context, MainActivity.class);//APP首页
Intent intentDetails = new Intent(context, DetailsActivity.class);//文章详情页
Intent[] intents = new Intent[2];
intents[0] = intentLauncher;
intents[1] = intentDetails;

PendingIntent mPendingIntent = PendingIntent.getActivities(context, 0, intents, 0);

mPendingIntent.send();//这里同时启动2个页面,把首页放到栈底,最终只显示文章详情页

最终整合判断条件代码如下:

if(isFromBrowser){//判断从浏览器唤醒APP
    if(isLaunchedActivity(context, MainActivity.class)){//判断是否已经启动过APP(APP是否存在后台)
        Intent intent = new Intent(context, ArticleContentActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//加上Intent.FLAG_ACTIVITY_NEW_TASK的Flag,不然就在浏览器所在的堆栈里面了
        startActivity(intent);
    }else{
        Intent intentLauncher = new Intent(context, MainActivity.class);//APP首页
        Intent intentDetails = new Intent(context, DetailsActivity.class);//文章详情页
        Intent[] intents = new Intent[2];
        intents[0] = intentLauncher;
        intents[1] = intentDetails;

        PendingIntent mPendingIntent = PendingIntent.getActivities(context, 0, intents, 0);

        mPendingIntent.send();//这里同时启动2个页面,把首页放到栈底,最终只显示文章详情页
    }
}else{
    //TODO 如果是正常启动(不是从浏览器跳转,执行自己的逻辑)
}

总结:

本次实现此功能,也是折腾了我好一段时间,主要是对启动页面的逻辑思路没有整理清晰,其次对startActivities理解不熟悉。故做此记录以便后查

本文标签: 跳转首页浏览器页面app