Android: Как программно включать и выключать экран? - PullRequest
91 голосов
/ 05 марта 2012

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

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

Отключение тестов дисплея

Я могу выключить экран с помощью:

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

IНе удалось отключить экран с помощью метода 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.

Ответы [ 14 ]

63 голосов
/ 14 марта 2012

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

Этот код:

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 Книги используют это, чтобы вы могли установить яркость экрана тусклой при использовании книги, а затем вернуться к обычной яркости при ее отключении.

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

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

32 голосов
/ 16 марта 2012

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

    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().

26 голосов
/ 16 марта 2012

Я бы предложил это:

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" />
20 голосов
/ 10 августа 2015

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

 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();
}
6 голосов
/ 25 марта 2016
     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

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

6 голосов
/ 13 марта 2012

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

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

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

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

4 голосов
/ 23 февраля 2013

Вот успешный пример реализации того же самого на устройстве, которое поддерживает более низкие значения яркости экрана (я тестировал на 7-дюймовом планшете Allwinner Chinese с 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);

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

3 голосов
/ 22 октября 2018

Это работает на Зефир

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();
    }
}
3 голосов
/ 01 февраля 2017

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

@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);
}

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

2 голосов
/ 24 января 2019

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

    android:keepScreenOn="true" 

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

    setKeepScreenOn(true) 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...