本文出自:https://blog.csdn.net/DT235201314/article/details/80255143
一丶概述
前段時間配合開發,完成了一個APP拉起另一個APP的需求,負責接收數據跨登錄部分。當然整個實現思路挺感興趣就了解一下。先說說需求拉起另一個APP是為了方便統一使用管理,有些公司APP較多,部分人只需要用到部分APP,需要用到時就下載。市面上比較流行的解決辦法,第一個就是現在說的新開發一個管理型APP,其他APP需要時再下載,運用時拉起,另一個就是插件化,直接將多個APP合成一個APP,這個感興趣也可以了解一下。
二丶效果圖
三丶需求分析
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("kuyu.com.xxxx", "kuyu.com.xxxx.xxx.login.WelcomeActivity");
intent.setComponent(componentName);
intent.putExtra("", "");//這里Intent傳值
startActivity(intent);
B應用需要在manifest文件對應Activity添加
android:exported="true"
(2)包名拉起(這里就是進去啟動頁)
Intent intent = getPackageManager().getLaunchIntentForPackage("kuyu.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("kuyu.com.xxxxx")) {
openPackage(this,"kuyu.com.xxxxx");
} else {
Toast.makeText(this, "沒有安裝" + "",Toast.LENGTH_LONG).show();
//TODO 下載操作
}
這里運用的是模擬點擊圖標啟動,不會出現程序多開,和棧頂Activity重復或者順序錯亂的問題。
當然Activity的LaunchMode最好設為“singletop”
4.B應用接受傳值跨登錄操作
一般啟動頁有幾種操作
(1)定時直接跳轉登錄頁面
這個就簡單了,直接在handle發送跳轉做判斷接收intent操作就可以了
例:
if(getIntent().hasExtra("xxxx")){
otherOpen();
}else {
mHandler.removeMessages(0);
mHandler.sendEmptyMessageDelayed(0, 3000);
}
(2)做了用戶信息保存,跳過登錄的,這個時候就通過handle的消息判斷,做出相應操作
例:
/**
* 跳去首頁/登錄頁面
*/
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.arg1) {
case 1009:
goToActivity(MainActivity.class);
WelcomeActivity.this.finish();
break;
case 1010:
gotoLogin(handler1, runnable);
break;
}
}
};
五丶參考文章
Android從一個APP跳轉到另一個APP的主界面或某頁面,并傳遞數據
通過 PackageManager 獲得你想要的 App 信息
如果文章對你有幫助,歡迎點贊關注
源碼下載:
https://github.com/JinBoy23520/CoderToDeveloperByTCLer