在Android中,即使屏幕被锁定,也可以启动Activity界面

18

如何在设备屏幕锁定的情况下启动一个Activity。我尝试了以下代码,但它没有起作用。

广播接收器:

Intent alarmIntent = new Intent("android.intent.action.MAIN");
        alarmIntent.setClass(context, Alarm.class);
        alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        alarmIntent.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED +
                             WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD +
                             WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON +
                             WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        context.startActivity(alarmIntent);
6个回答

25

您可以通过以下两种方式实现:

  1. 按照@Yup在这篇文章中所述的方法使用唤醒锁。

  2. 使用窗口标志。

使用窗口标志:

打开您想要在 onReceive(...)中启动的 Activity A。将以下代码粘贴到该Activity A 的 onCreate() 中。

final Window win= getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

setContentView(...)之前粘贴它,确保不要在其后面粘贴。 :-)


1
如果我使用第二种方式(使用窗口标志),我不需要在androidmanifest.xml中请求权限吗? - Dika
2
是的,你没有权限 @Dika - Junaid
当屏幕被锁定时,它也对我起作用,但是onCreate方法中的其他工作没有被调用。 例如,我正在播放声音,如果屏幕被锁定,则声音不会播放。 - Chirag Jain
@ChiragJain,我已经很久没有在Android上工作了。请将您的问题发布为另一个问题。您可以将此答案链接到您发布的问题中。 - Junaid
1
@Junaid 谢谢你的回复,实际上我通过在 onResume 方法中添加 mp.start 方法来解决问题,因为在 onDestroy 方法中最后会再次调用 onResume 方法,如果正在使用此屏幕锁定情况下的活动,则会执行以下操作 if (mpPlay.isPlaying()) { mpPlay.stop(); mpPlay.reset(); }。 - Chirag Jain
显示剩余3条评论

22

你需要在 AndroidManifest.xml 文件中添加以下权限:

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

在这里查看清单细节您可以在此链接中查询


10
将以下内容粘贴到您想要在屏幕锁定时打开的活动的 onCreate 方法中,在 setContentView() 之后。
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); 

1
对我来说,它从来没有到达onCreate方法,似乎在那之前就被某些东西阻止了。 - trampster

2
从Android 10(SDK版本29)开始,如果应用在后台运行(例如在BroadcastReceiver中),其他答案将不再有效。
为了使其在Android 10及以上版本中正常工作,如果确实需要从后台启动活动,则应使用全屏意图[source]:
引用:
Android 10(API级别29)及更高版本限制应用在后台运行时启动活动的时间。这些限制有助于最小化用户的干扰,并使用户更加控制其屏幕上显示的内容。几乎所有情况下,处于后台的应用应显示时间敏感的通知,以向用户提供紧急信息,而不是直接启动活动。例如,处理来电或活动闹钟时,应使用此类通知。
可以通过以下方式实现[source]:
val fullScreenIntent = Intent(this, CallActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

val notificationBuilder =
        NotificationCompat.Builder(this, CHANNEL_ID)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("Incoming call")
    .setContentText("(919) 555-1234")
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setCategory(NotificationCompat.CATEGORY_CALL)

    // Use a full-screen intent only for the highest-priority alerts where you
    // have an associated activity that you would like to launch after the user
    // interacts with the notification. Also, if your app targets Android 10
    // or higher, you need to request the USE_FULL_SCREEN_INTENT permission in
    // order for the platform to invoke this notification.
    .setFullScreenIntent(fullScreenPendingIntent, true)

val incomingCallNotification = notificationBuilder.build()

本回答的部分内容摘自安卓开源项目共享的作品,并根据Creative Commons 2.5 Attribution许可证中描述的条款使用。

1

对于一些 Android 8、9 版本的系统,您需要在清单中使用 SYSTME_ALERT_WINDOW 权限,并将标志添加到启动活动意图中 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

如下所示:

 val i = Intent(context, AlarmActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
 it.startActivity(i)

这是 Kotlin 语言编写的。

对于 Android 10 及以上设备,您需要使用带有 pending intent 的全屏意图通知来启动所需的活动。

了解更多关于全屏意图的信息,请访问:

全屏意图示例


0
  1. 清单文件授予权限 uses-permission android:name="android.permission.WAKE_LOCK" 然后在你需要的活动 onCreate() 方法中编写代码
  2. final Window win= getWindow(); win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接