我正在尝试创建一个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
下面是应用程序代码的一个非常简单的版本,它是一个带有1个按钮的活动,用于在将来与广播接收器一起调度通知,以便在锁定屏幕后触发。
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());
}
}
}
}
找到来电的答案后,终于可以使它正常工作:https://stackoverflow.com/a/53192049/13008865
Android文档示例中针对全屏意图缺失的部分是,全屏意图试图显示的活动需要设置几个WindowManager.LayoutParams标志:FLAG_SHOW_WHEN_LOCKED和FLAG_TURN_SCREEN_ON。
这是最终的最小测试应用程序代码,我希望这对尝试制作闹钟类型应用程序的其他人很有用。我已在上面列出的4个OS版本上成功测试,目标sdk 29和最低sdk15。唯一的清单许可是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);
}
}
}
}