I'm trying to create an android full screen notification to show an activity over the lock screen, like an alarm clock.
The notification always occurs, but the activity is never started over the lock screen; it just rings and shows a notification icon on the lock screen if the phone is off. It shows a heads up notification if the phone is on as expected. A debug print indicates the notification channel is successfully registered at importance level HIGH/4 as requested.
I've tried it on 5 different android device versions: Android 10, 8.0.0, 6.0.1, 5.1.1
I've followed the android developers documentation linked below. I also linked a couple similar stack overflow questions.
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
Below is a very minimal version of the application code, an activity with 1 button to schedule the notification in the future with a broadcast receiver so it fires after the screen is locked.
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());
}
}
}
}
I was finally able to get this to work after finding this answer for an incoming call: https://stackoverflow.com/a/53192049/13008865
The part missing from the android document examples for full screen intents was that the activity the full screen intent tries to show needs a couple WindowManager.LayoutParams flags set: FLAG_SHOW_WHEN_LOCKED and FLAG_TURN_SCREEN_ON.
Here's the final minimal test app code I hope is useful for others trying to do an alarm clock type app. I tested successfully on the 4 OS versions listed above with target sdk 29 and minimum sdk 15. The only manifest permission needed was USE_FULL_SCREEN_INTENT and only for devices running android Q/29 and above.
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);
}
}
}
}
//use the following code it will work
//also put this in your 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With