需求分析:
1.A点击拉起B;
2.如果B没安装,下载安装;
3.如果B已安转,未在后台运行点击打开B,传值账号密码,做跨登录;
4.如果B已安装,且正在后台运行,A打开B直接显示在后台运行的页面;
1.A拉起B可实现的几种方法
(1)包名,特定Activity名拉起
Intent intent = new Intent(Intent.ACTION_MAIN); /**知道要跳转应用的包命与目标Activity*/ ComponentName componentName = new ComponentName("cn.com.xxxx", "cn.com.xxxx.xxx.login.WelcomeActivity"); intent.setComponent(componentName); intent.putExtra("", "");//这里Intent传值 startActivity(intent);
B应用需要在manifest文件对应Activity添加
android:exported="true"
(2)包名拉起(这里就是进去启动页)
Intent intent = getPackageManager().getLaunchIntentForPackage("cn.com.xxxx"); if (intent != null) { intent.putExtra("type", "110"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); }
(3)url拉起
Intent intent = new Intent(); intent.setData(Uri.parse("csd://pull.csd.demo/cyn?type=110")); intent.putExtra("", "");//这里Intent当然也可传递参数,但是一般情况下都会放到上面的URL中进行传递 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
B应用manifest文件需配置(注意:在原有intent-filter下方另外添加,不是在原先里面,两个同时存在)
<intent-filter> <data android:host="pull.csd.demo" android:path="/cyn" android:scheme="csd" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> </intent-filter>
优点:不暴露包名 缺点:host path schemeA应用和B应用得提前规定
2.判断B应用是否安装
/** * 检查包是否存在 * * @param packname * @return */ private boolean checkPackInfo(String packname) { PackageInfo packageInfo = null; try { packageInfo = getPackageManager().getPackageInfo(packname, 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return packageInfo != null; }
3.判断B应用是否在后台运行并直接打开
public static Intent getAppOpenIntentByPackageName(Context context,String packageName){ //Activity完整名 String mainAct = null; //根据包名寻找 PackageManager pkgMag = context.getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED|Intent.FLAG_ACTIVITY_NEW_TASK); List<ResolveInfo> list = pkgMag.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES); for (int i = 0; i < list.size(); i++) { ResolveInfo info = list.get(i); if (info.activityInfo.packageName.equals(packageName)) { mainAct = info.activityInfo.name; break; } } if (TextUtils.isEmpty(mainAct)) { return null; } intent.setComponent(new ComponentName(packageName, mainAct)); return intent; } public static Context getPackageContext(Context context, String packageName) { Context pkgContext = null; if (context.getPackageName().equals(packageName)) { pkgContext = context; } else { // 创建第三方应用的上下文环境 try { pkgContext = context.createPackageContext(packageName, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } return pkgContext; } public static boolean openPackage(Context context, String packageName) { Context pkgContext = getPackageContext(context, packageName); Intent intent = getAppOpenIntentByPackageName(context, packageName); if (pkgContext != null && intent != null) { pkgContext.startActivity(intent); return true; } return false; }
if (checkPackInfo("cn.com.xxxxx")) { openPackage(this,"cn.com.xxxxx"); } else { Toast.makeText(this, "没有安装" + "",Toast.LENGTH_LONG).show(); //TODO 下载操作 }
这里运用的是模拟点击图标启动,不会出现程序多开,和栈顶Activity重复或者顺序错乱的问题。
当然Activity的LaunchMode最好设为“singletop”