FLAG_TURN_SCREEN_ON не всегда работает - PullRequest
10 голосов
/ 31 марта 2012

я запускаю действие с BroadcastReceiver, который запускается аларамом (тип RTC_WAKEUP).при создании этой операции я добавляю эти флаги

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON        
);

проблема в том, что иногда (примерно в 10% случаев) экран не включается.Будильник правильно сработал (здесь звук уведомления, который также срабатывает в onReceive () приемника. Затем, если я нажму кнопку питания телефона, экран включится, показывая мою активность, и сразу же выключится.что кнопка питания работает хорошо. это происходит на Android 2.3.7 и вот метод onReceive ()

@Override
public void onReceive(Context context, Intent intent) {
    m_Context = context;

    Bundle extras = intent.getExtras();
    final int id = extras.getInt("timer_id");

    Intent activityIntent = new Intent(m_Context, MyActivity.class);
    activityIntent.putExtra("timer_id", id);
    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    m_Context.startActivity(activityIntent);

    // and now load the alarm sound and play it for the desired time
    showFinishedNotification();
}

я хотел бы избежать использования PowerManager, так как для этого требуется разрешение, а флагипредпочтительный способ.

в чем может быть проблема? logcat не показывает никаких проблем ...

Ответы [ 4 ]

8 голосов
/ 30 апреля 2015

Я немного опоздал на вечеринку здесь, но я боролся с этим некоторое время и наконец нашел способ заставить экран разблокироваться каждый раз.Я добавляю флаги в событие onAttachToWindow ().Обычно я делаю это из WakefulBroadcastReceiver, поэтому экран плавно переключается, но это зависит от варианта использования.

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    //Screen On
    getWindow().addFlags(
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}

private void clearFlags() {
    //Don't forget to clear the flags at some point in time.
    getWindow().clearFlags(
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
6 голосов
/ 16 мая 2016

Из моего опыта и исследований по этой теме:

  • FLAG_TURN_SCREEN_ON не может использоваться для многократного включения и выключения экрана в вашем приложении.

  • FLAG_TURN_SCREEN_ON можно использовать только один раз, чтобы включить экран, когда создает новую активность (предпочтительно в onCreate ()метод) или при воссоздании вида .

Теперь вы можете обойти это ограничение:

  • Запуск нового действия и установка там флага, затем завершение действия (пользователем или программным способом), чтобы отключить экран.
  • Установка параметров params.screenBrightness на настолько «тусклый», насколько это возможно , иногда экран «выключен».Затем вы можете увеличить яркость, чтобы «включить» экран.Однако это часто не работает, поскольку экран по-прежнему тусклый, но видимый, также это не работает, если пользователь блокирует телефон.
  • Использование Power Manager Wakelock (это по-прежнему работаетно Android отказался от этой функциональности, поэтому они не рекомендуют использовать эту технику).Однако, насколько я могу судить, это единственный способ заставить мое приложение надежно включать / выключать экран.

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

Подробнее вы можете прочитать здесь:

4 голосов
/ 31 марта 2012

проблема в том, что иногда (примерно в 10% случаев) экран не включается

Если бы мне пришлось угадывать, устройство снова засыпает, прежде чем начнется активность. Как только onReceive() вернется, устройство может и снова заснет, и пройдет некоторое время после того, как onReceive() вернется, прежде чем начнется ваша деятельность.

Этот же сценарий, но с заменой startActivity() на startService(), поэтому я должен был написать WakefulIntentService, который использует WakeLock, чтобы гарантировать, что устройство не спит достаточно долго для него чтобы сделать свою работу, то выпускает WakeLock.

2 голосов
/ 19 сентября 2018

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

public static void turnScreenOnThroughKeyguard(@NonNull Activity activity) {
    userPowerManagerWakeup(activity);
    useWindowFlags(activity);
    useActivityScreenMethods(activity);
}

private static void useActivityScreenMethods(@NonNull Activity activity) {
    if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) {
        try {
            activity.setTurnScreenOn(true);
            activity.setShowWhenLocked(true);
        } catch (NoSuchMethodError e) {
            Log.e(e, "Enable setTurnScreenOn and setShowWhenLocked is not present on device!");
        }
    }
}

private static void useWindowFlags(@NonNull Activity activity) {
    activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
            | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}

private static void userPowerManagerWakeup(@NonNull Activity activity) {
    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    WakeLock wakelock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, tag);
    wakeLock.acquire(TimeUnit.SECONDS.toMillis(5));
}
...