天天看點

Android APP打開另一個APP的多種實作方式及完整邏輯實作(附源碼)一丶概述二丶效果圖三丶需求分析四丶原理與實作五丶參考文章

轉載僅供本人存檔及後續研究使用,請尊重原創。

轉載自:https://blog.csdn.net/dt235201314/article/details/80255143

一丶概述

前段時間配合開發,完成了一個APP拉起另一個APP的需求,負責接收資料跨登入部分。當然整個實作思路挺感興趣就了解一下。先說說需求拉起另一個APP是為了友善統一使用管理,有些公司APP較多,部分人隻需要用到部分APP,需要用到時就下載下傳。市面上比較流行的解決辦法,第一個就是現在說的新開發一個管理型APP,其他APP需要時再下載下傳,運用時拉起,另一個就是插件化,直接将多個APP合成一個APP,這個感興趣也可以了解一下。

二丶效果圖

Android APP打開另一個APP的多種實作方式及完整邏輯實作(附源碼)一丶概述二丶效果圖三丶需求分析四丶原理與實作五丶參考文章
Android APP打開另一個APP的多種實作方式及完整邏輯實作(附源碼)一丶概述二丶效果圖三丶需求分析四丶原理與實作五丶參考文章

三丶需求分析

1.A點選拉起B;

2.如果B沒安裝,下載下傳安裝;

3.如果B已安轉,未在背景運作點選打開B,傳值賬号密碼,做跨登入;

4.如果B已安裝,且正在背景運作,A打開B直接顯示在背景運作的頁面;

簡版流程圖:

Android APP打開另一個APP的多種實作方式及完整邏輯實作(附源碼)一丶概述二丶效果圖三丶需求分析四丶原理與實作五丶參考文章

四丶原理與實作

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

---------------------------------------------------------------------------------------------------------------------------

早計劃,早準備,早完成。 歡迎關注!交流!Star!

GitHub:https://github.com/wangyang0313

微信公衆号:一個靈活的胖子MrWang

簡書:https://www.jianshu.com/u/e5e733d79b96  

Android APP打開另一個APP的多種實作方式及完整邏輯實作(附源碼)一丶概述二丶效果圖三丶需求分析四丶原理與實作五丶參考文章