zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    csrf攻击实例
    《四 数据库连接池源码》手写数据库连接池
    《四 spring源码》手写springmvc
    spring和springmvc是单例还是多例
    redis集群设置密码
    mongodb3.6集群搭建:分片集群认证
    mongodb3.6集群搭建:分片+副本集
    Mongo 3.6.1版本Sharding集群配置
    windows计划任务
    Redis slowlog慢查询
  • 原文地址:https://www.cnblogs.com/KillBugMe/p/13672370.html
Copyright © 2011-2022 走看看