Подтвердить что ты не робот

Android: широковещательный приемник для включения и выключения экрана

Мне просто интересно, можно ли зарегистрировать широковещательный приемник, который обнаруживает включение/выключение экрана в манифесте приложения. Причина, по которой мне не нравится программируемый метод, заключается в том, что приложение должно работать, чтобы обнаружить такую ​​вещь, в то время как: "Приложения с широковещательными приемниками, зарегистрированными в манифесте, не должны запускаться, когда Intent транслируется для приемников для выполнения" (источник: Professional Android 2 Application Development book)

Мое приложение на самом деле является приложением lockscreen, которое с помощью программируемого способа должно работать все время: S

Есть ли способ?

Я пробую в манифесте следующее:

<receiver android:name=".MyBroadCastReciever">
    <intent-filter>
        <action android:name="android.intent.action.SCREEN_OFF"/>
        <action android:name="android.intent.action.SCREEN_ON"/>
    </intent-filter>
</receiver>

и простой класс MyBroadCastReciever:

public class MyBroadCastReciever extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.i("Check","Screen went OFF");
            Toast.makeText(context, "screen OFF",Toast.LENGTH_LONG).show();
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            Log.i("Check","Screen went ON");
            Toast.makeText(context, "screen ON",Toast.LENGTH_LONG).show();
        }
    }
}
4b9b3361

Ответ 1

Два действия для включения и выключения экрана:

android.intent.action.SCREEN_OFF
android.intent.action.SCREEN_ON

Но если вы зарегистрируете приемник для этих трансляций в манифесте, то приемник не получит эти трансляции.

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

PS: запустите службу на переднем плане, чтобы она работала дольше.

Простой фрагмент кода будет примерно таким:

IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, screenStateFilter);

Не забудьте отменить регистрацию получателя в службе onDestroy:

unregisterReceiver(mScreenStateReceiver);

На всякий случай для людей, которые спрашивают, почему получатель не работает с объявлением трансляций в манифесте для ACTION_SCREEN_ON и ACTION_SCREEN_OFF:

https://developer.android.com/reference/android/content/Intent.html#ACTION_SCREEN_ON https://developer.android.com/reference/android/content/Intent.html#ACTION_SCREEN_OFF

Вы не можете получить это через компоненты, объявленные в манифесте, только путем явной регистрации для него с помощью Context.registerReceiver().

Это защищенный замысел, который может быть отправлен системой.

Ответ 2

Вам нужно создать фоновый сервис, чтобы проверить его. Затем вы можете установить его программно.