Android获取前台进程包名
来源:互联网 发布:博客数据出售 编辑:程序博客网 时间:2024/06/05 04:21
在Android L之前的版本,获取前台进程基本上是用下面两种方法:(现在都已失效)
方法一:getRunningTasks()
这种方法不仅可以获取前台进程包名,还可以获取前台activity名。
public String getForegroundActivity() { ActivityManager mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); if (mActivityManager.getRunningTasks(1) == null) { Log.e(TAG, "running task is null, ams is abnormal!!!"); return null; } ActivityManager.RunningTaskInfo mRunningTask = mActivityManager.getRunningTasks(1).get(0); if (mRunningTask == null) { Log.e(TAG, "failed to get RunningTaskInfo"); return null; } String pkgName = mRunningTask.topActivity.getPackageName(); //String activityName = mRunningTask.topActivity.getClassName(); return pkgName;}
方法二:getRunningAppProcesses()
这种方法只能获取前台包名。
public String getForegroundApp(Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcesInfo> lr = am.getRunningAppProcesses(); if (lr == null) { return null; } for (RunningAppProcessInfo ra : lr) { if (ra.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE || ra.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return ra.processName; } } return null; }
在Android L上,google收紧了这两个API的权限,只能获取自身的包名,无法获取其他应用的包名。具体原因就是下面这个权限检查方法:
private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (!allowed) { if (checkPermission(android.Manifest.permission.GET_TASKS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { // Temporary compatibility: some existing apps on the system image may // still be requesting the old permission and not switched to the new // one; if so, we'll still allow them full access. This means we need // to see if they are holding the old permission and are a system app. try { if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { allowed = true; Slog.w(TAG, caller + ": caller " + callingUid + " is using old GET_TASKS but privileged; allowing"); } } catch (RemoteException e) { } } } if (!allowed) { Slog.w(TAG, caller + ": caller " + callingUid + " does not hold REAL_GET_TASKS; limiting output"); } return allowed;}
很明显,只有两种情况可以通过该权限检查:
- 拥有REAL_GET_TASKS权限授权
- 拥有GET_TASKS权限授权,同时自己是privileged app,也就是安装在/system/priv-app/下的app
查看frameworks/base/core/res/AndroidManifest.xml可知,REAL_GET_TASKS只有系统签名的app可以申请,第三方app申请了也白搭。
<!-- @deprecated No longer enforced. --> <permission android:name="android.permission.GET_TASKS" android:permissionGroup="android.permission-group.APP_INFO" android:protectionLevel="normal" android:label="@string/permlab_getTasks" android:description="@string/permdesc_getTasks" /> <!-- New version of GET_TASKS that apps can request, since GET_TASKS doesn't really give access to task information. We need this new one because there are many existing apps that use add libraries and such that have validation code to ensure the app has requested the GET_TASKS permission by seeing if it has been granted the permission... if it hasn't, it kills the app with a message about being upset. So we need to have it continue to look like the app is getting that permission, even though it will never be checked, and new privileged apps can now request this one for real access. @hide @SystemApi --> <permission android:name="android.permission.REAL_GET_TASKS" android:permissionGroup="android.permission-group.APP_INFO" android:protectionLevel="signature|system" android:label="@string/permlab_getTasks" android:description="@string/permdesc_getTasks" />
那么,在Android L之后,还有没有方法可以获取到前台包名呢?答案是肯定的,用usage statistics API。这个API本来是系统用来统计app使用情况的,包含了每个app最近一次被使用的时间。我们只需要找出距离现在时间最短的那个app,就是当前在前台的app:
private String getForegroundApp(Context context) { UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long ts = System.currentTimeMillis(); List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, 0, ts); UsageEvents usageEvents = usageStatsManager.queryEvents(isInit ? 0 : ts-5000, ts); if (usageEvents == null) { return null; } UsageEvents.Event event = new UsageEvents.Event(); UsageEvents.Event lastEvent = null; while (usageEvents.getNextEvent(event)) { // if from notification bar, class name will be null if (event.getPackageName() == null || event.getClassName() == null) { continue; } if (lastEvent == null || lastEvent.getTimeStamp() < event.getTimeStamp()) { lastEvent = event; } } if (lastEvent == null) { return null; } return lastEvent.getPackageName(); }
0 0
- Android获取前台进程包名
- 获取前台进程包名(ForegroundProcess)
- android 5.0以上获取前台应用的包名
- 获取Android进程中的包名
- 获取前台应用包名 终极解决方案
- android 5.0获取前台应用的包名的实现方法
- 根据包名获取进程pid
- android中获取包名,类名
- Android获取前台进程技术方案
- Android获得当前前台运行的app包名
- Android获取包名、版本号、包名、meta-data
- android 通过包名杀死进程
- Android通过包名杀死进程
- Android应用开发中的进程名,包名,applicationId
- Android获取组件的进程名
- Android获取Apk的包名
- android 5.0 获取 当前app包名
- android 获取应用包名并启动
- Android文件存储基础
- socket之send,recv,sendto,recvfrom
- Action Bar的使用
- linux ubuntu 14.0 修改文件上下左右出现ABCD
- git修改远程仓库地址及远程仓库管理
- Android获取前台进程包名
- listview中item的各种进入效果实现
- 利用Masonry自适应键盘高度
- java代码审查检查表
- 龟兔赛跑 PAT
- IE9及以下版本浏览器中 filter 设置 背景渐变 border不显示
- iOS开发——Carthage:去中心化的Cocoa依赖管理器
- iOS Xcode6之后给工程添加全局引用文件(pch头文件)
- JAVA 基础之 异常机制