繁体   English   中英

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

[英]Android: How to turn screen on and off programmatically?

在将这篇文章标记为“重复”之前,我写这篇文章是因为没有其他文章可以解决问题。

我正在尝试关闭设备,然后在几分钟或传感器更换后重新打开它。

关闭显示测试

我可以使用以下方法关闭屏幕:

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

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

开启显示测试

我的第一个猜测如下,不起作用。 没有任何反应,屏幕保持关闭状态。

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

总而言之,对于这些方法中的任何一种,我都没有在控制台中收到任何类型的错误。 当我使用电源按钮打开设备时,我的测试文本“屏幕应该打开”在屏幕上。 这表明代码应该已经运行了。 请仅在您测试过代码的情况下回答,似乎许多功能(例如params.screenBrightness = -1 )无法根据 sdk 正常工作。

我将假设您只希望在您的应用程序处于前台时这才生效。

这段代码:

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

不会关闭传统意义上的屏幕。 它使屏幕尽可能暗淡。 在标准平台中,它的昏暗程度是有限的; 如果您的设备实际上允许屏幕完全关闭,那么这是该设备实现的一些特殊性,而不是您可以跨设备信赖的行为。

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

现在要将屏幕恢复到常规亮度,只需设置亮度值即可:

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 window”来查看窗口的当前状态。 在窗口的数据中,它会告诉您已为其设置的当前 LayoutParams。 确保您认为的价值确实存在。

同样,FLAG_KEEP_SCREEN_ON 是一个单独的概念; 它和亮度没有直接的影响。 (如果您在将亮度设置为 0 时已经设置了它,则在撤消亮度时没有理由再次设置该标志。该标志将保持设置状态,直到您更改它为止。)

我写了这个方法来在屏幕锁定后打开屏幕。 它非常适合我。 尝试一下-

    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()调用此方法。

我会推荐这个:

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();
}
     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

//用户清单文件

您确定您在 Manifest 文件中请求了适当的权限吗?

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

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

您还可以查看使用 PowerManager 将设备设置为睡眠状态: http : //developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)

最好的方法(使用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

   .
   .
   .
}

现在我们有这两个函数:

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

对不起,我的英语不好。

这是在支持较低屏幕亮度值的设备上实现相同功能的成功示例(我在运行 API15 的全志中文 7 英寸平板电脑上进行了测试)。

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。

要保持屏幕开启:

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

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

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

这是在棉花糖上工作的

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

只需添加

android:keepScreenOn="true" 

或打电话

setKeepScreenOn(true) 

在父视图中。

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

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

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

在链接上,您将找到实现此目的的不同方法以及一般说明。

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

如果您的应用程序是系统应用程序,您可以使用 PowerManager.goToSleep() 关闭屏幕,您需要特殊权限

在使用 goToSleep() 之前,您需要使用反射,就像:

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

现在,您可以使用 goToSleep() 关闭屏幕。

这就是按下电源键关闭屏幕时发生的情况。

根据 Android API 28 及更高版本,您需要执行以下操作才能打开屏幕

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

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

醒来时,有锁屏的问题。 我不知道任何应用程序如何自动绕过锁屏。

您应该考虑在服务中运行后台任务,然后在检测到任何内容时使用通知管理器发送通知。 通知应提供某种设备警报(屏幕唤醒、通知图标、通知 LED 等)。 单击通知时,它可以启动意图以开始您的活动。

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

我已经尝试了上述所有解决方案,但没有一个对我有用。 所以我用谷歌搜索并找到了以下解决方案。 我试过了,它奏效了。

https://www.tutorialspoint.com/how-to-turn-android-device-screen-on-and-off-programmatically

如果有任何建议,请给出

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM