Android APP打開另一個APP完整邏輯實現

一丶概述

前段時間配合開發,完成了一個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的主界面或某頁面,並傳遞數據
Android-跳轉第三方app重複啓動問題
通過 PackageManager 獲得你想要的 App 信息

如果文章對你有幫助,歡迎多多支持!

源碼下載:
https://github.com/JinBoy23520/CoderToDeveloperByTCLer

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章