Android:如何以编程方式打开和closures屏幕?

在将这篇文章标为“重复”之前,我正在撰写这篇文章,因为没有其他文章能够解决这个问题。

我试图closures设备,然后几分钟后或更换传感器,将其重新打开。

closures显示testing

我能够closures屏幕使用:

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

我一直无法使用wl.release()方法closures屏幕。

打开显示testing

我的第一个猜测,如下所示,不起作用。 没有任何反应,屏幕仍然closures。

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

然后,我也尝试使用唤醒锁,没有成功。

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

最后我试了下面,没有结果。

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

总而言之,在这些方法的控制台中我没有遇到任何错误。 当我使用电源button开启设备时,我的testing文本“屏幕应该打开”,在屏幕上。 这表明代码应该已经跑了。 请只回答,如果你已经testing了代码,似乎很多函数,如params.screenBrightness = -1 ,不工作,因为他们应该根据SDK。

我将假设你只是希望在你的应用程序处于前台的时候才能生效。

此代码:

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

不要在传统意义上closures屏幕。 它使屏幕尽可能地变暗。 在标准平台上,它可能会有多么暗淡的限制; 如果您的设备实际上允许屏幕完全closures,那么这个设备的实现有一些特殊之处,而不是您可以在各个设备上指望的行为。

实际上,将这与FLAG_KEEP_SCREEN_ON结合使用意味着,即使特定设备允许您将屏幕亮度设置为全关,也不会允许屏幕熄灭(因此设备将进入低功耗模式)。 牢记这一点。 如果屏幕真的closures,你将会使用更多的电源。

现在将屏幕恢复到正常的亮度,只需设置亮度值就可以了:

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

我不能解释为什么这不会取代你以前设置的0值。 作为一个testing,你可以尝试把强制的全亮度强制到那个特定的亮度:

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

这绝对有效。 例如,Google的图书应用程序使用它来允许您在使用图书时将屏幕亮度设置为暗淡,然后在closures时恢复正常的亮度。

为了帮助debugging,您可以使用“adb shell dumpsys窗口”来查看窗口的当前状态。 在窗口的数据中,它会告诉你已经设置的当前LayoutParams。 确保你认为的价值实际在那里。

而且,FLAG_KEEP_SCREEN_ON是一个单独的概念; 它和亮度对彼此没有直接的影响。 (如果你已经在亮度设置为0的时候设置了亮度,那么在撤消亮度的时候没有任何理由再次设置这个标志。这个标志会一直保持设置,直到你改变它为止。)

我已经写了这个方法来在屏幕locking之后打开屏幕。 这对我来说是完美的。 尝试一下-

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

并从onResume()调用此方法。

我会build议这一个:

 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" /> 

嗨,我希望这将有助于:

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

你确定你在你的Manifest文件中请求了正确的权限吗?

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

您可以使用AlarmManager 1类来触发启动您的活动的意图并获取唤醒锁。 这将打开屏幕并保持打开状态。 释放唤醒锁将允许设备自己进入睡眠状态。

你也可以看看使用PowerManager来设置设备进入睡眠状态: http : //developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)

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

//用户清单文件

在一个支持较低屏幕亮度值的设备(我在一个运行API15的Allwinner中文7“平板电脑上testing)上实现同样的事情,这是一个成功的例子。

 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。

最好的方法来做到这一点(使用植根设备):

 @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 . . . } 

现在我们有这两个function:

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

对不起,我的英语不好。

我不会希望在活动中“醒来的屏幕”。 如果屏幕closures,则活动可能处于暂停状态,不应该运行任何代码。

起床时,有锁屏问题。 我不知道任何应用程序可以自动绕过锁屏。

您应该考虑在服务中运行后台任务,然后使用通知pipe理器在发现任何事件时发送通知。 通知应该提供某种设备警报(屏幕唤醒,通知图标,通知指示等)。 点击通知时,可以启动开始活动的意图。

你也可以尝试从服务直接启动活动,但我真的不知道这是否会打开屏幕或绕过锁屏。

关于Android文档,可以使用下面的代码行来实现:

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

我已经在我的onCreate方法中添加了这个,它工作正常。

在链接上,你会发现不同的方式来实现这个和一般的解释。

链接到文档: https : //developer.android.com/training/scheduling/wakelock.html

为了保持屏幕:

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

回到屏幕默认模式:只需清除标志FLAG_KEEP_SCREEN_ON

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

有些情况下,屏幕需要完全closures。 如果省电function对您的应用程序不是什么大问题,那么可以在以下情况下使用PowerManager类:

  • 使用PowerManager.goToSleep()closures屏幕显示。
  • 使用PowerManager.wakeUp()打开屏幕显示。
  • 使用PowerManager.isScreenOn()获取屏幕显示的开/关状态。 或者,为此,使用PowerManager.isInteractive()或Display.getState()。

以下代码示例显示如何实现此解决scheme:

  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)的embedded式设备上进行了testing。

请注意,某些API方法可能在Android API文档中找不到,您需要指定适当的权限,例如DEVICE_POWER。