setFullScreenIntent on Android 13 not shown over lock screen - android

I am trying to use setFullScreenIntent to show my alarm screen when the lock screen is on:
// I am using AlarmManager to send notification at a specific time:
setAlarmClock(AlarmManager.AlarmClockInfo(info.cld.timeInMillis, null), pendingIntent)
// FullscreenIntent to open activity on lock screen
val fullScreenIntent = Intent(context, MainActivity::class.java)
val fullPendingIntent = PendingIntent.getActivity(
context, FULL_PENDING_ID, fullScreenIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val builder = NotificationCompat
.Builder(context, context.getString(R.string.notification_channel_id))
.setDefaults(0)
.setSmallIcon(R.drawable.logo)
.setSilent(true)
.setLargeIcon(bm)
.setAutoCancel(false)
.setContentIntent(tapPendingIntent)
.setFullScreenIntent(fullPendingIntent, true)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentTitle(context.getString(R.string.label_alarm_notification))
.setColor(ContextCompat.getColor(context, R.color.blue))
.setOngoing(true)
mgr.notify(NOTIFICATION_ID, builder.build())
// On MainActivity, I added some flags:
fun setupShowOverLockedScreen() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
)
}
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
// I added those permissions as well
<uses-permission android:name="android.permission.SET_ALARM" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
It's working fine on Android 12 or below. However, when I tested the Android 13 phone, it stopped working. From the log, I can see the notification was fired, but the activity was not shown on the lock screen.
Does anyone have a solution for it?

Related

Android Stopping Foreground Service when device locks

On my Android 12 device, the ActivityManager is stopping my foreground service when the device locks. The service's purpose is to get GPS info and do various tracking and specialty geofencing (which cannot be handled by the regular GeoFencing features). I need it to run all the time.
My Activity does:
Context context = getApplicationContext();
Intent intent = new Intent(context, NavService.class); // Build the intent for the Navigation service
if (!isNavServiceRunning())
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
Log.v(LOG_TAG, "startForegroundService(NavService)");
context.startForegroundService(intent);
} else
context.startService(intent);
}
and that Log.v entry does show up.
Then my Service does:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID, "Foreground Service Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
Notification notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle(getText(R.string.nav_service_title))
.setContentText(getText(R.string.nav_service_message))
.setSmallIcon(R.drawable.logo_no_text_plain_24x24)
.setContentIntent(pendingIntent)
.setTicker(getText(R.string.nav_service_ticker_text))
.setAutoCancel(false)
.setOngoing(true)
.build();
Log.v(LOG_TAG, "startForeground");
startForeground(SERVICE_ID, notification);
}
// Now start the GPS updates. Note: Permissions were requested in main activity.
startGpsUpdates(); // My code to kick off updates.
return START_STICKY;
And that Log.v entry shows up.
I should add my manifest stuff here:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<service android:name=".NavService" android:foregroundServiceType="location" />
But when the phone locks, I get "ActivityManager: Stopping service due to app idle: u0a528 -1m16s853ms com.hubbardsoftware.racetac/.NavService"
Everything works fine up until then. The notification shows up as required. This seems to be per the documentation for long running services.
???
Thanks,
Dave

show notifications - Do Not Disturb mode enabled

Does someone know how to receive notifications on a device when silent mode is enabled?
I'm sending notifications push with a web server and firebase, and it seems impossible to receive a notification when the android device is in silence mode (Do Not Disturb).
But, when I put my smartphone in silent mode my alarms are still ringing.
Then we should be able to receive a notification categorized "alarm", even in Silence mod. No?
The best way to show notification in silent mode is to show full-screen intent
val summaryNotification =
NotificationCompat.Builder(
context,
notificationChannelId
)
.setSmallIcon(getSmallIconForNotification())
.setLargeIcon(largeIcon(context))
.setStyle(bigPicStyle)
.setContentTitle(title)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.addAction(
R.drawable.ic_cancel_small,
context.getString(R.string.dismiss),
dismissIntent
)
.setAutoCancel(true)
.setTimeoutAfter(durationInMilliSeconds!!.toLong())
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentIntent(
contentIntent(
context,
SUMMARY_NOTIFICATION_ID
)
)
if (!showFull) {
summaryNotification.setSound(sound, AudioManager.STREAM_ALARM)
}
if (showFull) {
summaryNotification.setFullScreenIntent(buildPendingIntent(context, i), true)
}
notificationManager.notify(
SUMMARY_NOTIFICATION_ID,
summaryNotification.build()
)
build pending intent:
private fun buildPendingIntent(
context: Context,
intent: Intent
): PendingIntent? {
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
when you receive data from firebase check if the phone is active or not and then send proper notification
val mPowerManager = context!!.getSystemService(Context.POWER_SERVICE) as PowerManager
if (!mPowerManager.isInteractive) {
showFullNotification(true)
}else{
showFullNotification(false)
}
then you have to create an alarming activity.
to hide action bar in alarm activity:
(this as AppCompatActivity?)!!.supportActionBar!!.hide()
and in the manifests
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

Opening call activity from notification in lock screen

I'm able to show notification that redirects to call activity when call is incoming and screen is unlocked, but that notification doesn't respond when screen lock is active. I see it, but if I click on it, no events are getting fired.
I use following code from https://developer.android.com/training/notify-user/time-sensitive
val fullScreenIntent = Intent(this, CallActivity::class.java)
fullScreenIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_USER_ACTION or Intent.FLAG_ACTIVITY_SINGLE_TOP
val fullScreenPendingIntent = PendingIntent.getActivity(
this, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
val notificationBuilder =
NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Incoming call")
.setContentText("(919) 555-1234")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentIntent(fullScreenPendingIntent)
.setFullScreenIntent(fullScreenPendingIntent, true)
val incomingCallNotification = notificationBuilder.build()
startForeground(NOTIFICATION_ID, incomingCallNotification)
Iadded permission:
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
I've tried numerous suggestions on SO, but none of them seem to work. My activity does have required code to open above lock screen, but it's onCreate or onNewIntent newer get called from lockscreen.
Any ideas?

Open Activity from BroadcastReceiver when screen off

When app is running and device is locked I'm able to start the activity. But when app is in background and device is locked not able to start the activity even though I'm getting the control in BroadcastReceiver class. This is my intent call.
context.startActivity(new Intent(context, ReceiveCallActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setAction(Intent.ACTION_ANSWER)
.putExtra("title", intent.getStringExtra("title"))
.putExtra("action", intent.getStringExtra("action")));
Manifest of Activity
<activity
android:name=".ReceiveCallActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true"
android:launchMode="singleTop"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:turnScreenOn="true"
android:windowSoftInputMode="adjustPan|stateHidden" />
ReceiveCallActivity.class
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
} else {
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
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
}
setContentView(R.layout.receive_call_activity);
...
...
}
setShowWhenLocked(true) && setTurnScreenOn(true) helps to open app even if device is locked but app has to be in foreground for that.
PS: I'm getting the control in BroadcastReceiver in all scenarios.
TIA
I was checking different permissions given to Skype from Settings, and noticed 'Show on Lock Screen' is enabled while the same was disabled for my App. On enabling it, BroadcastReceiver is able to open Activity in all scenarios. I read it's a issue with Xiamoi devices(I'm using Note 5 Pro).
EDIT
For Android 10 need to add USE_FULL_SCREEN_INTENT permission in manifest.
Then when the screen is locked, PendingIntent set as FullScreenIntent on NotificationCompat.Builder will be called.
My Notification code:
private void showCallNotification(Map<String, String> dataMap) {
//CREATING pendingIntent
...
...
...
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 2, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(this, 1, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews notificationLayout = new RemoteViews(getPackageName(), R.layout.notification_small);
notificationLayout.setTextViewText(R.id.tvTitle, dataMap.get("sender"));
notificationLayout.setTextViewText(R.id.tvContent, getString(R.string.incoming_call));
notificationLayout.setOnClickPendingIntent(R.id.tvAccept, pendingIntent);
notificationLayout.setOnClickPendingIntent(R.id.tvDecline, cancelPendingIntent);
RemoteViews notificationLayoutExpanded = new RemoteViews(getPackageName(), R.layout.notification_large);
notificationLayoutExpanded.setTextViewText(R.id.tvTitle, dataMap.get("sender"));
notificationLayoutExpanded.setTextViewText(R.id.tvContent, getString(R.string.incoming_call));
notificationLayoutExpanded.setOnClickPendingIntent(R.id.btAccept, pendingIntent);
notificationLayoutExpanded.setOnClickPendingIntent(R.id.btDecline, cancelPendingIntent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, AppConstants.CALL_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(dataMap.get("sender"))
.setContentText(getString(R.string.incoming_call))
.setAutoCancel(true)
.setTimeoutAfter(CALL_DISMISS_TIME)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setCustomBigContentView(notificationLayout)
.setCustomContentView(notificationLayoutExpanded)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(fullScreenPendingIntent)
.setFullScreenIntent(fullScreenPendingIntent, true);
if (Build.VERSION.SDK_INT < 26) {
builder.setPriority(NotificationCompat.PRIORITY_MAX);
}
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createCallNotificationChannel();
}
notificationManager.notify(notificationId, builder.build());
}
And i call it like this
onMessageReceived()
if (Build.VERSION.SDK_INT > 28) {
if (isAppOnForeground(getApplicationContext())) {
sendBroadcast(remoteMessage);
} else {
showCallNotification(dataMap);
}
} else {
sendBroadcast(remoteMessage);
}

Full screen intent not starting the activity but do show a notification on android 10

I try to launch activity for a broadcastReceiver by using the next code
Intent i = new Intent(context, AlarmNotification.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // This is at least android 10...
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (mgr.getNotificationChannel(CHANNEL_WHATEVER)==null) {
mgr.createNotificationChannel(new NotificationChannel(CHANNEL_WHATEVER,
"Whatever", NotificationManager.IMPORTANCE_HIGH));
}
mgr.notify(NOTIFY_ID, buildNormal(context, i).build());
}
private NotificationCompat.Builder buildNormal(Context context, Intent intent) {
NotificationCompat.Builder b=
new NotificationCompat.Builder(context, CHANNEL_WHATEVER);
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(TEXT)
.setContentText(TEXT)
.setFullScreenIntent(buildPendingIntent(context, intent), true);
return(b);
}
private PendingIntent buildPendingIntent(Context context, Intent intent) {
return(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
In the beginning, everything work's perfectly fine. But if I enter the app settings, turn off the notification channel of CHANNEL_WHATEVER, and then turn it on again. Later when I call NotificationManager.notify it shows the notification in the notification drawer but does not start the activity. If I delete the app and reinstall, it works fine again. Is that a bug of android 10 which I should report on, or there is something I can do about it?
In Android 10 we need to add permission for USE_FULL_SCREEN_INTENT
Permissions changes for fullscreen intents
Apps that target Android 10 or higher and use notifications with fullscreen intents must request the USE_FULL_SCREEN_INTENT permission in their app's manifest file.
This is a normal permission, so the system automatically grants it to the requesting app.
Make sure you have added permission in manifest file
SAMPLE CODE
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nilu.demo">
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Android doesn't grant that the activity is shown even if you use a full screen intent:
On some platforms, the system UI may choose to display a heads-up
notification, instead of launching this intent, while the user is
using the device.
Please go through my article on medium on how to launch activity with full screen intent for OS 10. The article also explains how to display headsup notification and to handle action button clicks.
https://medium.com/#dcostalloyd90/show-incoming-voip-call-notification-and-open-activity-for-android-os-10-5aada2d4c1e4
not sure if this was answered. In addition to Permissions previously mentioned... The only way i found to make this work is to use a "NotificationManager.IMPORTANCE_HIGH" Channel and the Notification.
After setting to HIGH, the fullScreenIntent will be opened if the screen is off. Changing the Channel later seems to require an uninstall and reinstall.
Set up the Notification Channel before sending the Notification as (see also):
private static void createNotificationChannel(Context context) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = **"YOUR CHANNEL"**;
String description = "YOUR CHANNEL DESCRIPTION";
int importance = **NotificationManager.IMPORTANCE_HIGH**;
NotificationChannel channel = new NotificationChannel( "YOUR CHANNEL ID", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
I set both intents, unclear if you have to set both:
createNotificationChannel((context));
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, **"YOUR CHANNEL**");
builder.setContentIntent(pendingIntent);
builder.setFullScreenIntent(pendingIntent,true);
If you want to display your own activity on lock screen you need to enable showOnLockScreen in Manifest
<activity android:name="NewActivity" android:showOnLockScreen="true" />
and set flag showWhenLocked in your activity class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
}
}
Finally create a fullScreenIntent with your activity class and attach it to notification
Intent fullScreenIntent = new Intent(applicationContext, NewActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(applicationContext, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(applicationContext, channel)
.setSmallIcon(R.drawable.ic_small)
.setContentTitle(textTitle)
.setContentText(textContent)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setFullScreenIntent(fullScreenPendingIntent, true)
.setAutoCancel(true);
You should wake up the screen of Android, before showing the notification:
fun asquireWake() {
val mPowerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val mWakeLock: PowerManager.WakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_DIM_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP,
"YourApp:Whatever"
)
mWakeLock.acquire()
}
In my case the problem was in the notification id which is used to show the full screen intent notification.
If we have the previous notification with the same notification id, then the full screen intent activity will not be launched instead heads up notification will be shown in the lock screen.
so try using the unique notification id for the full screen intent notification.
For more info about how to setup full screen intent notification:Display time-sensitive notifications
for these who has problems with:
builder.setFullScreenIntent(pendingIntent, true)
please try to use instead:
builder.setContentIntent(pendingIntent)

Categories

Resources