Обнаружение наложения экрана - как справиться с этим в приложении наложения экрана

Некоторые устройства имеют дополнительные функции безопасности и проверяют, рисует ли приложение поверх других при отображении диалогового окна разрешений.

У меня есть приложение боковой панели, и мое приложение должно быть отключено, прежде чем пользователи смогут принять системный диалог.

Вопросы

  • Как я должен обращаться с этим делом?
  • Есть ли способ прослушать событие "Системное диалоговое окно", чтобы я мог удалить боковую панель и "Системный диалог завершен", чтобы я знал, что могу продолжить мой набросок боковой панели? Я знаю, что этого достаточно, чтобы остановить службу (вам не нужно удалять разрешение), так что это тоже будет решение.

ИЗМЕНИТЬ

Одно из решений, о котором я могу думать, следующее:

Использование AccessibilityService для проверки текущих приложений/представлений переднего плана. Там я смогу проверить события, которые показывают текущие фоновые действия и даже представления...

Мои проблемы:

  • Я не знаю, как определить там диалог разрешений.
  • Во-вторых, это заставляет меня попросить пользователя получить это разрешение (чего я хочу избежать, но имея решение с этой службой, уже будет для меня улучшением, потому что некоторые пользователи уже дают это разрешение моему приложению - Я должен был бы все спросить и объяснить причину, с которой я могу жить).

Ответ 1

Насколько я знаю, то, что вы хотите, невозможно. В аналогичном question есть решение для обнаружения системных диалогов, но я не думаю, что он будет работать для вашего наложения (только для текущей активности).

Другой question предполагает, что можно контролировать системные диалоги с помощью ActivityManager, но этот API был устаревшим с LOLIPOP.

По этим причинам я предлагаю вам добавить кнопку паузы на ваш оверлей. Или даже лучше, используйте кнопки notification с кнопками остановки/запуска, чтобы пользователи могли вручную приостановить наложение.


Чтобы определить системные приложения, вам нужно имя пакета, как описано в этом ответе:
public boolean isSystemApp(String packageName) {
    try {
        // Get packageinfo for target application
        PackageInfo targetPkgInfo = mPackageManager.getPackageInfo(
                packageName, PackageManager.GET_SIGNATURES);
        // Get packageinfo for system package
        PackageInfo sys = mPackageManager.getPackageInfo(
                "android", PackageManager.GET_SIGNATURES);
        // Match both packageinfo for there signatures
        return (targetPkgInfo != null && targetPkgInfo.signatures != null && sys.signatures[0]
                .equals(targetPkgInfo.signatures[0]));
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}