前言

有时我们需要在自己的程序调起第三方程序,这个时候我们就需要知道第三方程序的包名和入口界面的Activity。
下面我们介绍几种方式获取第三方程序的包名及程序入口Activity。

0.使用aapt获取

aapt在SDK的build-tools中。

获取Apk的包名:

aapt dump badging xxxxx.apk | grep package | sed 's/ //g' | cut -d "'" -f2

获取Apk启动Activity:

aapt dump badging xxxxx.apk | grep launchable-activity | sed 's/ //g' | cut -d "'" -f2

在这里插入图片描述

1.使用adb指令获取

配置了adb指令环境后,手机打开调试模式连接电脑(虚拟机也行)直接在命令行中输入如下指令:

adb shell dumpsys activity activities 

命令行会输出当前运行的Activity的所有信息,我们只需要关注如下图标注的mFocusedActivity信息即可。
第一个圈是包名,第二个就是当前的Activity名。

这里写图片描述

2.PackageManager

ResolveInfo类的部分方法
  1. 获取图标:resolveInfo.activityInfo.loadIcon(packageManager)
  2. 获取包名:resolveInfo.activityInfo.packageName
  3. 获取程序入口activity:resolveInfo.activityInfo.name
代码
/**
     * Created by Derek on 2017/3/31 0031.
     * 根据应用程序的名称获取对应的信息
     *
     * @param context
     * @param appLabel 程序的名称
     * @return
     */
    public ResolveInfo findInstallAppDetails(Context context, String appLabel) {
        PackageManager packageManager = context.getPackageManager();
        //匹配程序的入口
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        //查询
        List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
        for (int i = 0; i < resolveInfos.size(); i++) {
            String appName = resolveInfos.get(i).loadLabel(packageManager).toString();
            if (appLabel.equals(appName)) {
                return resolveInfos.get(i);
            }
        }
        return null;
    }

ActivityManager

核心代码
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        RunningTaskInfo info = manager.getRunningTasks(1).get(0);
    String shortClassName = info.topActivity.getShortClassName();    //类名
        String className = info.topActivity.getClassName();              //完整类名
        String packageName = info.topActivity.getPackageName();          //包名

因为ActivityManager获取的是topActivity的信息,所以为了获取第三方应用的包名,我们需要在Service中执行这段代码,然后打开第三方应用,在控制台输出第三方应用的信息。

为了及时获取最新的Activity,我们需要使用子线程不断刷新。

Service
public class SoftService extends Service {
    private ActivityManager activityManager = null;
    private Handler handler = new Handler();
    private String activityName = null;
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            List<ActivityManager.RunningTaskInfo> runningTaskInfo = activityManager.getRunningTasks(1);
            activityName = (runningTaskInfo.get(0).topActivity).toString();
            Log.i("ActivityManager: ", "当前activity是---->" + activityName);

            handler.postDelayed(runnable, 5000);//每5秒刷新一次
        }
    };

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handler.post(runnable);//开启子线程
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onDestroy() {
        handler.removeCallbacks(runnable);
    }

}

这里写图片描述

源码

https://github.com/Demo-DeMon/SoftManager

参考

https://blog.csdn.net/android_cmos/article/details/73382573

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐