需求:
分享内容页面中有一个按钮,点击跳转到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跳转指定页面,点击返回到APP首页
发布评论