Intereting Posts
Можно ли узнать, работает ли приложение Android как часть контрольно-измерительного теста Проблема с & и двойными кавычками в моем приложении для Android Как определить, является ли какая-либо из моих операций самой фронтальной и видимой для пользователя? Приложение зависает / замерзает при использовании функции camera.open () – требуется перезапуск устройства Активность просочилась в окно изменения ориентации при открытии SubMenu Fragment_display_message: Моя первая ошибка приложения для Android OnGestureListener # onScroll не вызывается из GestureDetector на Samsung Galaxy Note 10.1 Ошибка сбора данных в Android Studio Android: Ошибка медиаплеера Не ​​удалось воспроизвести на стороне клиента Ошибка приложения не установлена ​​на Android Как создать список с липким столбцом, как Календарь Google XPathExpression не оценивается в надлежащем контексте? EditText и InputFilter вызывают повторяющийся текст Цвет подсказки TextInputLayout Bad FPS в 2D-андроиде / java-игре на устройствах с высоким разрешением

Android – Как определить, когда запускается приложение для 3D-вечеринки

В настоящее время я разрабатываю приложение для планшетов, которое покажет рекламу в магазинах. Мне нужно добавить защиту паролем для приложения настроек. Для этого мне нужно обнаружить, что приложение настроек запущено в фоновом режиме. Для устройств с Android ниже API 21 это можно сделать с помощью getRunningTasks () . К сожалению, этот метод устарел. Я попытался достичь своей цели с помощью этого ответа , но все работает не так, как мне нужно. Я пытаюсь слушать V/WindowManager( 740): Adding window Window{1f4535ef u0 com.android.settings/com.android.settings.Settings} at 9 of 16 (before Window{e14eed2 u0 Starting com.android.settings}) Но я не могу видеть его как результат. Я использую код из ответа, на который я ссылался выше. Вместо того, чтобы поджарить его, я печатаю его в логарифме.

Можете ли вы рассказать мне, как моя цель может быть достигнута для версий Android выше API 21? Я знаю, что это возможно, потому что такие приложения, как Smart AppLock, делают это. Заранее спасибо!

В настоящее время невозможно получить приложение foreground на Android 5.1.1+, если вам не предоставлено разрешение на уровне системы android.permission.PACKAGE_USAGE_STATS . Обратите внимание, что несколько крупных поставщиков удалили системную активность, которая предоставляет доступ к API UsageStats с их устройств. Это означает, что приложения на этих устройствах никогда не смогут получить необходимое разрешение. Это может измениться при обновлении системы.

Вы упомянули, что Smart Lock (App Protector) может обнаружить текущую активность переднего плана на Android M. При первом открытии Smart Lock (или подобных приложений) вам будет предложено предоставить разрешение PACKAGE_USAGE_STATS . Поэтому мы можем заключить, что они полагаются на UsageStatsManager чтобы получить приложение переднего плана.

Я попытался найти обходное решение (взломать), чтобы получить приложение переднего плана на Android M без разрешения на системном уровне. Пожалуйста, прочтите и попробуйте мой сценарий в моем ответе здесь: Android 5.1.1 и выше – getRunningAppProcesses () возвращает только мой пакет приложений


Logcat

Если у вас нет прав на root, чтение логарифма для получения приложения переднего плана не будет работать. Чтение logcat, поскольку Jelly Bean возвращает только сообщения журнала из вашего приложения.


Полезные ссылки:

Как проверить, разрешено ли разрешение «android.permission.PACKAGE_USAGE_STATS»?

Как использовать UsageStatsManager?

https://code.google.com/p/android-developer-preview/issues/detail?id=2347


Редактировать:

После копания через Android-источник я написал следующий код, чтобы получить приложение foreground на Android M без каких-либо разрешений. Я тестировал его только на Nexus 9, где был запущен последний предварительный просмотр. Скопируйте и вставьте код в класс в свой проект и проверьте его, вызвав статический метод getForegroundApp() :

 /** 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"); if (lines.length != 2) { continue; } String cpuSubsystem = lines[0]; String cpuaccctSubsystem = lines[1]; 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(); }