Android: Làm cách nào để bật và tắt màn hình theo chương trình?


98

Trước khi đánh dấu bài đăng này là "trùng lặp", tôi viết bài này vì không có bài nào khác nắm giữ giải pháp cho vấn đề.

Tôi đang cố gắng tắt thiết bị, sau một vài phút hoặc cảm biến thay đổi, hãy bật lại.

Tắt kiểm tra hiển thị

Tôi có thể tắt màn hình bằng cách sử dụng:

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

Tôi không thể tắt màn hình bằng phương thức wl.release ().

Bật kiểm tra màn hình

Dự đoán đầu tiên của tôi, như sau, không hoạt động. Không có gì xảy ra, màn hình vẫn tắt.

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

Sau đó, tôi cũng đã thử sử dụng wakelocks, nhưng không thành công.

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

Cuối cùng tôi đã thử những điều sau đây, không có kết quả.

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

Nói chung, tôi không gặp bất kỳ loại lỗi nào trong bảng điều khiển cho bất kỳ phương pháp nào trong số này. Văn bản kiểm tra của tôi "Màn hình phải bật", hiển thị trên màn hình khi tôi bật thiết bị bằng nút nguồn. Điều này cho thấy mã lẽ ra đã chạy. Vui lòng chỉ trả lời nếu bạn đã kiểm tra mã, có vẻ như nhiều chức năng chẳng hạn như params.screenBrightness = -1, không hoạt động như chúng nên theo sdk.


1
Phương pháp tắt màn hình của bạn không hiệu quả với tôi. Bạn đặt cờ để màn hình luôn sáng, điều này sẽ làm tiêu hao năng lượng.
Kristy Welsh

Bạn đã bao giờ con số này ra? Có một vài ứng dụng trên PlayStore đề xuất họ làm điều đó. Đã thử cái này và nó hoạt động nhưng nó yêu cầu Quản trị thiết bị. play.google.com/store/apps/…
George

bạn đã đạt được điều gì đó trong vấn đề này? !!
Muhammed Refaat

Câu trả lời:


69

Tôi sẽ giả định rằng bạn chỉ muốn điều này có hiệu lực trong khi ứng dụng của bạn ở phía trước.

Mã này:

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

Không tắt màn hình theo nghĩa truyền thống. Nó làm cho màn hình mờ nhất có thể. Trong nền tảng tiêu chuẩn, có giới hạn về độ mờ của nó; nếu thiết bị của bạn thực sự cho phép màn hình tắt hoàn toàn, thì đó là một số đặc thù của việc triển khai thiết bị đó và không phải là hành vi bạn có thể tin tưởng trên các thiết bị.

Trên thực tế, việc sử dụng điều này kết hợp với FLAG_KEEP_SCREEN_ON có nghĩa là bạn sẽ không bao giờ cho phép màn hình tắt (và do đó thiết bị chuyển sang chế độ năng lượng thấp) ngay cả khi thiết bị cụ thể đang cho phép bạn đặt độ sáng màn hình thành tắt hoàn toàn. Hãy ghi nhớ điều này một cách mạnh mẽ. Bạn sẽ sử dụng nhiều năng lượng hơn so với khi màn hình thực sự tắt.

Bây giờ để chuyển màn hình trở lại độ sáng bình thường, bạn chỉ cần đặt giá trị độ sáng là xong:

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

Tôi không thể giải thích tại sao điều này sẽ không thay thế giá trị 0 mà bạn đã đặt trước đó. Để thử nghiệm, bạn có thể thử đặt độ sáng đầy đủ bắt buộc vào đó để buộc đến độ sáng cụ thể đó:

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

Điều này chắc chắn hoạt động. Ví dụ: ứng dụng Sách của Google sử dụng điều này để cho phép bạn đặt độ sáng màn hình thành mờ trong khi sử dụng sách và sau đó trở lại độ sáng bình thường khi tắt chế độ đó.

Để giúp gỡ lỗi, bạn có thể sử dụng "adb shell dumpsys window" để xem trạng thái hiện tại của cửa sổ. Trong dữ liệu cho cửa sổ của bạn, nó sẽ cho bạn biết LayoutParams hiện tại đã được thiết lập cho nó. Đảm bảo giá trị bạn nghĩ là thực sự ở đó.

Và một lần nữa, FLAG_KEEP_SCREEN_ON là một khái niệm riêng biệt; nó và độ sáng không có ảnh hưởng trực tiếp đến nhau. (Và sẽ không có lý do gì để đặt lại cờ khi hoàn tác độ sáng, nếu bạn đã đặt nó khi đặt độ sáng về 0. Cờ sẽ vẫn được đặt cho đến khi bạn thay đổi nó.)


8
Có cách nào tốt hơn để tắt màn hình không?
akash

Như @hackbod đã nêu ở trên, "params.screenBrightness = 0;" không tắt hoàn toàn màn hình; thay vào đó, nó làm cho màn hình mờ nhất có thể. Và "params.screenBrightness = -1;" chuyển màn hình trở lại mức sáng trước đó. Tuy nhiên, có những trường hợp chúng ta cần tắt màn hình hoàn toàn. Có thể có các phương pháp khác ...
jonathanzh

6
Những phương pháp khác sẽ thực sự tắt màn hình thay vì chỉ đặt độ sáng tối thiểu có thể hoạt động hoặc không hoạt động?
Michael

37

Tôi đã viết phương pháp này để bật màn hình sau khi khóa màn hình. Nó hoạt động hoàn hảo cho tôi. Thử nó-

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

Và gọi phương thức này từ onResume().


1
Không hữu ích nếu bạn định bật màn hình khi muốn chấm dứt hoạt động.
AndroidDev

7
Vâng, mọi người, tôi sẽ đề nghị không sử dụng phương pháp của tôi vì điều này không hiệu quả với tôi trên Micromax Canvas2 +. Sử dụng liên kết này để thay thế.
Rajkiran

28

Tôi sẽ đề nghị cái này:

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

Cờ ACQUIRE_CAUSES_WAKEUP được giải thích như vậy:

Các khóa chế độ thức thông thường không thực sự bật đèn. Thay vào đó, chúng làm cho đèn vẫn sáng sau khi bật (ví dụ: từ hoạt động của người dùng). Cờ này sẽ buộc màn hình và / hoặc bàn phím bật ngay lập tức khi có được WakeLock. Một cách sử dụng thông thường sẽ dành cho các thông báo quan trọng để người dùng có thể nhìn thấy ngay lập tức.

Ngoài ra, hãy đảm bảo rằng bạn có quyền sau trong tệp AndroidManifewst.xml:

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

3
Rất tiếc, cờ SCREEN_BRIGHT_WAKE_LOCK không được dùng nữa.
Camille Sévigny

20

Xin chào, tôi hy vọng điều này sẽ giúp:

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

Làm thế nào để tắt màn hình mà không liên quan đến cảm biến khoảng cách?
Michael

Hi @ Michael, bạn chỉ cần sử dụng public void turnOffScreen () chức năng chỉ
mangu23

3
Có, nhưng có vẻ như chức năng này sử dụng PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCKchỉ tắt màn hình khi cảm biến tiệm cận ở trạng thái "gần".
Michael

Ahh được rồi, tôi hiểu rồi, bạn có thể sử dụng cái này thay thế PowerManager.SCREEN_DIM_WAKE_LOCK
mangu23

1
Sự cố - ngay sau khi tôi thả khóa PROXIMITY_SCREEN_OFF_WAKE_LOCKchờ, màn hình sẽ bật trở lại. Làm cách nào để ngăn chặn điều này?
Michael

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

  //later
  screenLock.release();

// Tệp kê khai người dùng


2
Đây phải là câu trả lời chính xác. Tôi đang sử dụng Android 5 và đây là thứ duy nhất thực sự hoạt động. Chỉ có chú thích bên là SCREEN_BRIGHT_WAKE_LOCK không được dùng nữa và tôi không thấy bản thay thế. Bất kỳ ai?
HammerNL

Không có vấn đề gì, câu trả lời của bạn là hoàn toàn có thể sử dụng được. Như tôi đã nói: "đó là câu trả lời duy nhất mà thực sự hoạt động"
HammerNL

@HammerNL sự khác biệt giữa câu trả lời này và câu trả lời do ramdroid cung cấp là gì?
Lỗi xảy ra

@BugsHappen Ramdroids một cái là phức tạp hơn :) Nhưng vâng, nó giống nhau. Không biết tại sao Pir Fahim Shah đăng câu trả lời này, hoặc tại sao tôi không thấy Ramdroids một lần vào thời điểm đó.
HammerNL

6

Bạn có chắc là mình đã yêu cầu quyền thích hợp trong tệp kê khai của mình không?

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

Bạn có thể sử dụng lớp AlarmManager 1 để kích hoạt một ý định bắt đầu hoạt động của bạn và có được khóa đánh thức. Thao tác này sẽ bật màn hình và tiếp tục bật. Việc giải phóng wakelock sẽ cho phép thiết bị tự chuyển sang chế độ ngủ.

Bạn cũng có thể xem cách sử dụng PowerManager để đặt thiết bị ở chế độ ngủ: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)


1
Cảm ơn vì sự trả lời. Vâng tôi chắc chắn. Nó trong tệp kê khai của tôi và không có lỗi gỡ lỗi. AlarmManager sẽ không giúp tôi khi tôi sử dụng cảm biến để bật màn hình. Tôi không gặp nhiều may mắn với goToSleep, nhưng điều đó vẫn không giúp tôi bật màn hình. Tôi hiện đang có khả năng để làm cho màn hình đi tắt
thegreyspot

5

Cách tốt nhất để làm điều đó (sử dụng thiết bị đã root):

@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

   .
   .
   .
}

Bây giờ chúng ta có hai chức năng này:

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

Và điều này:

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

Xin lỗi vì tiếng Anh của tôi không tốt.


Xin chào, Rodrigo Gontijo Tại sao chúng ta cần root thiết bị. nói với tôi?
Kinjal,

@Kinjal vì bạn cần gọi hàm ("goToSleep") và hàm này yêu cầu quyền đặc biệt, chỉ được cấp cho các ứng dụng hệ thống: <use-allow android: name = "android.permission.DEVICE_POWER" />
Rodrigo Gontijo

ok, cảm ơn và vui lòng cung cấp liên kết hoặc bước làm thế nào để root thiết bị nếu có thể. Cảm ơn trước.
Kinjal

4

Đây là một ví dụ thành công về việc triển khai điều tương tự, trên một thiết bị hỗ trợ giá trị độ sáng màn hình thấp hơn (tôi đã thử nghiệm trên máy tính bảng Allwinner Trung Quốc 7 "chạy 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);

Nếu ai đó thử điều này, vui lòng bình luận bên dưới nếu nó hoạt động / không hoạt động và thiết bị, Android API.


2
Trên thiết bị của tôi, nexus 7, điều này không hoạt động tốt, màn hình vẫn sáng, chỉ tối hơn một chút, nhưng không hoàn toàn đen.
JackWM

Chắc chắn rằng triển khai này không nên được sử dụng cho bản phát hành công khai, mặc dù nó có thể phục vụ tích hợp với thiết bị cụ thể. Tôi sẽ giữ bài viết vì nó có thể giúp ích cho ai đó sau này.
ılǝ

3

Để tiếp tục bật màn hình:

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

Quay lại chế độ mặc định của màn hình: chỉ cần xóa cờ FLAG_KEEP_SCREEN_ON

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

3

Điều này đã hoạt động trên 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();
    }
}

Sẽ thật tuyệt nếu bạn giải thích được lý do tại sao câu trả lời của bạn lại hiệu quả, điều này sẽ giúp thành viên SO hiểu rõ hơn.
dkb

tắt màn hình không hoạt động tốt ... khi cảm biến khoảng cách đi từ gần đến xa, màn hình bật trở lại ... và nếu tôi mở khóa đánh thức trước đó, nó vẫn bật ngay lập tức !
Michael

2

Đối với tài liệu Android, nó có thể đạt được bằng cách sử dụng dòng mã sau:

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

Tôi đã thêm điều này vào onCreatephương pháp của mình và nó hoạt động tốt.

Trên liên kết, bạn sẽ tìm thấy những cách khác nhau để đạt được điều này và giải thích chung.

Liên kết đến tài liệu: https://developer.android.com/training/scheduling/wakelock.html


2

Nếu ứng dụng của bạn là ứng dụng hệ thống, bạn có thể sử dụng PowerManager.goToSleep () để tắt màn hình, bạn cần có quyền đặc biệt

trước khi sử dụng goToSleep (), bạn cần sử dụng phản chiếu giống như:

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

Bây giờ, bạn có thể sử dụng goToSleep () để tắt màn hình.

Đây là những gì sẽ xảy ra khi nhấn phím nguồn để tắt màn hình.


2

Chỉ cần thêm

android:keepScreenOn="true" 

hoặc gọi

setKeepScreenOn(true) 

trên chế độ xem của phụ huynh.


1

Tôi sẽ không hy vọng "đánh thức màn hình" trong hoạt động. Nếu màn hình tắt, hoạt động có thể đang ở trạng thái tạm dừng và không nên chạy bất kỳ mã nào.

Khi thức dậy, màn hình khóa có vấn đề. Tôi không biết làm thế nào mà bất kỳ ứng dụng nào có thể tự động vượt qua màn hình khóa.

Bạn nên cân nhắc việc chạy các tác vụ nền của mình trong một dịch vụ, sau đó sử dụng trình quản lý thông báo để gửi thông báo khi phát hiện bất kỳ điều gì. Thông báo phải cung cấp một số loại cảnh báo thiết bị (đánh thức màn hình, biểu tượng thông báo, đèn led thông báo, v.v.). Khi nhấp vào thông báo, nó có thể khởi chạy ý định để bắt đầu hoạt động của bạn.

Bạn cũng có thể cố gắng bắt đầu hoạt động trực tiếp từ dịch vụ, nhưng tôi thực sự không biết liệu điều đó sẽ bật màn hình hay bỏ qua màn hình khóa.


Cảm ơn bạn đã phản hồi, tôi đã nhập một số mã rung và khi tôi tắt màn hình và kích hoạt một trong các cảm biến của mình, nó sẽ rung. Vì vậy, mã chắc chắn đang chạy. Màn hình khóa không phải là một vấn đề lớn, tôi chỉ sử dụng bảo vệ chìa khóa.
thegreyspot

Ngay cả khi mã chạy, nó nằm ngoài vòng đời. Bạn không thể tin tưởng các hoạt động ngoài màn hình. Hãy nghĩ rằng những người tải xuống trò chơi, hầu hết được viết trong hoạt động và bạn có thể rời khỏi có thể từ 30 giây đến vài phút và họ sẽ vẫn tải xuống, nhưng chúng thường bị hỏng vì hệ điều hành giết hoạt động dựa trên cách sử dụng của bạn.
HaMMeReD 14/03/12

1

Theo Android API 28 trở lên, bạn cần làm như sau để bật màn hình

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.