Android 啟動第三方應用的幾種方法(整理)【轉】


最近要做一個打開第三方apk的功能,只給了一個apk,通過自己獲取包名然后在實現;需求是如果第三方apk已經打開,則直接把界面顯示出來,如果未打開,則啟動。

首先獲取bao包名,直接上代碼;

/**
 * 獲取包名
 *
 * @return
 */
public static String getPackagenameKemobilevideo() {
    String archiveFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MobileVideo.apk";//安裝包路徑
    PackageManager pm = ContextHolder.getContext().getPackageManager();
    PackageInfo info = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES);
    if (info != null) {
        ApplicationInfo appInfo = info.applicationInfo;
        String appName = pm.getApplicationLabel(appInfo).toString();
        String packageName = appInfo.packageName;  //得到安裝包名稱
        String version = info.versionName;       //得到版本信息
        LogUtil.e("MainActivity", "packageName:" + packageName + ";version:" + version);
        return packageName;
    }
    return "";
}

獲取到包名就可以啟動了,通過度娘找到好幾種辦法,各有優缺點:

1、最簡單的情況:只有包名

/**
 * 啟動第三方apk
 * 直接打開  每次都會啟動到啟動界面,每次都會干掉之前的,從新啟動
 * XXXXX : 包名
 */
public static void launchAPK1() {
    PackageManager packageManager = ContextHolder.getContext().getPackageManager();
    Intent it = packageManager.getLaunchIntentForPackage("XXXXX");
    ContextHolder.getContext().startActivity(it);
}

2、也是根據包名啟動

/**
 * 啟動第三方apk
 * 內嵌在當前apk內打開,每次啟動都是新的apk,你會發現打開了兩個apk
 * XXXXX : 包名
 */
public static void launchAPK2() {
    PackageInfo pi = null;
    try {
        pi = ContextHolder.getContext().getPackageManager().getPackageInfo("XXXX", 0);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
 
    Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
    resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    resolveIntent.setPackage(pi.packageName);
    List<ResolveInfo> apps = ContextHolder.getContext().getPackageManager().queryIntentActivities(resolveIntent, 0);
    ResolveInfo ri = apps.iterator().next();
    if (ri != null) {
        String packageName = ri.activityInfo.packageName;
        String className = ri.activityInfo.name;
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        ComponentName cn = new ComponentName(packageName, className);
        intent.setComponent(cn);
        ContextHolder.getContext().startActivity(intent);
    }
}

3、還是通過包名啟動,這種方式正好滿足我的需求

/**
 * 啟動第三方apk
 * 
 * 如果已經啟動apk,則直接將apk從后台調到前台運行(類似home鍵之后再點擊apk圖標啟動),如果未啟動apk,則重新啟動
 */
public static void launchAPK3() {
    Intent intent = getAppOpenIntentByPackageName(ContextHolder.getContext(), PACKAGENAME_KEMOBILEVIDEO);
    ContextHolder.getContext().startActivity(intent);
}
 
public static Intent getAppOpenIntentByPackageName(Context context, String packageName) {
    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);
 
    @SuppressLint("WrongConstant") 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;
}

上面三種都是通過包名啟動,如果要啟動到指定的界面

1、啟動第三方指定頁面。(這個方法有限制,第三方頁面 Activity的屬性Export=“true”)

啟動頁貌似是默認是true,其他頁面默認是false

/**
 * 啟動第三方apk
 * 直接打開  每次都會啟動到啟動界面
 */
public static void launchAPK4() {
    Intent intent = new Intent(pk_name);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings");
    intent.setComponent(comp);
    ContextHolder.getContext().startActivity(intent);
}

2、隱式啟動第三方應用

/**
 * 啟動第三方apk
 * 直接打開  每次都會啟動到啟動界面
 */
public static void launchAPK5() {
    Intent intent = new Intent();
    intent.setAction(action);
    intent.addCategory(category);
    intent.setDataAndType("abc://www.baidu.com","image/gif");
    ContextHolder.getContext().startActivity(intent);
}

條件1:IntentFilter 至少有一個action 至少有一個Category 可以沒有Data和Type

條件2:如果有Data,參數中Data必須符合Data規則

條件3:Action和Category必須同時匹配Activity中的一個Action和一個Category(Category 默認:android.intent.category.DEFAULT)

來源:https://blog.csdn.net/linfujiao_shugangyu/article/details/81502646


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM