Android 全屏通知不会显示在锁定屏幕上
Posted
技术标签:
【中文标题】Android 全屏通知不会显示在锁定屏幕上【英文标题】:Android full screen notification won't show over the lock screen 【发布时间】:2020-06-17 12:42:18 【问题描述】:我正在尝试创建一个 android 全屏通知以在锁定屏幕上显示活动,例如闹钟。
通知总是发生,但活动永远不会在锁定屏幕上启动;如果手机关机,它只会响铃并在锁定屏幕上显示通知图标。如果手机按预期开机,它会显示提示通知。调试打印表明通知通道已按要求成功注册为重要性级别 HIGH/4。
我已经在 5 种不同的 Android 设备版本上进行了尝试:Android 10、8.0.0、6.0.1、5.1.1
我遵循了下面链接的 android 开发者文档。我还链接了几个类似的堆栈溢出问题。
https://developer.android.com/training/notify-user/time-sensitive
https://developer.android.com/training/notify-user/build-notification#urgent-message
Full screen intent not starting the activity but do show a notification on android 10
FullScreen Notification
下面是应用程序代码的极简版本,一个带有 1 个按钮的 Activity,用于通过广播接收器安排未来的通知,以便在屏幕锁定后触发。
compileSdkVersion 29
buildToolsVersion "29.0.2"
minSdkVersion 25
targetSdkVersion 29
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
public class AppReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
if (FullscreenActivity.FULL_SCREEN_ACTION.equals(intent.getAction()))
FullscreenActivity.CreateFullScreenNotification(context);
public class FullscreenActivity extends AppCompatActivity
private static final String CHANNEL_ID = "my_channel";
static final String FULL_SCREEN_ACTION = "FullScreenAction";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
createNotificationChannel(this);
/**
* Use button to set alarm manager with a pending intent to create the full screen notification
* after use has time to shut off device to test with the lock screen showing
*/
public void buttonClick(View view)
Intent intent = new Intent(this, AppReceiver.class);
intent.setAction(FULL_SCREEN_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
if (am != null)
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 15000, pi);
static void CreateFullScreenNotification(Context context)
Intent fullScreenIntent = new Intent(context, FullscreenActivity.class);
fullScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);//?
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(context, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Full Screen Alarm Test")
.setContentText("This is a test")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setDefaults(NotificationCompat.DEFAULT_ALL) //?
.setFullScreenIntent(fullScreenPendingIntent, true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(1, notificationBuilder.build());
private static void createNotificationChannel(Context context)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
if (notificationManager != null && notificationManager.getNotificationChannel(CHANNEL_ID) == null)
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("channel_description");
notificationManager.createNotificationChannel(channel);
//DEBUG print registered channel importance
if (notificationManager != null && notificationManager.getNotificationChannel(CHANNEL_ID) != null)
Log.d("FullScreenActivity", "notification channel importance is " + notificationManager.getNotificationChannel(CHANNEL_ID).getImportance());
【问题讨论】:
【参考方案1】:在找到来电的答案后,我终于能够让它工作: https://***.com/a/53192049/13008865
全屏意图的 android 文档示例中缺少的部分是全屏意图尝试显示的活动需要设置几个 WindowManager.LayoutParams 标志: FLAG_SHOW_WHEN_LOCKED 和 FLAG_TURN_SCREEN_ON。
这是最终的最小测试应用程序代码,我希望对尝试制作闹钟类型应用程序的其他人有用。我在上面列出的 4 个操作系统版本上成功测试了目标 sdk 29 和最低 sdk 15。唯一需要的清单权限是 USE_FULL_SCREEN_INTENT 并且仅适用于运行 android Q/29 及更高版本的设备。
public class AppReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
if (FullscreenActivity.FULL_SCREEN_ACTION.equals(intent.getAction()))
FullscreenActivity.CreateFullScreenNotification(context);
public class FullscreenActivity extends AppCompatActivity
private static final String CHANNEL_ID = "my_channel";
static final String FULL_SCREEN_ACTION = "full_screen_action";
static final int NOTIFICATION_ID = 1;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
createNotificationChannel(this);
//set flags so activity is showed when phone is off (on lock screen)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
/**
* Use button to set alarm manager with a pending intent to create the full screen notification
* after use has time to shut off device to test with the lock screen showing
*/
public void buttonClick(View view)
Intent intent = new Intent(FULL_SCREEN_ACTION, null, this, AppReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null)
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 15000, pendingIntent);
NotificationManagerCompat.from(this).cancel(NOTIFICATION_ID); //cancel last notification for repeated tests
static void CreateFullScreenNotification(Context context)
Intent intent = new Intent(context, FullscreenActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Full Screen Alarm Test")
.setContentText("This is a test")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true);
NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, notificationBuilder.build());
private static void createNotificationChannel(Context context)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (notificationManager.getNotificationChannel(CHANNEL_ID) == null)
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("channel_description");
notificationManager.createNotificationChannel(channel);
【讨论】:
很好,谢谢。像往常一样,Google 的文档只会让人头疼。 这是如何工作的。就我而言,我正在从后台服务中抛出具有全屏意图的通知。通知就在那里,但在我解锁设备并实际单击通知之前,活动不会启动。 @behelit 如何在设备锁定时显示活动。在某些设备上它不像 xiomi 那样工作。 @RajGohel 我找到了this article 并在“它不起作用”下给出了解决方案,显然这是特定于小米的,默认情况下禁用在锁定屏幕上显示的权限【参考方案2】://use the following code it will work
//也把它放在你的Manifest.xml中
<uses-permission android:name="android.permission.WAKE_LOCK"/>
//put this in manifest in your specific activity you want to show on lock
//screen
android:showWhenLocked="true"
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(AccessibilityEventCompat.TYPE_WINDOWS_CHANGED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
【讨论】:
【参考方案3】:对我来说,有帮助的是Ranjith Kumar's answer in this question。
下面是相同的Java代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
// For newer than Android Oreo: call setShowWhenLocked, setTurnScreenOn
setShowWhenLocked(true);
setTurnScreenOn(true);
// If you want to display the keyguard to prompt the user to unlock the phone:
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
else
// For older versions, do it as you did before.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
【讨论】:
你在哪里设置这个? 我在 Activity 的 onCreate() 方法中有这个,@elcapitan 这是如何工作的。就我而言,我正在从后台服务中发出带有全屏意图的通知。通知就在那里,但在我解锁设备并实际单击通知之前,活动不会启动。你能说明你是如何在清单上声明这个活动的吗 @Dibzmania,清单中的 Activity 没有什么特别之处。它被声明为任何其他活动。清单具有USE_FULL_SCREEN_INTENT
和 DISABLE_KEYGUARD
权限。自从我编写该代码以来已经很长时间了。但更深入地查看创建通知的代码(例如,使用 setFullScreenIntent 等)。祝你好运!【参考方案4】:
我也遇到了类似的问题,对我来说,问题不在于窗口标志,而是在触发通知时,通知通道都应该有 IMPORTANCE_HIGH 和带有 HIGH_PRIORITY 的通知,而且你正在使用红米,你必须在应用设置上明确设置权限
【讨论】:
以上是关于Android 全屏通知不会显示在锁定屏幕上的主要内容,如果未能解决你的问题,请参考以下文章
Android:不活动后,Expo Notification 未显示在锁定屏幕上