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)

最后,我不生产,我只是代码界的搬运工,感谢lucky__baby和简书的方小钢

 

 

 

 

 

 

 

 

 

  • 12
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值