【问题标题】:how to check screen on/off status in onStop()?如何在 onStop() 中检查屏幕开/关状态?
【发布时间】:2013-10-13 21:03:17
【问题描述】:

here所说,当屏幕熄灭时,当前Activity的onStop()会被调用。当我的ActivityonStop() 被调用时,我需要检查屏幕的开/关状态。所以我为这些操作注册了一个BroadcastReceiverACTION_SCREEN_ONACTION_SCREEN_OFF)来记录当前的开/关状态(它们工作正常,我已经登录了!)。
但是当我关闭屏幕并检查 onStop 中的开/关状态时,它说屏幕已打开。为什么?我认为接收者必须在调用onStop 之前收到ACTION_SCREEN_OFF,这是怎么回事?

【问题讨论】:

  • "我认为接收器必须在调用 onStop 之前收到 ACTION_SCREEN_OFF,所以怎么了?" ——我不知道你为什么会这么认为。使用Log 语句或断点来查看首先调用哪个。更好的是,重新设计您的应用程序,以不在乎是否因为屏幕正在关闭而调用 onStop(),而不是任何其他原因。
  • @CommonsWare 应用程序必须能够区分onStop 被调用的不同情况,所以我必须知道关闭屏幕是否导致onStop 被调用或其他事情。有更好的解决方案吗?
  • “应用程序必须能够区分调用 onStop 的不同情况”——为什么?无论屏幕关闭、用户按下 HOME、用户按下 BACK、用户接听来电、用户点击通知或用户做了其他任何事情,这对您的应用程序有什么影响导致您的活动不再可见?屏幕关闭通常不是特殊情况。
  • 因为我正在开发一个解锁器应用程序,任何导致调用onStop 的事情都应该在我的应用程序中处理,所以我试图定义任何调用onStop 的情况,这样我就可以在按下主页按钮和其他按钮之间有所不同。无论如何!让我们回到我的第一个问题!你有什么想法吗?
  • 当我们打开或关闭屏幕时,您想在onStop 中做什么?也许有更简单或其他方式来完成工作。

标签: android android-activity android-broadcast


【解决方案1】:

您可以尝试使用 PowerManager 系统服务来实现此目的,这里是示例和official documentation(注意此方法是在 API 级别 7 中添加的):

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();

编辑:

isScreenOn() 方法已弃用 API 级别 21。您应该改用 isInteractive:

boolean isScreenOn = pm.isInteractive();

http://developer.android.com/reference/android/os/PowerManager.html#isInteractive()

【讨论】:

  • 优秀的亚历山大! BroadcastReceiver 目前没有收到我想要的操作,但这个成功了 :)
  • pm.isScreenOn() 已弃用。
  • @SuperThomasLab 用什么代替?
  • 三星 Always On Display 之类的东西会影响isInteractive() 功能吗?
  • @RuchirBaronia 想通了:stackoverflow.com/a/60218008/1720829
【解决方案2】:

正如this answer 中提到的类似问题。 在 API 21 及更高版本中,我们可以使用DisplayManager 来确定显示的状态。这样做的好处是支持多显示器的查询:

DisplayManager dm = (DisplayManager) 
context.getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays()) {
    if (display.getState() != Display.STATE_OFF) {
        return true;
    }
}
return false;

根据您的情况,查询显示特定视图的显示器可能更合适:

myView.getDisplay().getState() != Display.STATE_OFF

【讨论】:

  • 它有效,但我有一个问题。我在 onStop() 中使用了这段代码。当我离开应用程序(没有完全杀死它)时,它会按我的预期返回 true。但是当我关闭设备时,它不会返回 false。只有当我返回应用程序并在应用程序处于前台时关闭设备时,它才会返回 false。我想要的是我想在应用程序处于后台状态时检查状态。
  • @AbdulsametKılınçarslan 因此,当您将应用程序发送到后台时,会调用此代码。但是当你关闭设备时它没有被调用?我相信如果这段代码在 onStop() 中,那是因为 onStop() 只会在活动被销毁时被调用。这只会发生一次。您可能需要做这篇文章的 OP 正在做的事情,并使用广播接收器来收听屏幕关闭事件。
【解决方案3】:
PowerManager pm = (PowerManager) mMainActivity.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = Utils.hasLollipop() ? pm.isInteractive() : pm.isScreenOn();

【讨论】:

  • 什么是 Utils.hasLollipop?这如何以更好的方式回答这个问题?
  • @Jaward public static boolean hasLollipop() { return Build.VERSION.SDK_INT >= 21; } isScreenOn() 已弃用,但 isInteractive() 不能低于 21。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 2017-10-28
  • 1970-01-01
  • 2020-01-10
相关资源
最近更新 更多