show notifications - Do Not Disturb mode enabled - android

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" />

Related

Notifications only work on certain versions of android

My app uses a receiver to send the user notifications after a certain amount of time. The receiver works great as it runs a few functions, the notification however doesn't work so smoothly.
On the emulator (API29 and Android 10) it sends them correctly however when I install it on real devices it either doesn't work at all or works perfectly fine.
My phone had the notifications perfectly until when I updated it to android 12, from then on no notifications are fired. I also tested it on an older device (Android 7) and again it doesn't work.
I read into it and don't really understand how the channels work, so I think the issue might be there however I find it weird how it would then still work on some devices/emulators.
Here is my code:
class MyReceiver: BroadcastReceiver() {
#RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context, intent: Intent) {
val notificationChannel =
NotificationChannel("My Channel", "New Quote",
NotificationManager.IMPORTANCE_DEFAULT).apply {
description = "Alerts when A new daily quote is set!"
}
val titles = arrayOf(
"Become inspired!",
"Check out this quote!",
"A new quote appeared!",
"Daily quote available!"
)
val title = titles.random()
val i = Intent(context, Qinperation::class.java)
val builder = NotificationCompat.Builder(context, "My Channel")
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle(title)
.setContentText("A new daily quote is available for viewing")
.setContentIntent(
PendingIntent.getActivity(
context,
0,
i,
PendingIntent.FLAG_UPDATE_CURRENT
)
);
with(NotificationManagerCompat.from(context)) {
createNotificationChannel(notificationChannel)
notify(1, builder.build())
}
}
}
All help is appreciated :)
Channels are required for android version O and above. You need to create the channel(s) before you receive a notification. Channels basically are like a "switch" that can be turned off and on from the settings of the app and you configure your notifications, this means you can configure if you receive a notification if it should vibrate etc.
Before android version O you don't require a channel and the configuration of the notification is happening from the notificationBuilder.
So if you want to configure your notifications for above and bellow version O you have to do it on both places.
Now regarding your problem I think, you create to late the channel and call this method in your first activity or in the application class :
private fun createNotificationChannel() {
// 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) {
val name = getString(R.string.channel_name)
val descriptionText = getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
And then in your receiver you need only to create your notification and finally call this:
with(NotificationManagerCompat.from(this)) {
// notificationId is a unique int for each notification that you must define
notify(notificationId, builder.build())
}
In case this doesn't work you might want to add a log to see if your receiver is indeed called.
This was my bad. Turns out that on certain devices (like the one I was testing on), Doesn't support the pending intent I was using to fire the notification. If people have a similar issue, try changing Pending Intents to - PendingIntent.FLAG_IMMUTABLE as this works on more devices, Especially newer ones!

Having notification in system tray makes device slow

I have 3 samsung S10 devices, on two of which this problem occurs:
If there is a notification present in the system tray that belongs to the app, it takes the phone about 5 seconds to turn on the screen when clicking the power button.
If there is no notification in the system tray, the screen turns on immediately.
If you manually remove the notification from the system tray, without opening the app, it fixes the issue with the delay in turning on the screen.
What could be causing this problem?
There could only be 1 notification, each new notification replaces the old one.
All the notification does is open the app.
The problem is apparent without opening the app, just having the notification in the tray and the app is not in the background is enough to cause the problem.
The problem is not apparent on any other device that I have.
This is the code that loads the notification into the system tray once it arrives via firebase messaging
private fun sendNotification(message: RemoteMessage) {
val intent = this.packageManager.getLaunchIntentForPackage(this.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent =
PendingIntent.getActivity(applicationContext, Random().nextInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT)
val gson = Gson()
val jsonData = gson.toJson(message.data)
val data = gson.fromJson(jsonData, NotificationPayload::class.java)
if (data.isEmpty()) {
Timber.i("Was supposed to display notification, but there was no data to display")
return
}
val defaultSoundUri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this, context.getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_notification) //
.setContentTitle(data.title) //
.setContentText(data.body) //
.setColor(ContextCompat.getColor(context, R.color.very_dark_blue)).setAutoCancel(true) //
.setSound(defaultSoundUri) //
.setOnlyAlertOnce(true) //
.setContentIntent(pendingIntent) as NotificationCompat.Builder
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val importance = when(ApplicationForegroundListener.isApplicationForeground()) {
true -> NotificationManager.IMPORTANCE_DEFAULT
else -> NotificationManager.IMPORTANCE_HIGH
}
notificationBuilder.priority = importance
notificationBuilder.setVibrate(LongArray(0))
// Since android Oreo notification channel is needed.
val channel = NotificationChannel(context.getString(R.string.app_name),
context.getString(R.string.app_name),
importance)
notificationManager.createNotificationChannel(channel)
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
The issue was the size of the notification icon in dp.
I needed to scale it down to 48x48 to fix it.

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?

Android: Self managed ConnectionService, how to implement actions in custom incoming call screen

I am building a Voip app in android. Everything is working fine but I am not able to figure out how to accept and reject calls.
I use TelephoneManager#addNewIncomingCall to report new calls to the system. After that, I created a Connection object in ConnectionService#onCreateIncomingConnection and returned it. The onShowIncomingCallUi gets called and I create a notification this way:
val intent = Intent(context, TokboxActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
this.putExtras(this#Call.extras)
}
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, "OKDOK")
.setSmallIcon(R.drawable.common_full_open_on_phone)
.setContentTitle("OKDOK")
.setContentText("Incoming call from ${extras.getString("docName")}")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setFullScreenIntent(pendingIntent, true)
.build()
notification.flags = notification.flags or NotificationCompat.FLAG_INSISTENT
val notificationManager = context.getSystemService(
NotificationManager::class.java)
notificationManager.notify("OKDOK", 0, notification)
I am getting the notification too. But I have two buttons in TokboxActivity. I want them to accept and reject the call. How do I implement that?

Cancelling notification from BroadcastReceiver is not working

I use BroadcastReceiver to process some data after user clicks on action button from notification.
So in order to achieve that first I build PendingIntent:
val intent = Intent(context, CustomBroadcastReceiver::class.java).apply {
action = MY_ACTION
// Also put some extras here like notification id.
}
val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0)
And this is called from Service which builds and shows the notification:
NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(getString(R.string.title))
.setContentText(getString(R.string.text))
.setSmallIcon(R.drawable.ic_notification)
.addAction(actionIcon, actionTitle, pendingIntent)
.setAutoCancel(true)
.build()
Then in CustomBroadcastReceiver I'm cancelling this notification (I have notification ID from intent):
getNotificationManager().cancel(notificationId)
The problem is that notification is not dismissed, it's till on notification drawer.
I saw answers from this question, but it doesn't help - I'm using applicationContext, notificationId is correct and it's greater than 0.

Categories

Resources