Получить (реальный) процесс переднего плана с помощью activityManager.getRunningAppProcesses()
Я пытаюсь определить видимое в данный момент приложение для пользователя. Для этого я использую activityManager.getRunningAppProcesses()
метод.
Я знаю, что этот метод не поддерживается как Android 5.1.1 - это нормально.
В начале это работало как очарование, я перебираю список RunningAppProcessInfos и проверяю на важность.
tl; dr Как правильно получить текущий процесс переднего плана и предотвратить ложные предположения? Как устроен порядок списка - API говорит, что он не указан. Есть ли способ правильно их заказать?
Что я сделал:
К сожалению, список, возвращаемый ActivityManager, отличается на каждом устройстве. Некоторые устройства возвращают многократную информацию со значением 100 (что ЗАЯВКА), даже если процесс в настоящее время не виден.
Это вызвало проблему, что у меня было много ложных срабатываний. Например, я протестировал его с помощью Face book и создал тост, каждый раз, когда Face book находится на переднем плане. Я переключился на "Домой", поэтому моя программа запуска должна была быть на переднем плане. Это было в течение примерно 10 секунд, после этого, Face book снова появился в списке со значимостью ЗАПИСЬ (он не был открыт и не виден), и я получил ложный положительный результат.
Я понял, что некоторые устройства упорядочивают список по недавнему процессу сверху. Поэтому я решил попробовать следующий подход:
ActivityManager.RunningAppProcessInfo appProcess = appProcesses.get(0);
final String processName = appProcess.processName;
final String packageName = removeProcessSuffix(processName);
if (appProcess.importance == FOREGROUND || appProcess.importance == VISIBLE){
//do something, like the toast
}
С appProcesses.get(0); Я только исследую первый элемент, и ошибка исчезла. Больше никаких ложных срабатываний.
Но теперь на некоторых устройствах у меня больше нет процесса переднего плана. Потому что они никак не упорядочивают список. Например, некоторые 4.2 смартфоны Sony являются одними из кандидатов. Я получаю список, но реально видимый в данный момент процесс находится в индексе 11 или около того.
Я понятия не имею, что делать, чтобы получить текущий приоритетный процесс, без ложных срабатываний.
Каков правильный метод, чтобы получить текущий процесс переднего плана и предотвратить ложные предположения? Как устроен порядок списка - API говорит, что он не указан. Есть ли способ правильно их заказать?
Спасибо!
1 ответ
Какой правильный метод для получения текущего процесса переднего плана и предотвращения ложных срабатываний?
UsageStatsManager - единственный официальный API для получения текущего запущенного приложения ( см. # 50).
С помощью getRunningTasks(int maxNum)
, getRunningAppProcesses()
или же AccessibilityService
чтобы получить приложение переднего плана никогда не было надежным. Документация для первых двух методов имеет следующее предупреждение: Note: this method is only intended for debugging
Ниже приведен пример получения лучшего приложения с помощью UsageStatsManager:
Calendar endCal = Calendar.getInstance();
Calendar beginCal = Calendar.getInstance();
beginCal.add(Calendar.MINUTE, -30);
UsageStatsManager manager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
List<UsageStats> stats = manager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
beginCal.getTimeInMillis(), endCal.getTimeInMillis());
Collections.sort(stats, new Comparator<UsageStats>() {
@Override public int compare(UsageStats lhs, UsageStats rhs) {
long time1 = lhs.getLastTimeUsed();
long time2 = rhs.getLastTimeUsed();
if (time1 > time2) {
return -1;
} else if (time1 < time2) {
return 1;
}
return 0;
}
});
// The first "UsageStats" in the list will be the top application.
// If the list is empty you will need to ask for permissions to use UsageStatsManager
// To request permission:
// startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
Я знаю, что это не тот ответ, на который вы надеетесь. Такие приложения, как CM Security и AppLock, используют UsageStatsManager на Android 5.1.1+. Из-за SeLinux невозможно получить приложение переднего плана, используя getRunningTasks(int maxNum)
или же getRunningAppProcesses()
,