前沿
有时候会时刻检查当前进程是否还在前台.这个时候需要获取前台进程了,然而考虑到Android版本对于系统权限越来越严格,获取前台进程根据不同SDK,有所不同.
题外话-进程级别
进程级别也可以说是进程优先级
当系统在某些情况下需要关闭一些进程,会根据进程优先级来关闭.因此在app保活上,提高进程优先级是一种手段.这边不详细讲解.
1、前台进程
- 拥有用户交互的Activity
- 拥有用户交互的Activity上的Service
- 拥有前台运行的Service
- 拥有正在执行onReceive()方法的BroadReceiver
2、可见进程
不拥有运行在前台的组件,但是用户可见 - 不在前台依然可见的Activity:例如activity启动一个对话框
3、服务进程 - 绑定一个可见activity的service
4、后台进程 - activity调用onStop()方法后
5、空进程 - 不拥有任何active组件
详细可见官网:https://developer.android.com/guide/components/processes-and-threads?hl=zh-cn
言归正传:获取前台进程
getRunningTasks
Android5.0之前 AMS中存在
public List<ActivityManager.RunningTaskInfo> getRunningTasks (int maxNum)
.
返回当前正在运行的任务的列表,其中最新的任务是第一个,较旧的任务在后面。官网:https://developer.android.com/reference/android/app/ActivityManager.html#getRunningTasks(int)
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERICE);
List<ActivityManager.RunningTaskInfo> runningTasks = mActivityManager.getRunningTasks(1);
if (runningTasks.size() == 0) {
//获取不到哦
}
String packageName = runningTasks.get(0).topActivity.getPackageName();
getRunningAppProcesses
Android 5.0及以前,AMS中
public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses ()
返回在设备上运行的应用程序进程列表。在5.1版本之后这个方法只能获取到自己应用信息.官网:https://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERICE);
List<ActivityManager.RunningAppProcessInfo> processes = mActivityManager.getRunningAppProcesses();
if (processes.size() == 0) {
//获取不到
}
for (ActivityManager.RunningAppProcessInfo process : processes) {
if (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
//最前台进程
break;
}
}
UsageStatsManager
Android 5.0之后加入了提供对设备使用历史和统计数据的访问。使用数据按时间间隔聚合:天、周、月和年。(大部分5.1之后才支持)
注意:需要系统权限android.permission.PACKAGE_USAGE_STATS
+用户开启权限
官网:https://developer.android.com/reference/android/app/usage/UsageStatsManager
- 检查权限
public static boolean checkAppUsagePermission(Context context) {
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
if (usageStatsManager == null) {
return false;
}
long currentTime = System.currentTimeMillis();
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 60 * 1000, currentTime);
if (stats.size() == 0) {
return false;
}
return true;
}
- 跳转权限页面
public static void requestAppUsagePermission(Context context) {
Intent intent = new Intent(android.provider.Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
//error
}
}
- 获取当前前台进程
实际上就是找到最近使用的进程.
private String getRunningApp() {
long time = System.currentTimeMillis();
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_BEST,time-2000, time);
if (queryUsageStats == null || queryUsageStats.isEmpty()) {
return null;
}
UsageStats recentStats = null;
for (UsageStats usageStats : queryUsageStats) {
if (recentStats == null ||
recentStats.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
recentStats = usageStats;
}
}
return recentStats.getPackageName();
}