Intereting Posts
Исходные чертежи SearchView в ActionBar выглядят размытыми Самый быстрый способ найти, если int array содержит число Восстановление иерархии представлений из сохраненного состояния не восстанавливает добавленные представления Ошибка раздувания фрагмента класса, Xamarin Получение идентификатора оборудования NFC на Android Как я могу перетащить несколько изображений на другие образы viewviews android Измените элемент внутри слоя-листа drawable xml Android webview, запускайте действие ACTION_VIEW, когда URL-адрес не может обрабатываться webview Android-телефоны не открывают PDF-поток после обратной передачи на сайте ASP.Net Ограничение частоты кадров при использовании Thread.sleep () Передача данных через фрагменты в viewpager JSoup не анализирует страницу известных версий Android Являются ли статические сквозные версии ресурса ресурса R.xxx.xxx? Выполнение не выполнено для задачи ': app: dexDebug' Android Studio Android Google Map – маркер Clicked открывает новую активность или большее окно

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(); }