LeetCode刷题记录

Android中如何获取栈顶应用的包名 2018-11-18

2018-11-18  本文已影响226人  TheKey_

在android 5.0之前获取栈顶应用包名的方法:

ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);

packageName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();

通过上面3行代码即可获取,但是在5.0之后Google对此做了限制,不允许获取第三方的应用程序栈,所以在5.0之后如果使用此种方法只能获取桌面包名和自身应用程序的包名。
但是android 5.0之后也提供了UsageStatsManager的方式来获取栈顶的应用包名(并非直接获取,需要处理)。
UsageStatManager是一个使用情况统计管理者,通过它可以获取应用的使用情况,通过List集合来记录APP的使用情况,通过UsageStats对象可以获取包名,最后的在前台的时间,在前台的次数等等。

代码如下:

/**
     * 获取栈顶的应用包名
     * android5.0之前可以直接获取
     */
    private static final long END_TIME = System.currentTimeMillis();
    private static final long TIME_INTERVAL = 7 * 24 * 60 * 60 * 1000L;
    private static final long START_TIME = END_TIME - TIME_INTERVAL;

    public String getForegroundActivityName(Context context) {
        String packageName = "";
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
            packageName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
        } else {
            UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME);
            if (initStat != null) {
                packageName = initStat.getPackageName();
            }
        }
        return packageName;
    }

 /**
     * 获取记录前台应用的UsageStats对象
     */
   private static final long END_TIME = System.currentTimeMillis();
    private static final long TIME_INTERVAL = 7 * 24 * 60 * 60 * 1000L;
    private static final long START_TIME = END_TIME - TIME_INTERVAL;

    private UsageStats getForegroundUsageStats(Context context, long startTime, long endTime) {
        UsageStats usageStatsResult = null;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
            if (usageStatses == null || usageStatses.isEmpty()) return null;
            for (UsageStats usageStats : usageStatses) {
                if (usageStatsResult == null || usageStatsResult.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
                    usageStatsResult = usageStats;
                }
            }
        }
        return usageStatsResult;
    }

使用此方法需要声明权限,否则系统无法获取数据:

<uses-permission
  android:name="android.permission.PACKAGE_USAGE_STATS"
  tools:ignore="ProtectedPermissions" />

那么如何在app中动态跳转指引用户打开权限呢:
首先进行判断该权限(访问数据量)是否已经打开:

/**
     * 此方法判断是否打开了数据量访问的权限
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public boolean isNoSwitch() {
        long ts = System.currentTimeMillis();
        UsageStatsManager usageStatsManager = (UsageStatsManager) getContext()
                .getSystemService(Context.USAGE_STATS_SERVICE);
        List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(
                UsageStatsManager.INTERVAL_BEST, 0, ts);
        if (queryUsageStats == null || queryUsageStats.isEmpty()) {
            return false;
        }
        return true;
    }

如果没有打开,则进行跳转:

 /**
     * 跳转数据量权限页面
     */
    private void AccessPermission(){
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            if (!ForegroundAppUtils.getInstance().isNoSwitch()){
                Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
                getContext().startActivity(intent);
            }
        }
    }
上一篇下一篇

猜你喜欢

热点阅读