我从BroadcastReceiver开始一个活动,它由alaram(RTC_WAKEUP类型)触发。在onCreate的那个活动我添加这些标志
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
);
问题是有时(大约10%的情况)屏幕无法打开。警报被正确触发(我这里是通知的声音,也会在接收器的onReceive()中触发。然后,如果我按下电话的电源按钮,屏幕会亮起,显示我的活动,并立即关闭。那个,电源按钮工作正常。这发生在android 2.3.7上,这里是onReceive()方法
@Override
public void onReceive(Context context, Intent intent) {
m_Context = context;
Bundle extras = intent.getExtras();
final int id = extras.getInt("timer_id");
Intent activityIntent = new Intent(m_Context, MyActivity.class);
activityIntent.putExtra("timer_id", id);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
m_Context.startActivity(activityIntent);
// and now load the alarm sound and play it for the desired time
showFinishedNotification();
}
我想避免使用PowerManager,因为它需要一个权限,并且标志是首选方式。
可能有什么问题? logcat没有显示任何问题...
答案 0 :(得分:8)
我在这里参加派对有点晚了,但我现在已经有一段时间了,最后还是找到了让屏幕每次都解锁的方法。我在onAttachToWindow()事件中添加了标志。通常我是从WakefulBroadcastReceiver执行此操作,因此屏幕平滑过渡但依赖于用例。
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
//Screen On
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
private void clearFlags() {
//Don't forget to clear the flags at some point in time.
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
答案 1 :(得分:6)
根据我对此主题的经验和研究:
FLAG_TURN_SCREEN_ON 不能用于在应用程序中多次打开和关闭屏幕。
FLAG_TURN_SCREEN_ON 只能在creating a new activity(最好是onCreate()方法)或when re-creating a view时使用一次才能启用屏幕。
现在,您可以通过以下方式解决此问题:
这些都不是理想的(实际上它们感觉像黑客)但只是使用更适合您的应用需求的那个。
您可以在这里阅读更多内容:
答案 2 :(得分:4)
问题是有时(大约10%的情况)屏幕无法打开
如果我不得不猜测,设备会在活动开始前重新入睡。一旦onReceive()
返回,设备可以并且将会重新入睡,并且在您的活动开始之前onReceive()
返回后的一段时间。
同样的情况,但将startActivity()
替换为startService()
,这就是为什么我必须编写WakefulIntentService
,它使用WakeLock
来确保设备保持足够长的清醒状态为了完成它的工作,然后发布WakeLock
。
答案 3 :(得分:2)
我同时使用这三种方法,几乎可以在任何设备上使用
。public static void turnScreenOnThroughKeyguard(@NonNull Activity activity) {
userPowerManagerWakeup(activity);
useWindowFlags(activity);
useActivityScreenMethods(activity);
}
private static void useActivityScreenMethods(@NonNull Activity activity) {
if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) {
try {
activity.setTurnScreenOn(true);
activity.setShowWhenLocked(true);
} catch (NoSuchMethodError e) {
Log.e(e, "Enable setTurnScreenOn and setShowWhenLocked is not present on device!");
}
}
}
private static void useWindowFlags(@NonNull Activity activity) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
private static void userPowerManagerWakeup(@NonNull Activity activity) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakelock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, tag);
wakeLock.acquire(TimeUnit.SECONDS.toMillis(5));
}
答案 4 :(得分:2)
最新答案,但这对任何人都可以帮助。
对于较高和较低的版本,请使用以下代码(可以正常工作)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
}
else{
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
setContentView(R.layout.activity_incoming_call);
}
重要说明:您应将其放置在setContentView()之前
答案 5 :(得分:0)
定位 sdk 30
以下代码可以从 PendingIntent 打开 Activity,即使是应用程序
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(view)
turnOnScreen()
}
private fun turnOnScreen() {
window.addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
)
setTurnScreenOn(true)
setShowWhenLocked(true)
val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
}