android+5.1+获取前台,android 5.1及以上获取正在运行的app(top app)

1.android 5.0以下:

((ActivityManager.RunningAppProcessInfo)((ActivityManager)paramContext.getSystemService("activity")).getRunningAppProcesses().get(0)).processName;

2.android 5.0:

((ActivityManager.RunningTaskInfo)((ActivityManager)paramContext.getSystemService("activity")).getRunningTasks(1).get(0)).topActivity;

3.android 5.1及以上:

使用他写的code:https://github.com/jaredrummler/AndroidProcesses,但是获取的是列表,不能判断哪一个进程是当然显示的应用,用于判断的foreground参数能返回多个true的情况。这个大神又在回答这个问题放出获取当前应用的代码。贴一下代码:

/** first app user */

public static final int AID_APP = 10000;

/** offset for uid ranges for each user */

public static final int AID_USER = 100000;

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;

String cpuaccctSubsystem;

if (lines.length == 2) {//有的手机里cgroup包含2行或者3行,我们取cpu和cpuacct两行数据

cpuSubsystem = lines[0];

cpuaccctSubsystem = lines[1];

}else if(lines.length==3){

cpuSubsystem = lines[0];

cpuaccctSubsystem = lines[2];

}else {

continue;

}

if (!cpuaccctSubsystem.endsWith(Integer.toString(pid))) {

// not an application process

continue;

}

if (cpuSubsystem.endsWith("bg_non_interactive")) {

// background policy

continue;

}

String cmdline = read(String.format("/proc/%d/cmdline", pid));

if (cmdline.contains("com.android.systemui")) {

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()) {

int oomAdj = Integer.parseInt(read(oomScoreAdj.getAbsolutePath()));

if (oomAdj != 0) {

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(),包名后面会带有乱码

}  依照大神的代码,在实际测试中有的手机能返回当然的包名,有的还是返回null,比照系统文件和代码分析,发现有的手机里cgroup包含两行cpu 和cpuacct,有的则是三行,多了一行memory。所以对代码稍加改动,上面是改动过的。下面对调用的文件和文件内容解释一下:

1.proc下以数字命名的文件夹,文件夹名即是一个进程的pid,该文件夹下的文件包含这个进程的信息;

2.cgroup,控制组群(control groups)的简写,是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。cpu:设置cpu的使用率;cpuacct:记录cpu的统计信息。

3.bg_non_interactive,运行cpu的一个分组,另一分组是apps,当一个应用(进程)即可从apps分组切换到bg_non_interactive,也可以切换回来。apps分组可以利用95%的cpu,而bg_non_interactive只能使用大约5%。

4.cmdline,显示内核启动的命令行。

5.oom_score_adj,这个文件的数值用来标记在内存不足的情况下,启发式的(不知道怎么翻译好==)选择哪个进程被杀掉,值从0(从不被杀掉)到1000(总是被杀掉)。

完整的代码,稍后会上到GitHub.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值