Android O - FLAG_SHOW_WHEN_LOCKED 已弃用
Android O - FLAG_SHOW_WHEN_LOCKED is deprecated
我的申请对象是 Android O。
在我的应用程序中,我有一个作业服务显示 window 超过所有其他应用程序,因此当它触发时它需要显示此 window 即使屏幕已关闭并解锁并打开它。
我在之前的 Android 版本中实现了这种行为,但在 Android O 中它并没有像我预期的那样工作。
我读到我需要使用标志 TYPE_APPLICATION_OVERLAY
并且还在清单文件中添加了权限 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
。
所以当屏幕打开时它工作正常,但是当屏幕关闭时我注意到它没有打开屏幕,当我打开屏幕时我看到 window是在其他应用程序之上创建的。
所以我的问题是,由于标志 FLAG_TURN_SCREEN_ON
和 FLAG_SHOW_WHEN_LOCKED
在 Android API 中已弃用 27,有什么替代方法可以做到这一点?
这是我当前的代码:
private void showView()
{
if (!wakeLockAcquired)
{
wakeLock.acquire();
wakeLockAquired = true;
}
windowManager = (WindowManager)context.getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
PixelFormat.RGBA_8888);
RelativeLayout layout = buildView();
windowManager.addView(layout, layoutParams);
windowManager.updateViewLayout(layout, layoutParams);
}
备注:
- buildView 是一个 returns 相对布局的函数,在这个函数中我动态添加内容(TextView、ImageView 等...)。
- wakeLockAcquired为boolean成员,视图销毁时设置为false。
因此根据 android 文档,这些方法已被弃用,因此您需要改用 showWhenLocked or setShowWhenLocked(boolean)
。
FLAG_TURN_SCREEN_ON
int FLAG_TURN_SCREEN_ON
This constant was deprecated in API level 27.
Use turnScreenOn or setTurnScreenOn(boolean) instead to prevent an
unintentional double life-cycle event.
Window flag: when set as a window is being added or made visible, once
the window has been shown then the system will poke the power
manager's user activity (as if the user had woken up the device) to
turn the screen on.
和FLAG_SHOW_WHEN_LOCKED
int FLAG_SHOW_WHEN_LOCKED
This constant was deprecated in API level 27.
Use showWhenLocked or setShowWhenLocked(boolean) instead to prevent an unintentional double life-cycle event.
Window flag: special flag to let windows be shown when the screen is
locked. This will let application windows take precedence over key
guard or any other lock screens. Can be used with FLAG_KEEP_SCREEN_ON
to turn screen on and display windows directly before showing the key
guard window. Can be used with FLAG_DISMISS_KEYGUARD to automatically
fully dismisss non-secure keyguards. This flag only applies to the
top-most full-screen window.
因此根据文档,弃用这些方法的原因是为了避免 an unintentional double life-cycle event.
您可以在此处阅读有关它们的更多信息。
https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html
好的,所以我设法通过一些解决方法和@Umair 的回答帮助解决了这个问题。
正如我所说,我正在显示一个使用 WindowManager 在后台服务中创建的视图,并使用我在上面的问题中添加的代码,该视图显示在所有其他应用程序之上,但不会转动当 Android 版本为 Android 8.
时屏幕开启
现在替换标志的方法:FLAG_SHOW_WHEN_LOCKED
FLAG_TURN_SCREEN_ON
对活动可见,对服务或 WindowManager 不可见,并且将上下文转换为 Activity 不是一个好方法想法,不会帮助你:)
所以我现在所做的(临时解决方案)是创建一个透明 activity 并且当我从后台服务调用 showView()
方法时,我也会启动透明activity.
在 activity - 在 onCreate 方法中,我正在调用以下方法:
setShowWhenLocked(true)
setTurnScreenOn(true)
并且当视图被销毁时,activity 也会在广播接收器的帮助下被销毁:)
所以现在屏幕已打开,视图位于所有其他应用程序之上。
我知道你可以告诉我,我可以将我的服务中的代码移动到新的 activity。
我这样做的原因:
我正在使用语音识别器.. 当我在 activity 中对其进行编码时,没有任何效果。我的意思是当屏幕被模式锁定时,activity 进入暂停状态,我无法得到结果。所以模式解雇了我的 activity..
所以我决定使用 window 管理器创建一个视图,直到现在它运行良好 - 当 Google(Android 团队)决定弃用这些标志时。
所以这是我现在的解决方案..我希望有人能找到更好的解决方案。
如果 attr turnScreenOn 为真,KeyguardManager 打开屏幕,因此方法顺序和调用 requestDismissKeyguard 是必要的。我将此代码用于 activity,希望对您有所帮助:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}
}
你经历过吗
setShowWhenLocked(true)
setTurnScreenOn(true)
在 Android 9 中不再打开屏幕?还是只是我的情况?
正如 Dmitry Ognyov 在上面发布的那样 - 除了这些:
setShowWhenLocked(true); setTurnScreenOn(true);
你也需要关闭键盘锁 keyguardManager.requestDismissKeyguard(...
我的申请对象是 Android O。 在我的应用程序中,我有一个作业服务显示 window 超过所有其他应用程序,因此当它触发时它需要显示此 window 即使屏幕已关闭并解锁并打开它。 我在之前的 Android 版本中实现了这种行为,但在 Android O 中它并没有像我预期的那样工作。
我读到我需要使用标志 TYPE_APPLICATION_OVERLAY
并且还在清单文件中添加了权限 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
。
所以当屏幕打开时它工作正常,但是当屏幕关闭时我注意到它没有打开屏幕,当我打开屏幕时我看到 window是在其他应用程序之上创建的。
所以我的问题是,由于标志 FLAG_TURN_SCREEN_ON
和 FLAG_SHOW_WHEN_LOCKED
在 Android API 中已弃用 27,有什么替代方法可以做到这一点?
这是我当前的代码:
private void showView()
{
if (!wakeLockAcquired)
{
wakeLock.acquire();
wakeLockAquired = true;
}
windowManager = (WindowManager)context.getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
PixelFormat.RGBA_8888);
RelativeLayout layout = buildView();
windowManager.addView(layout, layoutParams);
windowManager.updateViewLayout(layout, layoutParams);
}
备注:
- buildView 是一个 returns 相对布局的函数,在这个函数中我动态添加内容(TextView、ImageView 等...)。
- wakeLockAcquired为boolean成员,视图销毁时设置为false。
因此根据 android 文档,这些方法已被弃用,因此您需要改用 showWhenLocked or setShowWhenLocked(boolean)
。
FLAG_TURN_SCREEN_ON
int FLAG_TURN_SCREEN_ON This constant was deprecated in API level 27. Use turnScreenOn or setTurnScreenOn(boolean) instead to prevent an unintentional double life-cycle event.
Window flag: when set as a window is being added or made visible, once the window has been shown then the system will poke the power manager's user activity (as if the user had woken up the device) to turn the screen on.
和FLAG_SHOW_WHEN_LOCKED
int FLAG_SHOW_WHEN_LOCKED This constant was deprecated in API level 27. Use showWhenLocked or setShowWhenLocked(boolean) instead to prevent an unintentional double life-cycle event.
Window flag: special flag to let windows be shown when the screen is locked. This will let application windows take precedence over key guard or any other lock screens. Can be used with FLAG_KEEP_SCREEN_ON to turn screen on and display windows directly before showing the key guard window. Can be used with FLAG_DISMISS_KEYGUARD to automatically fully dismisss non-secure keyguards. This flag only applies to the top-most full-screen window.
因此根据文档,弃用这些方法的原因是为了避免 an unintentional double life-cycle event.
您可以在此处阅读有关它们的更多信息。
https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html
好的,所以我设法通过一些解决方法和@Umair 的回答帮助解决了这个问题。
正如我所说,我正在显示一个使用 WindowManager 在后台服务中创建的视图,并使用我在上面的问题中添加的代码,该视图显示在所有其他应用程序之上,但不会转动当 Android 版本为 Android 8.
时屏幕开启现在替换标志的方法:FLAG_SHOW_WHEN_LOCKED
FLAG_TURN_SCREEN_ON
对活动可见,对服务或 WindowManager 不可见,并且将上下文转换为 Activity 不是一个好方法想法,不会帮助你:)
所以我现在所做的(临时解决方案)是创建一个透明 activity 并且当我从后台服务调用 showView()
方法时,我也会启动透明activity.
在 activity - 在 onCreate 方法中,我正在调用以下方法:
setShowWhenLocked(true)
setTurnScreenOn(true)
并且当视图被销毁时,activity 也会在广播接收器的帮助下被销毁:) 所以现在屏幕已打开,视图位于所有其他应用程序之上。
我知道你可以告诉我,我可以将我的服务中的代码移动到新的 activity。
我这样做的原因:
我正在使用语音识别器.. 当我在 activity 中对其进行编码时,没有任何效果。我的意思是当屏幕被模式锁定时,activity 进入暂停状态,我无法得到结果。所以模式解雇了我的 activity..
所以我决定使用 window 管理器创建一个视图,直到现在它运行良好 - 当 Google(Android 团队)决定弃用这些标志时。 所以这是我现在的解决方案..我希望有人能找到更好的解决方案。
如果 attr turnScreenOn 为真,KeyguardManager 打开屏幕,因此方法顺序和调用 requestDismissKeyguard 是必要的。我将此代码用于 activity,希望对您有所帮助:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}
}
你经历过吗
setShowWhenLocked(true)
setTurnScreenOn(true)
在 Android 9 中不再打开屏幕?还是只是我的情况?
正如 Dmitry Ognyov 在上面发布的那样 - 除了这些:
setShowWhenLocked(true); setTurnScreenOn(true);
你也需要关闭键盘锁 keyguardManager.requestDismissKeyguard(...