【Android】获取前台应用的历史信息

最近接到一个新的需求,需要得到运行在前台应用的上一个应用的包名,比如我现在正在使用音乐播放器,这时候由于某种原因开启了另外一个应用,我需要在新开启的应用中拿到音乐播放器的包名。

实现这个需求尝试过几个方法,具体实现情况如下:

1、getRunningTasks() :获取当前打开的所有应用程序,但是这个方法只能拿到最顶层的也就是显示在前台的应用包名,无法满足需求,且在Android5.0后该方法已经失效。

ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> localList = manager.getRunningTasks(Integer.MAX_VALUE);
if (localList != null && localList.size() > 0) {
    for (ActivityManager.RunningTaskInfo info : localList) {
         Log.d("TAG", "ID : " + info.id + "  " + info.topActivity.getPackageName() + "  " + info.baseActivity.getPackageName());
         /*if (containsTaskID(info.id)) {
                 return info.topActivity;
           }*/
    }
}

2、getRunningAppProcesses() :获取正在运行的所有应用程序的进程,在Android6.0后该方法失效,使用该方法只能获取到顶层应用信息,如果要获取列表需要系统签名或者修改Framework代码,后来我用Android4.4.2的模拟器试了一下,确实获取到了正在运行的应用列表,但是顺序是打乱的,无法确定哪个是上一个位于前台的应用。

ActivityManager mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
// 通过调用ActivityManager的getRunningAppProcesses()方法获得系统里所有正在运行的进程
List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcessList) {
        int pid = appProcess.pid; // pid
        String processName = appProcess.processName; // 进程名
        String[] pkgNameList = appProcess.pkgList; // 获得运行在该进程里的所有应用程序包
}

3、UsageStatsManger类:Android5.0后新加类,用来获取应用的使用统计信息,调用他的queryUsageStats方法来获得应用的启动历史记录,通过启动时间来判断应用启动的先后顺序,下面来分析一下使用方法:

(1)添加权限

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

(2)在代码中动态设定权限,并获取指定时间范围内的应用列表的统计信息列表

    第一步添加的权限,是允许查看应用的使用情况的权限,由于Android5.0以下是没有该权限设置页面的,所以要判断一下安卓版本。

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //得到UsageStatsManager对象
            UsageStatsManager manager = (UsageStatsManager) context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
            //获取指定时间范围内的应用统计信息列表
            /**
             * queryUsageStats : 获取应用统计信息
             * 参数一:intervalType:时间间隔类型,有五种
             *      INTERVAL_DAILY: 日长短级别数据,最长7天内的数据;
             *      INTERVAL_WEEKLY: 星期长短级别数据,最长4个星期内的数据;
             *      INTERVAL_MONTHLY: 月长短级别数据,最长6个月内的数据;
             *      INTERVAL_YEARLY: 年长短级别数据,最长2年内的数据,也就是说,数据最长保存2年;
             *      INTERVAL_BEST: 根据提供的时间间隔(根据与第二个参数和第三个参数获取),自动搭配最好的级别
             * 参数二:beginTime:开始统计的时间
             * 参数三: endTime:结束的时间
             */
            List<UsageStats> usageStatses = manager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
            if (usageStatses == null || usageStatses.size() == 0) {// 没有权限,获取不到数据
                Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.getApplicationContext().startActivity(intent);
                return null;
            }
            return usageStatses;
        }

(3)拿到应用列表后,获取前台应用的记录信息,得到上一个在前台的应用

UsageStats usageStatsResult = null;
List<UsageStats> livingUsageStates = new ArrayList<>();
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 (usageStats.getLastTimeUsed() > 0) {
            Log.d("TAG", " " + usageStats.getLastTimeUsed() + "   " + usageStats.getPackageName());
            livingUsageStates.add(usageStats);
        }
    }

    // 按照使用时间对应用进行排序
    Collections.sort(livingUsageStates, new Comparator<UsageStats>() {
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public int compare(UsageStats o1, UsageStats o2) {
            if (o1.getLastTimeUsed() > o2.getLastTimeUsed()) {
                return -1;
            } else {
                return 1;
            }
        }
    });

    for (int i = 0; i < livingUsageStates.size(); i++) {
        //打印应用的最后使用时间以及应用包名
        Log.d("TAG", " " + livingUsageStates.get(i).getLastTimeUsed() + "   " + livingUsageStates.get(i).getPackageName());
    }
    usageStatsResult = livingUsageStates.get(1);
}

(4)得到上一个在前台得应用包名

UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME);
if (initStat != null) {
    currentClassName = initStat.getPackageName();
}

总结:大体逻辑基本这样,可能细节之处还有不足需要调整,希望能给有该需求的开发人员一个参考。

源码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值