Skip to content

Android获取顶层应用包名(较全面)

shewenbiao edited this page Nov 8, 2019 · 2 revisions

android5.0以下

private static String getTopAppBelowApi21(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (activityManager != null) {
            List<ActivityManager.RunningTaskInfo> appTasks = activityManager.getRunningTasks(1);
            if (appTasks != null && !appTasks.isEmpty()) {
                return appTasks.get(0).topActivity.getPackageName();
            }
        }
        return "";
    }

android5.0以上(包括5.0)

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private static String getTopAppAboveApi21(Context context) {
        UsageStatsManager sUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        long endTime = System.currentTimeMillis();
        long beginTime = endTime - 10000;
        String result = "";
        UsageEvents.Event event = new UsageEvents.Event();
        if (sUsageStatsManager != null) {
            UsageEvents usageEvents = sUsageStatsManager.queryEvents(beginTime, endTime);
            while (usageEvents.hasNextEvent()) {
                usageEvents.getNextEvent(event);
                if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
                    result = event.getPackageName();
                }
            }
        }
        if (!android.text.TextUtils.isEmpty(result)) {
            return result;
        }
        return "";
    }

注意点:

  1. 在AndroidManifest文件里添加权限:
    <uses-permission
        android:name="android.permission.PACKAGE_USAGE_STATS"
        tools:ignore="ProtectedPermissions"/>
  1. 需要引导用户去设置里打开权限:
if (!isUsageAccessPermissionSet(mContext)
        && isUsageAccessSettingExist(mContext)) {
    openUsageAccessSetting();
} 

/**
     * 判断是否已经获取 有权查看使用情况的应用程序 权限
     *
     * @param context
     * @return
     */
    public static boolean isUsageAccessPermissionSet(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                PackageManager packageManager = context.getPackageManager();
                ApplicationInfo info = packageManager.getApplicationInfo(context.getPackageName(), 0);
                AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
                if (appOpsManager != null) {
                    appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, info.uid, info.packageName);
                    return appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, info.uid, info.packageName) == AppOpsManager.MODE_ALLOWED;
                } else {
                    return false;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * 查看是否存在查看使用情况的应用程序界面
     *
     * @return
     */
    public static boolean isUsageAccessSettingExist(Context context) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            PackageManager packageManager = context.getPackageManager();
            Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
            List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
            return list.size() > 0;
        }
        return false;
    }

private void openUsageAccessSetting() {
        try {
            Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            startActivity(intent);
        } catch (Exception e) {
        }
    }
  1. 该方法在某些5.0设备上(比如LG3)获取不到顶层应用包名.

android5.0上

private static String getTopAppInApi21(Context context) {
        int num;
        String packageName = "";
        Field processStateField;
        try {
            processStateField = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
        } catch (Exception e) {
            return "";
        }
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (activityManager == null) {
            return "";
        }
        Field flagFiled;
        try {
            flagFiled = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("flags");
        } catch (NoSuchFieldException e) {
            flagFiled = null;
        }
        List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfoList) {
            if ((ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND == runningAppProcessInfo.importance
                    || 400 == runningAppProcessInfo.importance)
                    && runningAppProcessInfo.importanceReasonCode == 0) {
                if (flagFiled != null) {
                    try {
                        num = flagFiled.getInt(runningAppProcessInfo);
                        if ((num & 4) == 0) {
                            continue;
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }

                }
                try {
                    num = processStateField.getInt(runningAppProcessInfo);
                    if (2 != num) {
                        continue;
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                packageName = runningAppProcessInfo.processName.split(":")[0].trim();
                if (AppUtil.isHomeLauncher(context, packageName) || AppUtil.hasLaunchIntent(context, packageName)) {
                    break;
                }
            }
        }

        return packageName;
    }

注: 该方法在某些5.0设备上获取不到顶层应用包名

最终整合方法

public static String getTopAppPackageName(Context context) {
        try {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                return getTopAppBelowApi21(context);
            } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
                String packageName = getTopAppAboveApi21(context);
                if (!TextUtils.isEmpty(packageName)) {
                    return packageName;
                }
                return getTopAppInApi21(context);
            } else {
                return getTopAppAboveApi21(context);
            }
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return "";
    }
Clone this wiki locally