Android: Bagaimana cara menghidupkan dan mematikan layar secara terprogram?

98

Sebelum menandai posting ini sebagai "duplikat", saya menulis posting ini karena tidak ada posting lain yang memiliki solusi untuk masalah tersebut.

Saya mencoba mematikan perangkat, lalu setelah beberapa menit atau sensor berubah, hidupkan kembali.

Matikan Tes Tampilan

Saya bisa mematikan layar menggunakan:

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

Saya tidak dapat mematikan layar menggunakan metode wl.release ().

Nyalakan Tes Tampilan

Tebakan pertama saya, sebagai berikut, tidak berhasil. Tidak ada yang terjadi, layar tetap mati.

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

Saya juga kemudian mencoba menggunakan wakelocks, tetapi tidak berhasil.

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

Akhirnya saya mencoba yang berikut ini, tanpa hasil.

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

Secara keseluruhan, saya tidak mendapatkan kesalahan apa pun di konsol untuk salah satu metode ini. Teks pengujian saya "Layar harus menyala", ada di layar saat saya menyalakan perangkat menggunakan tombol daya. Ini menunjukkan bahwa kode seharusnya sudah berjalan. Tolong jawab saja jika anda sudah menguji kodenya, sepertinya banyak fungsi seperti params.screenBrightness = -1, tidak berfungsi sebagaimana mestinya sesuai dengan sdk.

thegreyspot
sumber
1
Metode Anda untuk mematikan layar tidak berhasil untuk saya. Anda menyetel bendera agar layar tetap menyala sepanjang waktu, yang akan menghabiskan daya.
Kristy Welsh
Apakah Anda pernah memikirkan hal ini? Ada beberapa aplikasi di PlayStore yang menyarankan mereka melakukannya. Sudah mencoba yang ini dan berhasil tetapi meminta Administrasi Perangkat. play.google.com/store/apps/…
George
apakah Anda mencapai sesuatu dalam masalah ini? !!
Muhammed Refaat

Jawaban:

69

Saya akan menganggap Anda hanya ingin ini berlaku saat aplikasi Anda berada di latar depan.

Kode ini:

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

Tidak mematikan layar dalam pengertian tradisional. Itu membuat layar menjadi redup mungkin. Pada platform standar ada batasan seberapa redupnya; jika perangkat Anda benar-benar memungkinkan layar untuk mati sepenuhnya, maka itu adalah beberapa keanehan dari penerapan perangkat itu dan bukan perilaku yang dapat Anda andalkan di seluruh perangkat.

Bahkan menggunakan ini dalam hubungannya dengan FLAG_KEEP_SCREEN_ON berarti Anda tidak akan pernah membiarkan layar mati (dan dengan demikian perangkat masuk ke mode daya rendah) bahkan jika perangkat tertentu memungkinkan Anda untuk mengatur kecerahan layar menjadi mati penuh. Ingatlah ini dengan sangat kuat. Anda akan menggunakan lebih banyak daya daripada jika layar benar-benar mati.

Sekarang untuk mengembalikan layar ke kecerahan biasa, cukup dengan mengatur nilai kecerahan sudah cukup:

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

Saya tidak bisa menjelaskan mengapa ini tidak menggantikan nilai 0 yang telah Anda tetapkan sebelumnya. Sebagai ujian, Anda dapat mencoba menempatkan kecerahan penuh paksa di sana untuk memaksa kecerahan spesifik itu:

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

Ini pasti berhasil. Misalnya, aplikasi Buku Google menggunakan ini untuk memungkinkan Anda menyetel kecerahan layar menjadi redup saat menggunakan buku dan kemudian kembali ke kecerahan biasa saat mematikannya.

Untuk membantu men-debug, Anda dapat menggunakan "jendela adb shell dumpsys" untuk melihat status jendela Anda saat ini. Dalam data untuk jendela Anda, ini akan memberi tahu Anda LayoutParams saat ini yang telah ditetapkan untuknya. Pastikan nilai yang menurut Anda benar-benar ada.

Dan lagi, FLAG_KEEP_SCREEN_ON adalah konsep yang terpisah; dan kecerahan tidak berdampak langsung satu sama lain. (Dan tidak akan ada alasan untuk menyetel bendera lagi saat membatalkan kecerahan, jika Anda telah mengaturnya saat mengatur kecerahan ke 0. Bendera akan tetap disetel sampai Anda mengubahnya.)

hackbod
sumber
8
Apakah ada cara yang lebih baik untuk mematikan screeen?
akash
Seperti yang dikatakan @hackbod di atas, "params.screenBrightness = 0;" tidak mematikan layar sepenuhnya; sebagai gantinya, ini membuat layar menjadi redup mungkin. Dan "params.screenBrightness = -1;" memutar layar kembali ke tingkat kecerahan sebelumnya. Namun, ada kasus di mana kami perlu mematikan layar sepenuhnya. Mungkin ada metode lain ...
jonathanzh
6
Apa metode lain yang sebenarnya mematikan layar daripada hanya mengatur kecerahan minimum yang mungkin atau mungkin tidak berfungsi?
Michael
37

Saya telah menulis metode ini untuk menghidupkan layar setelah kunci layar. Ini bekerja dengan sempurna untuk saya. Cobalah-

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

Dan panggil metode ini dari onResume().

Rajkiran
sumber
1
Tidak berguna jika Anda berencana menyalakan layar saat Anda ingin menghentikan aktivitas.
AndroidDev
7
Baiklah, saya akan menyarankan untuk tidak menggunakan metode saya karena ini tidak berhasil untuk saya di Micromax Canvas2 +. Gunakan tautan ini sebagai gantinya.
Rajkiran
28

Saya akan menyarankan yang ini:

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

Bendera ACQUIRE_CAUSES_WAKEUP dijelaskan seperti itu:

Penguncian layar saat aktif normal tidak benar-benar mengaktifkan iluminasi. Sebaliknya, mereka menyebabkan iluminasi tetap menyala setelah dinyalakan (misalnya dari aktivitas pengguna). Bendera ini akan memaksa layar dan / atau keyboard untuk segera menyala, saat WakeLock diperoleh. Penggunaan tipikal adalah untuk notifikasi yang penting bagi pengguna untuk segera melihatnya.

Selain itu, pastikan Anda memiliki izin berikut di file AndroidManifewst.xml:

<uses-permission android:name="android.permission.WAKE_LOCK" />
ramdroid.dll
sumber
3
Sayangnya, bendera SCREEN_BRIGHT_WAKE_LOCK sudah tidak digunakan lagi.
Camille Sévigny
20

Hai, saya harap ini akan membantu:

 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();
}
mangu23
sumber
Bagaimana cara mematikan layar tanpa melibatkan sensor jarak?
Michael
Hai @Michael, Anda cukup menggunakan fungsi public void turnOffScreen () saja
mangu23
3
Ya, tetapi tampaknya fungsi ini menggunakan PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCKyang hanya mematikan layar saat sensor jarak berada dalam status "dekat".
Michael
Ahh oke saya mengerti, Anda dapat menggunakan ini sebagai gantinya PowerManager.SCREEN_DIM_WAKE_LOCK
mangu23
1
Masalah - segera setelah saya melepaskan PROXIMITY_SCREEN_OFF_WAKE_LOCKkunci tunggu, layar kembali menyala. Bagaimana cara mencegahnya?
Michael
7
     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

// File Manifes Pengguna

Pir Fahim Shah
sumber
2
Ini harus menjadi jawaban yang benar. Saya menggunakan Android 5 dan ini adalah satu-satunya hal yang benar-benar berfungsi. Satu-satunya sidenote adalah SCREEN_BRIGHT_WAKE_LOCK sudah usang, dan saya tidak melihat penggantinya. Siapa saja?
HammerNL
Tidak ada masalah, jawaban Anda sangat berguna. Seperti yang saya katakan: "itu satu-satunya jawaban yang benar-benar berfungsi"
HammerNL
@HammerNL apa perbedaan antara jawaban ini dan jawaban yang diberikan oleh ramdroid?
Bug Terjadi
@BugsHappen Ramdroids satu lebih rumit :) Tapi ya, itu sama. Tidak tahu mengapa Pir Fahim Shah memposting jawaban ini, atau mengapa saya tidak melihat Ramdroids satu per satu.
HammerNL
6

Apakah Anda yakin Anda meminta izin yang sesuai di file Manifest Anda?

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

Anda bisa menggunakan kelas AlarmManager 1 untuk mengaktifkan maksud yang memulai aktivitas Anda dan memperoleh kunci bangun. Ini akan menghidupkan layar dan tetap menyala. Melepaskan wakelock akan memungkinkan perangkat tidur sendiri.

Anda juga dapat melihat penggunaan PowerManager untuk menyetel perangkat ke mode tidur: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)

Zambotron
sumber
1
Terima kasih atas tanggapannya. Ya saya yakin. Ada di manifes saya dan tidak ada kesalahan debug. AlarmManager tidak akan membantu saya saat saya menggunakan sensor untuk menghidupkan layar. Saya belum terlalu beruntung dengan goToSleep, tapi ya itu masih tidak membantu saya dalam menyalakan layar. Saat ini saya dapat membuat layar mati
thegreyspot
5

Cara terbaik untuk melakukannya (menggunakan perangkat yang di-rooting):

@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

   .
   .
   .
}

Sekarang kami memiliki dua fungsi ini:

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){
  }
}

Dan ini:

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

Maaf atas bahasa Inggris saya yang buruk.

Rodrigo Gontijo
sumber
Halo, Rodrigo Gontijo Mengapa kita perlu root perangkat pl. katakan padaku?
Kinjal
@Kinjal karena Anda perlu menjalankan fungsi ("goToSleep") dan fungsi ini memerlukan izin khusus, hanya diberikan ke aplikasi sistem: <using-permission android: name = "android.Riztion.DEVICE_POWER" />
Rodrigo Gontijo
ok terima kasih dan berikan tautan atau langkah cara root perangkat jika memungkinkan. Terima kasih sebelumnya.
Kinjal
4

Berikut adalah contoh sukses dari implementasi hal yang sama, pada perangkat yang mendukung nilai kecerahan layar yang lebih rendah (saya uji pada tablet Allwinner China 7 "yang menjalankan 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);

Jika orang lain mencoba ini, tolong beri komentar di bawah jika berfungsi / tidak berfungsi dan perangkatnya, Android API.

ılǝ
sumber
2
Di perangkat saya, nexus 7, ini tidak berfungsi dengan baik, layar masih menyala, sedikit lebih gelap, tetapi tidak sepenuhnya hitam.
JackWM
Maka dari itu, implementasi ini tidak boleh digunakan untuk rilis publik, meskipun mungkin melayani integrasi dengan perangkat tertentu. Saya akan menyimpan posting karena mungkin membantu seseorang untuk nanti.
ılǝ
3

Untuk menjaga layar tetap menyala:

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

Kembali ke mode default layar: hapus saja bendera FLAG_KEEP_SCREEN_ON

getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Marco Aurelio Silva
sumber
3

Ini bekerja di 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();
    }
}
mbsysd.dll
sumber
Akan lebih bagus jika Anda menjelaskan mengapa jawaban Anda berfungsi yang akan membantu anggota SO untuk lebih memahami.
dkb
mematikan layar tidak bekerja dengan baik ... ketika sensor jarak bergerak dari dekat ke jauh, layar kembali menyala ... dan jika saya melepaskan kunci pengaktifan sebelum itu, itu masih langsung menyala !
Michael
2

Mengenai dokumentasi Android, hal itu dapat dicapai dengan menggunakan baris kode berikut:

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

Saya telah menambahkan ini dalam onCreatemetode saya dan berfungsi dengan baik.

Di tautan tersebut Anda akan menemukan berbagai cara untuk mencapai ini dan penjelasan umum juga.

Tautan ke dokumentasi: https://developer.android.com/training/scheduling/wakelock.html

maytham-ɯɐɥʇʎɐɯ
sumber
2

Jika aplikasi Anda adalah aplikasi sistem, Anda bisa menggunakan PowerManager.goToSleep () untuk mematikan layar, Anda memerlukan izin khusus

sebelum Anda menggunakan goToSleep (), Anda perlu menggunakan refleksi seperti:

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

Sekarang, Anda dapat menggunakan goToSleep () untuk mematikan layar.

Inilah yang terjadi ketika tombol daya ditekan untuk mematikan layar.

Rickon Gao
sumber
2

Cukup tambahkan

android:keepScreenOn="true" 

atau telepon

setKeepScreenOn(true) 

pada pandangan orang tua.

mani
sumber
1

Saya tidak memiliki harapan untuk "membangunkan layar" dalam aktivitas tersebut. Jika layar mati, aktivitas mungkin dalam keadaan jeda dan seharusnya tidak menjalankan kode apa pun.

Saat bangun, ada masalah pada layar kunci. Saya tidak tahu bagaimana aplikasi apa pun dapat secara otomatis melewati layar kunci.

Anda harus mempertimbangkan untuk menjalankan tugas latar belakang Anda dalam suatu layanan, dan kemudian menggunakan pengelola pemberitahuan untuk mengirim pemberitahuan ketika ada yang terdeteksi. Pemberitahuan harus memberikan semacam peringatan perangkat (layar bangun, ikon pemberitahuan, dipimpin pemberitahuan, dll). Saat mengklik notifikasi itu bisa meluncurkan maksud untuk memulai aktivitas Anda.

Anda juga dapat mencoba untuk memulai aktivitas langsung dari layanan, tetapi saya benar-benar tidak tahu apakah itu akan mengaktifkan layar atau melewati layar kunci.

HaMMeReD
sumber
Terima kasih atas tanggapannya, saya memasukkan beberapa kode getar, dan ketika layar saya mati, dan saya mengaktifkan salah satu sensor saya, itu bergetar. Jadi kodenya pasti sedang berjalan. Lockscreen bukan masalah besar, saya hanya menggunakan pengaman tombol.
thegreyspot
Meskipun kodenya berjalan, kode itu berada di luar siklus proses. Anda tidak dapat mempercayai aktivitas di luar layar. Pikirkan pengunduh game, sebagian besar ditulis dalam aktivitas dan Anda dapat meninggalkannya selama mungkin 30 detik hingga beberapa menit dan mereka akan tetap mengunduh, tetapi biasanya rusak karena OS membunuh aktivitas berdasarkan pola penggunaan Anda.
HaMMeReD
1

Sesuai Android API 28 dan yang lebih baru, Anda perlu melakukan hal berikut untuk menyalakan layar

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