获取前台进程包名(ForegroundProcess)
在之前我们可以通过下面的方式获取到前台进程的包名
public String getForegroundApp(Context context) {
ActivityManager mActivityManager =
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (mActivityManager.getRunningTasks(1) == null) {
return null;
}
ActivityManager.RunningTaskInfo mRunningTask =
mActivityManager.getRunningTasks(1).get(0);
if (mRunningTask == null) {
return null;
}
String pkgName = mRunningTask.topActivity.getPackageName();
return pkgName;
}
最新的Android版本中google已经收紧权限了,只能获取到自己APP的进程信息,所以我们可以通过下面的方式获取前台进程。
public static String getForegroundApp() {
File[] files = new File("/proc").listFiles();
int lowestOomScore = Integer.MAX_VALUE;
String foregroundProcess = null;
for (File file : files) {
if (!file.isDirectory()) {
continue;
}
int pid;
try {
pid = Integer.parseInt(file.getName());
} catch (NumberFormatException e) {
continue;
}
try {
String cgroup = read(String.format("/proc/%d/cgroup", pid));
String[] lines = cgroup.split("\n");
String cpuSubsystem = null;
String cpuaccctSubsystem = null;
// 我们取cpu和cpuacct两行数据
for (String s : lines) {
if (s.contains(":cpu:")) {
cpuSubsystem = s;
}
if (s.contains(":cpuacct:")) {
cpuaccctSubsystem = s;
}
}
if (!cpuaccctSubsystem.endsWith(Integer.toString(pid))) {
// not an application process
continue;
}
if (cpuSubsystem.endsWith("bg_non_interactive")) {
// background policy
continue;
}
int uid = Integer.parseInt(cpuaccctSubsystem.split(":")[2]
.split("/")[1].replace("uid_", ""));
if (uid >= 1000 && uid <= 1038) {
// system process
continue;
}
int appId = uid - AID_APP;
int userId = 0;
// loop until we get the correct user id.
// 100000 is the offset for each user.
while (appId > AID_USER) {
appId -= AID_USER;
userId++;
}
if (appId < 0) {
continue;
}
// u{user_id}_a{app_id} is used on API 17+ for multiple user
// account support.
// String uidName = String.format("u%d_a%d", userId, appId);
File oomScoreAdj = new File(String.format(
"/proc/%d/oom_score_adj", pid));
if (oomScoreAdj.canRead()) {
String str = read(oomScoreAdj.getAbsolutePath());
int oomAdj = Integer.valueOf(str);
if (oomAdj != 0) {
continue;
}
}
String cmdline = read(String.format("/proc/%d/cmdline", pid));
if (cmdline.contains("com.android.systemui") || cmdline.contains("dirac")) {
continue;
}
int oomscore = Integer.parseInt(read(String.format(
"/proc/%d/oom_score", pid)));
if (oomscore < lowestOomScore) {
lowestOomScore = oomscore;
foregroundProcess = cmdline;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return foregroundProcess;
}
private static String read(String path) throws IOException {
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(path));
output.append(reader.readLine());
for (String line = reader.readLine(); line != null; line = reader
.readLine()) {
output.append('\n').append(line);
}
reader.close();
return output.toString().trim();// 不调用trim(),包名后会带有乱码
}
当然该方法也有缺点,就是需要进行IO操作,所以速度会比较慢。