Android: как включить и выключить экран программно?

Прежде чем отмечать этот пост как "дубликат", я пишу этот пост, потому что никакая другая почта не имеет решения проблемы.

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

Отключить показания дисплея

Я могу отключить экран, используя:

params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);

Мне не удалось отключить экран, используя метод wl.release().

Включить проверку дисплея

Мое первое предположение, как показано ниже, не работает. Ничего не происходит, экран остается выключенным.

params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = -1f;
getWindow().setAttributes(params);

Я также попытался использовать wakelocks, без успеха.

PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "tag");
wl.acquire();

Наконец, я пробовал следующее, без результата.

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

В целом, я не получаю никаких ошибок в консоли для любого из этих методов. Мой тестовый текст "Экран должен быть включен", находится на экране, когда я включаю устройство с помощью кнопки питания. Это показывает, что код должен работать. Пожалуйста, ответьте только, если вы протестировали код, кажется, что многие из функций, таких как params.screenBrightness = -1, не работают так, как должны, согласно sdk.

Ответ 1

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

Этот код:

params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);

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

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

Теперь, чтобы вернуть экран к обычной яркости, просто установите значение яркости:

WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = -1;
getWindow().setAttributes(params);

Я не могу объяснить, почему это не заменит ранее установленное значение 0. В качестве теста вы можете попытаться установить принудительную полную яркость, чтобы заставить эту конкретную яркость:

WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1;
getWindow().setAttributes(params);

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

Чтобы отладить, вы можете использовать "окно dumpsys оболочки adb", чтобы увидеть текущее состояние вашего окна. В данных для вашего окна он скажет вам текущие LayoutParams, которые были установлены для него. Убедитесь, что вы действительно на самом деле находитесь.

И снова FLAG_KEEP_SCREEN_ON - это отдельная концепция; он и яркость не оказывают прямого воздействия друг на друга. (И не было бы причин снова устанавливать флаг при отмене яркости, если вы уже установили его при установке яркости на 0. Флаг останется установленным до тех пор, пока вы его не измените.)

Ответ 2

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

    private void unlockScreen() {
        Window window = this.getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    }

И назовите этот метод из onResume().

Ответ 3

Я бы предложил следующее:

PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
wl.acquire();

Флаг ACQUIRE_CAUSES_WAKEUP объясняется следующим образом:

Обычные блокировки от бодрствования фактически не включают подсветку. Вместо, они заставляют освещение оставаться включенным после его включения (например, из активность пользователя). Этот флаг заставит экран и/или клавиатуру немедленно включается, когда приобретается WakeLock. Типичное использование будет для уведомлений, которые важны для пользователя, чтобы видеть немедленно.

Кроме того, убедитесь, что у вас есть следующее разрешение в файле AndroidManifewst.xml:

<uses-permission android:name="android.permission.WAKE_LOCK" />

Ответ 4

Привет, надеюсь, это поможет:

 private PowerManager mPowerManager;
 private PowerManager.WakeLock mWakeLock;

 public void turnOnScreen(){
     // turn on screen
     Log.v("ProximityActivity", "ON!");
     mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
     mWakeLock.acquire();
}

 @TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
 public void turnOffScreen(){
     // turn off screen
     Log.v("ProximityActivity", "OFF!");
     mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
     mWakeLock.acquire();
}

Ответ 5

     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

//Файл манифеста пользователя   

Ответ 6

Вы уверены, что запросили правильное разрешение в вашем файле манифеста?

<uses-permission android:name="android.permission.WAKE_LOCK" />

Вы можете использовать класс AlarmManager 1, чтобы сбить намерение, которое начинает вашу деятельность, и получает блокировку слежения. Это включит экран и сохранит его. Освобождение wakelock позволит устройству самостоятельно спать.

Вы также можете взглянуть на использование PowerManager, чтобы установить устройство в режим сна: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)

Ответ 7

Вот успешный пример реализации того же самого, на устройстве, которое поддерживает более низкие значения яркости экрана (я тестировал на планшете Allwinner Chinese 7 "с API15).

WindowManager.LayoutParams params = this.getWindow().getAttributes();

/** Turn off: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO Store original brightness value
params.screenBrightness = 0.1f;
this.getWindow().setAttributes(params);

/** Turn on: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO restoring from original value
params.screenBrightness = 0.9f;
this.getWindow().setAttributes(params);

Если кто-то еще это попробует, комментарий PLS ниже, если он работал/не работал и устройство Android API.

Ответ 8

Лучший способ сделать это (с использованием корневых устройств):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    .
    .
    .

    int flags = WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
    getWindow().addFlags(flags); // this is how your app will wake up the screen
    //you will call this activity later

   .
   .
   .
}

Теперь у нас есть две функции:

private void turnOffScreen(){

  try{
     Class c = Class.forName("android.os.PowerManager");
     PowerManager  mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
     for(Method m : c.getDeclaredMethods()){
        if(m.getName().equals("goToSleep")){
          m.setAccessible(true);
          if(m.getParameterTypes().length == 1){
            m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
          }
        }
     } 
  } catch (Exception e){
  }
}

И это:

public void turnOnScreen(){
  Intent i = new Intent(this,YOURACTIVITYWITHFLAGS.class);
  startActivity(i);
}

Извините за мой плохой английский.

Ответ 9

Это работает над Marshmallow

private final String TAG = "OnOffScreen";
private PowerManager _powerManager;
private PowerManager.WakeLock _screenOffWakeLock;

public void turnOnScreen() {
    if (_screenOffWakeLock != null) {
        _screenOffWakeLock.release();
    }
}

public void turnOffScreen() {
    try {
        _powerManager = (PowerManager) this.getSystemService(POWER_SERVICE);
        if (_powerManager != null) {
            _screenOffWakeLock = _powerManager.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
            if (_screenOffWakeLock != null) {
                _screenOffWakeLock.acquire();
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

Ответ 10

Чтобы включить экран:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Возврат к режиму по умолчанию: просто очистите флаг FLAG_KEEP_SCREEN_ON

getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Ответ 11

Если ваше приложение является системным приложением, вы можете использовать PowerManager.goToSleep() для выключения экрана, вам требуется специальное разрешение

перед использованием goToSleep() вам нужно использовать отражение так же, как:

public static void goToSleep(Context context) {
    PowerManager powerManager= (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    try {
        powerManager.getClass().getMethod("goToSleep", new Class[]{long.class}).invoke(powerManager, SystemClock.uptimeMillis());
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
}

Теперь вы можете использовать goToSleep(), чтобы выключить экран.

Это то, что происходит при нажатии клавиши питания для выключения экрана.

Ответ 12

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

При просыпании возникает проблема блокировки экрана. Я не знаю, как любое приложение может автоматически обойти lockscreen.

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

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

Ответ 13

Что касается документации Android, ее можно достичь, используя следующую строку кода:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Я добавил это в мой метод onCreate, и он отлично работает.

В ссылке вы найдете разные способы достижения этого и общее объяснение.

Ссылка на документацию: https://developer.android.com/training/scheduling/wakelock.html

Ответ 14

Просто добавь

    android:keepScreenOn="true" 

или позвоните по телефону

    setKeepScreenOn(true) 

на родительском представлении.

Ответ 15

В соответствии с Android API 28 и выше вам нужно сделать следующее, чтобы включить экран

setShowWhenLocked(true); setTurnScreenOn(true); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); keyguardManager.requestDismissKeyguard(this, null);

Ответ 16

Бывают случаи, когда экран необходимо отключить ПОЛНОСТЬЮ. Если энергопотребление не очень важно для вашего приложения, класс PowerManager может использоваться в следующих случаях:

  • Используйте PowerManager.goToSleep(), чтобы отключить отображение экрана.
  • Используйте PowerManager.wakeUp(), чтобы включить экран.
  • Используйте PowerManager.isScreenOn(), чтобы получить состояние включения/выключения экрана. Кроме того, для этой цели используйте PowerManager.isInteractive() или Display.getState().

В следующем примере кода показано, как реализовать это решение:

    public class TestScreenOff {
    private static final String TAG = TestScreenOff.class.getSimpleName();

    private Activity                   mActivity; // Activity with which this class is associated.
    private PowerManager               mPowerManager;
    private boolean                    mScreenOn = true;

    // Constructor:
    private TestScreenOff(Activity activity) {
        Log.d(TAG, "==TestScreenOff");

        initialize(activity);
    }

    // Initialize activity-dependent fields:
    public void initialize(Activity activity) {
        Log.d(TAG, "==initialize");

        mActivity = activity;
        mPowerManager = (PowerManager) mActivity.getSystemService(Context.POWER_SERVICE);
    }

    // Gets screenOn:
    public boolean getScreenOn() {
        if(mPowerManager == null) {
            Log.e(TAG, "==getScreenOn: mPowerManager == null");
            return mScreenOn;
        }

        mScreenOn = mPowerManager.isScreenOn();

        Log.d(TAG, "==getScreenOn[" + mScreenOn + "]");

        return mScreenOn;
    }

    // Sets screenOn:
    public void setScreenOn(final boolean screenOn) {
        Log.d(TAG, "==setScreenOn[" + screenOn + "]");

        if(mPowerManager == null) {
            Log.e(TAG, "==setScreenOn: mPowerManager == null");
            return;
        }

        if(screenOn) {
            mPowerManager.wakeUp(SystemClock.uptimeMillis());
        } else {
            mPowerManager.goToSleep(SystemClock.uptimeMillis());
        }
    }
}

Данный код был протестирован на встроенном устройстве под управлением Android 4.4.2 (API уровня 19).

Обратите внимание, что некоторые из этих методов API не могут быть найдены в документации API Android, и вам необходимо указать соответствующие разрешения, такие как DEVICE_POWER.