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

本文出自:https://blog.csdn.net/DT235201314/article/details/80255143

一丶概述

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

二丶效果圖

image
image

三丶需求分析

1.A點擊拉起B;

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

3.如果B已安轉,未在后臺運行點擊打開B,傳值賬號密碼,做跨登錄;

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

簡版流程圖:

image

四丶原理與實現

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

寫在最后微信掃碼提問

image
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,643評論 25 708
  • 【Android Activity】 什么是 Activity? 四大組件之一,通常一個用戶交互界面對應一個 ac...
    Rtia閱讀 3,834評論 3 18
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,482評論 0 17
  • 作品完全可以給人物編造各種劇情,使得整個故事更加完整。但他并沒有這樣做,而是選擇把實際上的情節描述搬運過來。 因為...
    saiyonana閱讀 206評論 0 1
  • 文/欣欣熳 1. 因為寫作的關系,我認識了一個副總裁。 或許在很多人眼里,一個男人在職場上做到這么高的職位,在家里...
    欣欣熳閱讀 481評論 0 10