Android: Ekran programlı olarak nasıl açılır ve kapatılır?


98

Bu gönderiyi "kopya" olarak işaretlemeden önce, bu gönderiyi yazıyorum çünkü başka hiçbir gönderi sorunun çözümünü tutmuyor.

Cihazı kapatmaya çalışıyorum, ardından birkaç dakika sonra veya sensör değişikliğinden sonra tekrar açıyorum.

Ekran Testlerini Kapat

Şunları kullanarak ekranı kapatabiliyorum:

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

Wl.release () yöntemini kullanarak ekranı kapatamadım.

Ekran Testini Aç

Aşağıdaki gibi ilk tahminim işe yaramıyor. Hiçbir şey olmuyor, ekran kapalı kalıyor.

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

Ayrıca daha sonra başarılı olamadan wakelocks kullanmayı denedim.

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

Sonunda hiçbir sonuç almadan aşağıdakileri denedim.

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

Sonuç olarak, bu yöntemlerden herhangi biri için konsolda herhangi bir hata almıyorum. Güç düğmesini kullanarak cihazı açtığımda test metnim "Ekran açık olmalı" ekranda görünüyor. Bu, kodun çalışması gerektiğini gösterir. Lütfen sadece kodu test ettiyseniz cevaplayın params.screenBrightness = -1, sdk'ye göre olması gerektiği gibi çalışmıyor gibi birçok işlev gibi görünüyor .


1
Ekranı kapatma yönteminiz benim için işe yaramadı. Bayrağı, ekranı her zaman açık tutacak şekilde ayarlarsınız, bu da gücü tüketir.
Kristy Welsh

Bunu hiç çözdün mü? PlayStore'da bunu yapmayı öneren birkaç uygulama var. Bunu denedim ve işe yarıyor, ancak Cihaz Yönetimi istiyor. play.google.com/store/apps/…
George

bu problemde bir şeye ulaştın mı? !!
Muhammed Refaat

Yanıtlar:


69

Bunun yalnızca başvurunuz ön plandayken geçerli olmasını istediğinizi varsayacağım.

Bu kod:

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

Geleneksel anlamda ekranı kapatmaz. Ekranı olabildiğince karartır. Standart platformda ne kadar loş olabileceğine dair bir sınır vardır; Cihazınız gerçekten ekranın tamamen kapanmasına izin veriyorsa, bu, o cihazın uygulanmasının bazı özelliğidir ve cihazlar arasında güvenebileceğiniz bir davranış değildir.

Aslında bunu FLAG_KEEP_SCREEN_ON ile birlikte kullanmak, belirli cihaz ekran parlaklığını tam kapalı olarak ayarlamanıza izin verse bile ekranın kapanmasına (ve dolayısıyla cihazın düşük güç moduna geçmesine) asla izin vermeyeceğiniz anlamına gelir. Bunu çok güçlü bir şekilde aklınızda bulundurun. Ekran gerçekten kapalıysa yapacağınızdan çok daha fazla güç kullanıyor olacaksınız.

Şimdi ekranı normal parlaklığa döndürmek için, sadece parlaklık değerini ayarlamak bunu yapmalıdır:

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

Bunun neden önceden ayarladığınız 0 değerinin yerini almayacağını açıklayamam. Test olarak, belirli bir parlaklığa zorlamak için oraya zorunlu bir tam parlaklık koymayı deneyebilirsiniz:

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

Bu kesinlikle işe yarıyor. Örneğin, Google'ın Kitaplar uygulamaları, bir kitap kullanırken ekran parlaklığını kısmaya ayarlamanıza ve ardından bunu kapatırken normal parlaklığa dönmenize olanak sağlamak için bunu kullanır.

Hata ayıklamaya yardımcı olmak için, pencerenizin o anki durumunu görmek için "adb shell dumpsys window" kullanabilirsiniz. Pencerenizin verilerinde, size bunun için ayarlanmış mevcut LayoutParams'ı söyleyecektir. Gerçekte orada olduğunu düşündüğünüz değerin olmasını sağlayın.

Ve yine, FLAG_KEEP_SCREEN_ON ayrı bir kavramdır; ve parlaklığın birbirleri üzerinde doğrudan bir etkisi yoktur. (Parlaklığı 0'a koyarken zaten ayarlamış olsaydınız, parlaklığı geri alırken bayrağı tekrar ayarlamak için hiçbir neden olmazdı. Bayrak siz değiştirene kadar ayarlanmış olarak kalacaktır.)


8
Ekranı kapatmanın daha iyi bir yolu var mı?
akash

@Hackbod'un yukarıda belirttiği gibi, "params.screenBrightness = 0;" ekranı tamamen kapatmaz; bunun yerine ekranı olabildiğince karartır. Ve "params.screenBrightness = -1;" ekranı önceki parlaklık seviyesine döndürür. Ancak ekranı tamamen kapatmamız gereken durumlar da var. Başka yöntemler olabilir ...
jonathanzh

6
Çalışabilecek veya çalışmayabilecek minimum parlaklığı ayarlamak yerine ekranı gerçekten kapatan diğer yöntemler nelerdir?
Michael

37

Ekran kilidinden sonra ekranı açmak için bu yöntemi yazmıştım. Benim için mükemmel çalışıyor. Dene-

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

Ve bu yöntemi den çağırın onResume().


1
Aktiviteyi sonlandırmak istediğinizde ekranı açmayı planlıyorsanız kullanışlı değildir.
AndroidDev

7
Pekala millet, Micromax Canvas2 + 'da benim için işe yaramadığı için yöntemimi kullanmamayı önereceğim. Kullan bu bağlantıyı yerine.
Rajkiran

28

Bunu öneririm:

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

ACQUIRE_CAUSES_WAKEUP bayrağı şu şekilde açıklanır:

Normal uyandırma kilitleri aslında aydınlatmayı açmaz. Bunun yerine, aydınlatmanın açıldıktan sonra açık kalmasına neden olurlar (örneğin, kullanıcı aktivitesinden). Bu bayrak, WakeLock alındığında ekranı ve / veya klavyeyi hemen açmaya zorlar. Tipik bir kullanım, kullanıcının hemen görmesi için önemli olan bildirimler içindir.

Ayrıca, AndroidManifewst.xml dosyasında aşağıdaki izne sahip olduğunuzdan emin olun:

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

3
Maalesef SCREEN_BRIGHT_WAKE_LOCK bayrağı kullanımdan kaldırıldı.
Camille Sévigny

21

Merhaba umarım bu yardımcı olur:

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

Yakınlık sensörünü dahil etmeden ekran nasıl kapatılır?
Michael

Merhaba @Michael, sadece genel void turnOffScreen () işlevini kullanıyorsun
mangu23

3
Evet, ancak bu işlevin PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCKyalnızca yakınlık sensörü "yakın" durumdayken ekranı kapatan kullandığı görülüyor .
Michael

Ahh tamam anladım, bunun yerine bunu kullanabilirsin PowerManager.SCREEN_DIM_WAKE_LOCK
mangu23

1
Sorun - PROXIMITY_SCREEN_OFF_WAKE_LOCKbekleme kilidini bırakır bırakmaz ekran yeniden açılıyor. Bunu nasıl önleyebilirim?
Michael

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

  //later
  screenLock.release();

// Kullanıcı Manifest dosyası


2
Bu doğru cevap olmalı. Android 5 kullanıyorum ve bu gerçekten çalışan tek şey. Tek yan not, SCREEN_BRIGHT_WAKE_LOCK'un kullanımdan kaldırıldığı ve bir drop-in değiştirme görmüyorum. Kimse?
HammerNL

Sorun yok, cevabınız mükemmel şekilde kullanılabilir. Dediğim gibi: "gerçekten işe
yarayan

@HammerNL Bu cevap ile ramdroid tarafından sağlanan cevap arasındaki fark nedir?
Hatalar

@BugsHappen Ramdroids biri daha ayrıntılı :) Ama evet, aynı. Pir Fahim Shah'ın bu cevabı neden gönderdiğini veya neden o sırada Ramdroid'leri görmediğimi bilmiyorum.
HammerNL

6

Manifest dosyanızda uygun izni istediğinizden emin misiniz?

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

Aktivitenizi başlatan ve uyandırma kilidini alan bir amacı ateşlemek için AlarmManager 1 sınıfını kullanabilirsiniz. Bu, ekranı açacak ve açık tutacaktır. Uyandırma kilidinin serbest bırakılması, cihazın kendi kendine uyku moduna geçmesine izin verecektir.

Cihazı uyku moduna ayarlamak için PowerManager'ı kullanmaya da göz atabilirsiniz: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)


1
Cevabınız için teşekkürler. Evet eminim. Benim bildirimimde ve hata ayıklama hatası yok. Ekranı açmak için sensörleri kullandığımda AlarmManager bana yardımcı olmuyor. GoToSleep konusunda pek şansım olmadı ama bu hala ekranı açmama yardımcı olmuyor. Şu anda ekranı kapatabiliyorum
thegreyspot

5

Bunu yapmanın en iyi yolu (köklü cihazları kullanarak):

@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

   .
   .
   .
}

Şimdi bu iki işleve sahibiz:

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

Ve bu:

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

Kötü ingilizcem için özür dilerim.


Merhaba Rodrigo Gontijo Neden pl kök cihazına ihtiyacımız var. bana söyle?
Kinjal

@Kinjal, çünkü işlevi ("goToSleep") çalıştırmanız gerekiyor ve bu işlev özel bir izin gerektiriyor, yalnızca sistem uygulamalarına verilir: <uses-allow android: name = "android.permission.DEVICE_POWER" />
Rodrigo Gontijo

tamam teşekkürler ve lütfen mümkünse cihazın nasıl kökleneceği ile ilgili bağlantı veya adım sağlayın. Şimdiden teşekkürler.
Kinjal

4

İşte aynı şeyin daha düşük ekran parlaklık değerlerini destekleyen bir cihazda uygulanmasının başarılı bir örneği (API15 çalıştıran bir Allwinner Chinese 7 "tabletinde test ettim).

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

Başka biri bunu denerse, işe yaradıysa / çalışmadıysa ve cihaz, Android API'sı lütfen aşağıya yorum yapın.


2
Cihazım nexus 7'de bu iyi çalışmıyor, ekran hala açık, biraz daha koyu, ancak tamamen siyah değil.
JackWM

Kesinlikle bu uygulama, belirli bir cihazla bir entegrasyona hizmet etse de, halka açık bir sürüm için kullanılmamalıdır. Daha sonra birine yardımcı olabileceği için gönderiyi saklayacağım.
ılǝ

3

Ekranı açık tutmak için:

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

Ekran varsayılan moduna geri dön: FLAG_KEEP_SCREEN_ON bayrağını kaldırmanız yeterli

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

3

Bu Marshmallow üzerinde çalışıyor

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

Cevabınızın neden işe yaradığını açıklarsanız, SO üyesinin daha iyi anlamasına yardımcı olursanız harika olur.
dkb

ekranı kapatmak o kadar iyi çalışmıyor ... yakınlık sensörü yakından uzağa gittiğinde ekran tekrar açılır ... ve ondan önce uyandırma kilidini açarsam, yine de hemen açılır !
Michael


2

Uygulamanız bir sistem uygulamasıysa, ekranı kapatmak için PowerManager.goToSleep () kullanabilirsiniz, özel bir izin gerekir

goToSleep () kullanmadan önce, aşağıdaki gibi yansıma kullanmanız gerekir:

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

Artık ekranı kapatmak için goToSleep () kullanabilirsiniz.

Ekranı kapatmak için güç tuşuna basıldığında olan şey budur.


2

Basitçe ekleyin

android:keepScreenOn="true" 

veya ara

setKeepScreenOn(true) 

ebeveyn görünümünde.


1

Etkinlikte "ekranı uyandırma" umudum olmazdı. Ekran kapalıysa, etkinlik muhtemelen duraklatılmış durumdadır ve herhangi bir kod çalıştırmaması gerekir.

Uyanırken kilit ekranı sorunu var. Herhangi bir uygulamanın kilit ekranını otomatik olarak nasıl atlayabileceğini bilmiyorum.

Arka plan görevlerinizi bir hizmette çalıştırmayı ve ardından algılandığında bildirim göndermek için bildirim yöneticisini kullanmayı düşünmelisiniz. Bildirim, bir tür cihaz uyarısı sağlamalıdır (ekran uyanma, bildirim simgesi, bildirim ışığı vb.). Bildirime tıkladığınızda, faaliyetinizi başlatma niyetini başlatabilir.

Ayrıca, etkinliği doğrudan hizmetten başlatmayı da deneyebilirsiniz, ancak bunun ekranı açıp açmayacağını veya kilit ekranını atlayacağını gerçekten bilmiyorum.


Yanıtınız için teşekkür ederim, biraz titreşim kodu ekledim ve ekranı kapattığımda ve sensörlerimden birini etkinleştirdiğimde titriyor. Yani kod kesinlikle çalışıyor. Kilit ekranı çok önemli değil, sadece tuş kilidi kullanıyorum.
thegreyspot

Kod çalışsa bile yaşam döngüsünün dışındadır. Ekranın dışındaki etkinliklere güvenemezsiniz. Oyun indiricileri düşünün, çoğu etkinlikte yazılmıştır ve belki 30 saniye ile birkaç dakika arasında bırakabilirsiniz ve yine de indirirler, ancak genellikle işletim sistemi kullanım düzeninize göre etkinliği öldürdüğü için bozulur.
HaMMeReD

1

Android API 28 ve üzeri uyarınca, ekranı açmak için aşağıdakileri yapmanız gerekir

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.