Что стоит учесть при разработке приложения для специальных возможностей в Android?

Рейтинг: 1Ответов: 1Опубликовано: 11.07.2023

Я наткнулся на проблему описанную в вопросе на этом же форуме - см. Служба специальных возможностей неисправна.

Покапавшись в сети я нашел этот сайт - см. Сервис работает некорректно Xiaomi спец возможности. В нем написано следующие:

  1. Включите администрирование устройства. Сделав это, пришло время заглянуть в меню «Администрирование устройства». Приложения с правами администратора устройства остаются в памяти и редко отключаются в настройках специальных возможностей.

Что, конечно, не является техническим ликбезом, но это всё что я нашел, что хоть косвенно, но связано с этой проблемой.

Моему приложению выдано разрешение IGNORE_BATTERY_OPTIMIZATIONS, Wake Lock также используется.

Тогда у меня возник вопрос, а как другие разработчики с этим справляются?

Вопросы

  1. Правильно ли я делаю, включая Wake Lock только в ресивере:

    public class ScreenReceiver extends BroadcastReceiver {
    
    public static boolean wasScreenOn = true;
    
    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            // do whatever you need to do here
            wasScreenOn = false;
            System.out.println("Экран: выключен");
            // Включить блокировку спящего режима для своего приложения:
            MyService.wakeLock.acquire();
            System.out.println("Включить блокировку спящего режима для своего приложения");
    
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            // and do whatever you need to do here
            wasScreenOn = true;
            System.out.println("Экран: включен");
            // Выключить блокировку спящего режима для своего приложения:
            MyService.wakeLock.release();
            System.out.println("Выключить блокировку спящего режима для своего приложения");
        }
      }
    }
    

    Ну, т.е в MyService и в AccessibilityService нет включений кода:

    MyService.wakeLock.release() и MyService.wakeLock.acquire()
    

    Правильно ли я понимаю, что wake lock нужно включать в каждом жизненном цикле отдельно, т.е в классах наследующих Service и AccessibilityService?

  2. Что ещё мне стоит знать, чтобы служба спец возможностей работала стабильно и без перебоев?

Ответы

▲ 0

Тогда у меня возник вопрос, а как другие разработчики с этим справляются?

С проблемой спец возможности работают некорректно, можно справится поставив wake lock, но не там где я поставил.

  1. Wake lock обычно прописывают в классах, у которых есть свой жизненный цикл. Таких как Activity, Service, IntentService. В AccessibilityService прописывать wake lock не нужно, т.к он является автономным и его жизненный цикл управляется непосредственно Android OS. У ресиверов жизненный цикл отсутствует вовсе. Их код просто переодически вызывается системой и только тогда код ресивера активный.

  2. Также я заметил, что в службах прописывать код Wake Lock также не требуется, если служба работает не постоянно, а запускается той которая работает постоянно. Т.е если MainService запускает службу GPSTraker и после какого-то времени служба отключается, в ней реализовывать wake lock не обязательно(у меня это и так работает).

в службе или активности нужно прописывать код создания Wake Lock:

PowerManager.WakeLock wakeLock = null;

@Override
public void onTaskRemoved(Intent rootIntent) {
     
           if (wakeLock != null)
           {
               if (wakeLock.isHeld() == true)
               {
                   wakeLock.release();
               }
           }
}

@Override
public void onDestroy() {
            super.onDestroy();

            if (wakeLock != null)
            {
                if (wakeLock.isHeld() == true)
                {
                    wakeLock.release();
                }
            }
}

@Override
public void onCreate() {

            super.onCreate();

            PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);
            if (wakeLock == null)
            {
                wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PeriSecure:MyWakeLock");
            }
            if (wakeLock != null)
            {
                if (wakeLock.isHeld() == false)
                {
                    wakeLock.acquire();
                }
            }
}

В каждом классе нужно создать новый WakeLock, а не использовать старый!!!

Надеюсь я понятно объяснил. Хотя, в Android документации объясняют не лучше..

В моём случае, я не там включал WakeLock и Android перезапускал службу спец возможностей, это видимо и приводило к не корректной работе. Как описывается в Accessibility Service is malfunctioning.

Это не из вашего приложения. После завершения работы вашего приложения системой. При следующей попытке включить службу специальных возможностей всегда не удается запустить службу специальных возможностей. Это ошибка Android. Android не удается запустить службу специальных возможностей после завершения работы службы. Вы ничего не можете с этим поделать. Кто-то уже отправил отчет об ошибке в Google в 2016 году, но это не было исправлено. Проверьте это: issuetracker.google.com/issues/37123359

Что ещё мне стоит знать, чтобы служба спец возможностей работала стабильно и без перебоев?

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

Моё предложение: по ходу, разберемся )