I am setting a custom tone for notifications. The notification is received via Firebase messaging data payload. The message is displayed correctly but the custom tone is not played. What is the problem? Here is the code
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val sound = Uri.parse("android.resource://" + applicationContext.packageName +"/"+R.raw.tone)
if (remoteMessage.data.isNotEmpty()) {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
val channelId = "Default"
val builder = NotificationCompat.Builder(this, channelId)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.ic_logo))
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(remoteMessage.data["title"]).setVisibility(VISIBILITY_PRIVATE)
.setSound(sound)
.setContentText(remoteMessage.data["body"]).setAutoCancel(true).setContentIntent(pendingIntent).setPriority(NotificationManager.IMPORTANCE_MAX)
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
val attributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
val channel = NotificationChannel(channelId, "Default channel", NotificationManager.IMPORTANCE_HIGH)
manager.createNotificationChannel(channel)
channel.setSound(sound, attributes)
}
manager.notify(0, builder.build())
}
}
Related
Method to create a Notification Channel
private fun createChannel(notificationManager: NotificationManager) {
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setLegacyStreamType(AudioManager.STREAM_RING)
.build()
val incomingPhoneCallChannel = NotificationChannel(
mNotificationManager.INCOMING_PHONE_CALL_CHANNEL_ID, "Incoming phone call",
NotificationManager.IMPORTANCE_HIGH
).apply {
setSound(uri, audioAttributes)
vibrationPattern = mNotificationManager._VIBRATION_PATTERN
enableVibration(true)
}
notificationManager.createNotificationChannel(incomingPhoneCallChannel)
}
Method to notify about the call
override fun notify(context: Context) {
val notificationManager = mNotificationManager.notificationManager
val notificationChannel = notificationManager.getNotificationChannel(mNotificationManager.INCOMING_PHONE_CALL_CHANNEL_ID)?: createChannel(notificationManager)
val contentTitle = "Incoming Call"
val contentIntent = Intent(context, PhoneCallReceiver::class.java)
val pendingIntent =
PendingIntent.getBroadcast(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
val ringtone =RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
var builder = NotificationCompat.Builder(
context,
mNotificationManager.INCOMING_PHONE_CALL_CHANNEL_ID
)
.setContentTitle(contentTitle)
.setContentIntent(pendingIntent)
.setContentText("phone call")
.setColor(ContextCompat.getColor(context, R.color.ic_launcher_background))
.setCategory(NotificationCompat.CATEGORY_CALL)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_phone_black_24dp)
.setOngoing(true)
.setSound(ringtone)
builder.setVibrate(mNotificationManager._VIBRATION_PATTERN
val notification = builder.build()
notification.flags = Notification.FLAG_INSISTENT
notificationManager.notify("Incoming Call", mId, notification)
}
The above code does give me notification with a default notification that sounds like a single "TING!!". It doesn't change the sound even if I select different Ringtones from the notification channel settings and doesn't vibrate at all.
Make sure the audio permission is allowed:
// Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// Change TYPE_RINGTONE to TYPE_NOTIFICATION
I'm creating notification using Firebase and FCM
class FcmServices: FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
sendNotification(remoteMessage)
}
override fun onNewToken(token: String) {
super.onNewToken(token)
}
private fun sendNotification(remoteMessage: RemoteMessage) {
val notifTitle = remoteMessage.notification?.title
val notifBody = remoteMessage.notification?.body
val builder: NotificationCompat.Builder?
val notificationManager =
this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "101"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_DEFAULT
val notificationChannel = NotificationChannel(channelId, "notification", importance)
notificationManager.createNotificationChannel(notificationChannel)
builder = NotificationCompat.Builder(applicationContext, notificationChannel.id)
} else {
builder = NotificationCompat.Builder(applicationContext)
}
val intent = Intent(this, NotifikasiActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
builder.setSmallIcon(R.drawable.logo_bprmsa)
.setLargeIcon(
BitmapFactory.decodeResource(
this.resources,
R.drawable.logo_bprmsa
)
)
.setContentIntent(pendingIntent)
.setContentTitle(notifTitle)
.setContentText(notifBody)
.setDefaults(Notification.DEFAULT_VIBRATE)
var alarmSound: Uri? = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
if (alarmSound == null) {
alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
if (alarmSound == null) {
alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
}
}
builder.setSound(alarmSound)
builder.setAutoCancel(true)
builder.setWhen(System.currentTimeMillis())
builder.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
builder.priority = NotificationCompat.PRIORITY_HIGH
notificationManager.notify(Random().nextInt(), builder.build())
}
}
I need to open the NotificationActivity after click the notification received from Firebase, but the problem is the PendingIntent is not working while the app is in background state. Is there any different condition between foreground and background state code ?
And for the second, the layout of foreground and background is also different (background state without the icon shown)
https://firebase.google.com/docs/cloud-messaging/concept-options
Based on the official document from Google, it is intentional. The Icon and any other buttons or others you wish to display other than the title and the message won't display if your app is not running foreground.
I have set custom sound for notification. It's working for some device but not working on some device mostly Xiaomi device.
I have used this code:
private fun createNotificationChannel(){
val context = AppApplication.getContext()
val notificationManagerCompat = NotificationManagerCompat.from(context)
preChannelIds.forEach {
deleteChannel(notificationManagerCompat,it)
}
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val attributes = getAudioAttributes()
val soundUri = getSoundUri(context)
val importance = NotificationManagerCompat.IMPORTANCE_HIGH
val channelBuilder = NotificationChannelCompat.Builder(channelId, importance).apply {
setName(channelName)
setDescription(channelDescription)
setSound(soundUri, attributes)
setVibrationPattern(vibrationPattern)
setLightsEnabled(true)
setShowBadge(true)
}
val channel = channelBuilder.build()
notificationManagerCompat.createNotificationChannel(channel)
}
}
fun sendNotification(title:String, message:String){
val context = AppApplication.getContext()
val intent = ....
val notificationManagerCompat = NotificationManagerCompat.from(AppApplication.getContext())
val pendingIntent = PendingIntent.getActivity(
AppApplication.getContext(), notificationRequestCode, intent,
PendingIntent.FLAG_UPDATE_CURRENT)
val notificationBuilder = NotificationCompat.Builder(AppApplication.getContext(), channelId)
.setSmallIcon(getNotificationIcon())
.setContentTitle(title)
.setContentText(message)
.setStyle(NotificationCompat.BigTextStyle().bigText(message))
.setAutoCancel(true)
.setVibrate(vibrationPattern)
.setColor(ContextCompat.getColor(AppApplication.getContext(), R.color.colorPrimary))
.setContentIntent(pendingIntent)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
notificationBuilder.priority = NotificationCompat.PRIORITY_MAX
notificationBuilder.setSound(getSoundUri(context))
}
val notification = notificationBuilder.build()
notification.flags = Notification.FLAG_INSISTENT
notificationManagerCompat.notify(notificationRequestCode, notification)
}
Please help me to solve this issue for some device. Is there any other solution for this issue.
I already made a notification without intent to MainActivity and it works fine, but when I add that intent to my MainActivity the notification does not show anymore. Is there anything wrong with my code or do I need to change the manifest or add some code in my MainActivity?
Here is my code. I set it into two functions - setDailyReminder and showAlarmNotification.
fun setDailyReminder(context: Context, type: String, message: String) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(EXTRA_MESSAGE, message)
intent.putExtra(EXTRA_TYPE, type)
val timeArray =
TIME_DAILY.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val calendar = Calendar.getInstance()
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArray[0]))
calendar.set(Calendar.MINUTE, Integer.parseInt(timeArray[1]))
calendar.set(Calendar.SECOND, 0)
val pendingIntent = PendingIntent.getBroadcast(context,
ID_DAILY, intent, 0)
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
pendingIntent
)
Toast.makeText(context, "Daily reminder set up", Toast.LENGTH_SHORT).show()
}
private fun showAlarmNotification(
context: Context,
title: String,
message: String?,
notifId: Int
) {
val CHANNEL_ID = "Github App"
val CHANNEL_NAME = "Let's find favourite user on Github"
val notificationManagerCompat =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setContentTitle(title)
.setContentText(message)
.setSound(alarmSound)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT
)
builder.setChannelId(CHANNEL_ID)
notificationManagerCompat.createNotificationChannel(channel)
}
val notification = builder.build()
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
notificationManagerCompat.notify(notifId, notification)
}
fun showNotification(context: Context,title: String, message:String, notifId: Int){
createNotificationChannel(context)
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0,
intent,PendingIntent.FLAG_ONE_SHOT)
var builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setColor(resources.getColor(R.color.colorAccent))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
val notificationManagerCompat = NotificationManagerCompat.from(this)
notificationManagerCompat.notify(notifId, builder.build())
}
private fun 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) {
val name = "Test"
val descriptionText = "FCM"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
I'm using Kotlin and Android Studio to try and push a Notification in a test app. I followed the instructions in the Android Developers site on How to create a Notification (https://developer.android.com/training/notify-user/build-notification) but I seem to be doing something wrong as my Notification is not showing anywhere. Here's my code:
val intent = Intent(context, Profile::class.java)
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0);
val builder = NotificationCompat.Builder(this.context)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
builder.setContentIntent(pendingIntent).setAutoCancel(true)
val mNotificationManager = message.context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
with(mNotificationManager) {
notify(123, builder.build())
I really don't know what I'm missing so I would be grateful for any help.
According to your code, you are not creating a Notification channel.
Notification channel is necessary from Android Oreo and above
So if you are running the app Android O and above devices without a notification channel, your notification won't show up.
Create Notification Channel
fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "all_notifications" // You should create a String resource for this instead of storing in a variable
val mChannel = NotificationChannel(
channelId,
"General Notifications",
NotificationManager.IMPORTANCE_DEFAULT
)
mChannel.description = "This is default channel used for all other notifications"
val notificationManager =
mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
}
Then create a notification using the same channelId while creating a notification.
createNotificationChannel()
val channelId = "all_notifications" // Use same Channel ID
val intent = Intent(context, Profile::class.java)
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0);
val builder = NotificationCompat.Builder(this.context, channelId) // Create notification with channel Id
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
builder.setContentIntent(pendingIntent).setAutoCancel(true)
val mNotificationManager =
message.context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
with(mNotificationManager) {
notify(123, builder.build())
Hope it helps.
try something like
val intent = Intent(context, Profile::class.java)
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0)
val mNotificationManager =
message.context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
mNotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//Don't forget this check
val channel = NotificationChannel (
channelId,
"my_notification",
NotificationManager.IMPORTANCE_HIGH
)
channel.enableLights(true)
channel.lightColor = Color.GREEN
channel.enableVibration(false)
val builder = NotificationCompat.Builder(this.context, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
builder.setContentIntent(pendingIntent).setAutoCancel(true)
mNotificationManager.createNotificationChannel(channel)//Notice this
mNotificationManager.notify(123, builder.build())
}
else {
//Create Notifcation for below Oreo
}
Does your Logcat say something like:
E/NotificationManager: notifyAsUser: tag=null, id=123, user=UserHandle{0}
Also have a look at your line:
val intent = Intent(context, Profile::class.java)
IF all else fails create a test Actvity with hello world.
And then make the line look like:
val intent = Intent(context, testActivity::class.java)
Remember to add the activity to your Manifest
The following line
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0);
should not have a semi colon. Kotin doesn't need this.
Is Profile your Class or System Class?
Try out this method and you can pass message and title dynamically :
private fun showNotification(title: String?, body: String?) {
val intent = Intent(this, Profile::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT)
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, notificationBuilder.build())
}