I have been trying to change the sound of the notification but it isn't changing at all.
It is using the default notification in all cases, even when I have assigned the channel.
Please check the codes below and let me know, where I am going wrong.
Created Notification Channel in Application class
class App : Application() {
override fun onCreate() {
super.onCreate()
createNotificationChannel()
}
private fun createNotificationChannel() {
val ordersChannelId = "Orders"
val orderSoundUri =
Uri.parse("android.resource://" + applicationContext + "/raw/ordernotification")
val attributes = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).build()
val VIBRATE_PATTERN = longArrayOf(0,400,800,600,800,800,800,1000)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val ordersChannel =
NotificationChannel(ordersChannelId, "Orders", NotificationManager.IMPORTANCE_HIGH)
ordersChannel.apply {
description = "This is Orders Channel"
setSound(orderSoundUri, attributes)
vibrationPattern = VIBRATE_PATTERN
importance = NotificationManager.IMPORTANCE_HIGH
}
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(ordersChannel)
}
}
Creating Notifications using FireBaseMessagingService
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.d("NotificationFire", "From: ${remoteMessage?.data}")
val contentIntent = Intent(applicationContext, OrderInDetailActivity::class.java)
val orderSoundUri = Uri.parse("android.resource://"+applicationContext+"/raw/ordernotification")
val attributes = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).build()
val VIBRATE_PATTERN = longArrayOf(0, 500)
val contentPendingIntent = PendingIntent.getActivity(
applicationContext,
0,
contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
remoteMessage?.data?.let {
Log.d("NotificationFire", "Message Notification Data: ${it}")
//Message Services handle notification
val notification = NotificationCompat.Builder(this, "Orders")
.setSmallIcon(R.drawable.biskit_logo)
.setContentTitle(remoteMessage.data.toString())
.setContentText(remoteMessage.data.toString())
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(orderSoundUri)
.setVibrate(VIBRATE_PATTERN)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setContentIntent(contentPendingIntent)
.build()
val notificationManager = NotificationManagerCompat.from(this)
Log.d("NotificationFire","Notification")
notificationManager.notify(1,notification)
}
This code is able to display notifications with the default sound only.
In your sound path you appended applicationContext. It will add some random value in your path. Instead you need to add the package name like this below.
Uri.parse("android.resource://"+context.getPackageName()+"/"+R.raw.FILE_NAME);//Here is FILE_NAME is the name of file that you want to play
Related
I have 3 parts of code that are not working on my application, here they are:
Main activity -
class MainActivity : AppCompatActivity() {
var CHANNEL_ID = "myChannel"
private var mAlarmManager : AlarmManager? = null
private fun createNotificationChannel() {
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
}
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mIntent = Intent(this, MyReceiver::class.java)
val mPendingIntent = PendingIntent.getBroadcast(this, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val mAlarmManager = this
.getSystemService(Context.ALARM_SERVICE) as AlarmManager
mAlarmManager.setRepeating(
AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
60000, mPendingIntent
)
Qinperation -
class Qinperation : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.qinsperational)
val back18 = findViewById<Button>(R.id.back18)
back18.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
And MyReceiver -
class MyReceiver : BroadcastReceiver() {
var CHANNEL_ID = "myChannel"
override fun onReceive(context: Context, intent: Intent) {
Toast.makeText(context,"This toast will be shown every X minutes", Toast.LENGTH_LONG).show()
Log.i("TAG","/////////////////// SHOW NOTIFICATION NOW //////////////////////")
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.orange)
.setLargeIcon(BitmapFactory.decodeResource(context.resources,R.mipmap.ic_launcher_round))
.setContentTitle("My notification")
.setContentText("Much longer text that cannot fit one line...")
.setStyle(
NotificationCompat.BigTextStyle()
.bigText("Much longer text that cannot fit one line...Much longer text that cannot fit one line..."))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
with(NotificationManagerCompat.from(context)) {
notify(12345, builder.build()) }
if (context !is Qinperation) return
val imageView = context.findViewById<View>(R.id.paininass) as ImageView
val quotes = arrayOf(R.drawable.i1, R.drawable.i2, R.drawable.i3, R.drawable.i5, R.drawable.i6, R.drawable.i7, R.drawable.i8, R.drawable.i9, R.drawable.i10, R.drawable.i11, R.drawable.i12)
val quote = quotes.random()
imageView.setImageResource(quote)
}
}
I want the receiver to run every set period (at the moment every minute), and then a notification to pop up and the image in the Qinperation activity to change to a randomized one. I know the receiver works due to the toast popping up successfully every minute. It then continues to say a notification cannot be posted to the notification channel "myChannel". After some research I concluded I needed to set up a channel that I thought I did in the main activity (using the android documentation), but it still doesn't work. It runs and just has that message pop up at the bottom. How would I successfully create this channel and run it so a notification pops up every set period of time?
As for the image view, I have the randomizer set up to run in the receiver and then based of the random image the image view to be set. It however stays blank throughout. Am I using the right command?
All help or tips are appreciated :)
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 am working on a parental control app which notify parent multiple times but when I try to create notification with a background service it generates only one 1.
Here is how I do it:
fun createNotification(parent_name: String, notificationText:String, id: Int){
val MchannelId = channelId+id.toString()
if (Build.VERSION.SDK_INT >= 26) {
val channel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel(
MchannelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT
)
} else {
TODO("VERSION.SDK_INT < O")
}
(getSystemService(NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(
channel
)
}
val notificationIntent = Intent(this, TabbedActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
id, notificationIntent, 0
)
val notification: Notification = NotificationCompat.Builder(this, "$MchannelId")
.setContentTitle("Hi $parent_name")
.setContentText(notificationText)
.setSmallIcon(R.drawable.icon_child)
//.setContentIntent(pendingIntent)
.build()
startForeground(random_number, notification)
}
My Full-Service Class:
const val TAG2 = "Child Service"
class ParentService: Service() {
val db = FirebaseFirestore.getInstance()
private val channelId = "Notification from Service"
var parent_name = userName
override fun onBind(intent: Intent?): IBinder? = null
//OnBind Function Implementation
init {
Log.d(TAG2, "Started Service!")
}
//onCreate Method Implementation
override fun onCreate() {
super.onCreate()
}
//OnStartCommand Override
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Thread{
while (true){
checkStatus()
Thread.sleep(PARENT_CHECK_TIME)
}
}.start()
return START_STICKY
}
private fun checkStatus() {
var listOfNames = ""
var i = 1
val calendar: Calendar = Calendar.getInstance()
var list = ArrayList<String>()
db.collection(LINKED_CHILDS)
.whereEqualTo(USER_PHONE, userPhone)
.get()
.addOnSuccessListener { documents ->
for (document in documents){
val startTime: Long = calendar.getTimeInMillis()
val diff = startTime - (document.data[ACTIVE_STATUS] as Long)
Log.d("TAG", "Time Difference : $diff")
Log.d("TAG", "${document.data[USER_NAME].toString()}")
if (diff> MAX_GAP_TIME){
Log.d("TAG", "Entered IFF")
list.add(document.data[USER_NAME].toString())
}
}
for (name in list){
listOfNames = listOfNames + "$i. Your child $name is not active\n"
i++
createNotification(parent_name, listOfNames, i)
Log.d("TAG Notification ID:", "ID: $i")
}
Log.d("TAG: ", "$listOfNames")
}
}
fun createNotification(parent_name: String, notificationText:String, id: Int){
val MchannelId = channelId+id.toString()
if (Build.VERSION.SDK_INT >= 26) {
val channel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel(
MchannelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT
)
} else {
TODO("VERSION.SDK_INT < O")
}
(getSystemService(NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(
channel
)
}
val notificationIntent = Intent(this, TabbedActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
id, notificationIntent, 0
)
val notification: Notification = NotificationCompat.Builder(this, "$MchannelId")
.setContentTitle("Hi $parent_name")
.setContentText(notificationText)
.setSmallIcon(R.drawable.icon_child)
//.setContentIntent(pendingIntent)
.build()
startForeground(id, notification)
}
}
Kinldy let me know how I can create multiple Notifications using this background service. Thank You so much in advance!
Kinldy let me know how I can create multiple Notifications using this background service. Thank You so much in advance!
Kinldy let me know how I can create multiple Notifications using this background service. Thank You so much in advance!
If you create a non-persistent notification, it will show your notifications. The permanent notification will be used for your service to run in the background.
#RequiresApi(Build.VERSION_CODES.O)
private fun createNotification() {
val intent = Intent(this, TabbedActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent =
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.icon_child)
.setContentTitle("Hi $parent_name")
.setContentText(notificationText)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
with(NotificationManagerCompat.from(this)) {
notify(notifManagerId, notification.build())
notifManagerId++
}
parmanentNotification()
}
this is a permanent notification will not be lost and destroyed will keep the service running permanently
private fun parmanentNotification() {
val notification=NotificationCompat.Builder(this,channelId)
.setSmallIcon(R.drawable.icon_child)
.setContentTitle("Hi $parent_name")
.setContentText("Application service running in the background")
.build()
startForeground(1,notification)
}
you aren't creating a common Notification in this scenario, you are running a Service, which must have a foreground representation on screen. So Activity visible or sticked, fixed Notification, and you are showing it
Now you can have much Notifications using similar code, but don't show them using startForeground, instead use NotificationManager, preferably compat version
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(uniqueId, notification);
or just like you are using it already when creating channel inside if: (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).notify(...)
foreground-related Notification is sticky and lives as long as Service works in background, they are "tied". other Notifications may be configured to be sticky or swipeable, also should be posted on some own Channel (per child? per action?). Note that if you show yet another sticky Notification then you have to release it by own through code, just killing Service won't dismiss it as it does with foreground-related Notification
some DOC in here, read carefully, all answers are there
I am trying to integrate Firebase Cloud Messages into my app. The code I used in the showNotification function is from the Android User Interface Samples. I tried it in the Activity and it worked but am not sure why it's not working in the service. The println is showing the function is getting called and values are coming as expected. Is there anything am missing from the function?
class MessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (remoteMessage.data.isNotEmpty()) {
val message = Gson().fromJson(remoteMessage.data.toString(), Message.Res::class.java).payload!!
showNotification(message.title, message.body, message.count)
}
}
private fun showNotification(title: String?, body: String?, count: Int = 0) {
println("_print::showNotification(title:$title, body:$body, count:$count)")
val mainPendingIntent = PendingIntent.getActivity(
applicationContext, BuildConfig.REQUEST_CODE,
Intent(applicationContext, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)
val builder = NotificationCompat.Builder(applicationContext, "channel_email_1")
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_round))
.setContentIntent(mainPendingIntent)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setColor(ContextCompat.getColor(applicationContext, R.color.primary))
.setSubText(if (count > 1) "You have $count pending notifications" else title)
.setCategory(Notification.CATEGORY_EMAIL)
.setPriority(1)
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
NotificationManagerCompat.from(applicationContext)
.notify(BuildConfig.NOTIFICATION_ID, builder.build())
}
}
Instead of
val mainPendingIntent = PendingIntent.getActivity(
applicationContext, BuildConfig.REQUEST_CODE,
Intent(applicationContext, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)
NotificationManagerCompat.from(applicationContext)
.notify(BuildConfig.NOTIFICATION_ID, builder.build())
I use:
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Since android Oreo notification channel is needed.
setupChannels(notificationManager, builder)
// Create pending intent, mention the Activity which needs to be triggered
// when user clicks on notification.
val notificationId = Random.nextInt()
navigateToScreen(builder, notificationId)
val notification = builder.build()
notificationManager.notify(notificationId, notification)
}
private fun setupChannels(notificationManager: NotificationManager,
builder: NotificationCompat.Builder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "channel_email_1"
val channel = NotificationChannel(channelId, "title",
NotificationManager.IMPORTANCE_DEFAULT).apply {
description = "body"
// Add other settings.
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
canShowBadge()
setShowBadge(true)
}
notificationManager.createNotificationChannel(channel)
builder.setChannelId(channelId)
}
}
private fun navigateToScreen(builder: NotificationCompat.Builder,
notificationId: Int) {
val intent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, notificationId, intent,
PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(pendingIntent)
}
I'm firing a notification after posting data to fcm , when i receive data back the notification is shown no problem but it has no sound no vibration even though i made sure that my sound and vibraton are enable in my phone , i'm not sure if i'm doing something wrong , please help me figure it out , thank you .
This is my application class code where i set the notification channel for oreo +
override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())
setUpNotification()
}
private fun setUpNotification(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val notificationChannel = NotificationChannel(
getString(R.string.channelid),getString(R.string.channelstring),
NotificationManager.IMPORTANCE_DEFAULT)
val ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
notificationChannel.description = "Notifications"
notificationChannel.enableLights(true)
notificationChannel.enableVibration(true)
notificationChannel.lightColor = Color.BLUE
notificationChannel.setSound(ringtone,audioAttributes)
val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as
NotificationManager
notificationManager.createNotificationChannel(notificationChannel)
}
}
This is my notification code
private fun FireNotification(title : String, body : String, isVibrationEnabled : Boolean,
notificationchannelid : String){
val intent = Intent(applicationContext,MainActivity::class.java)
val taskBuilder = TaskStackBuilder.create(applicationContext).run {
addNextIntentWithParentStack(intent)
getPendingIntent(1,PendingIntent.FLAG_UPDATE_CURRENT)
}
val vibratePattern = longArrayOf(1000L, 1000L, 1000L, 1000L)
val notification = NotificationCompat.Builder(applicationContext, notificationchannelid)
notification.apply {
setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
setContentTitle(title)
setContentText(body)
setContentIntent(taskBuilder)
setSmallIcon(R.drawable.ic_baseline_notifications_active_24)
addAction(R.drawable.default_icon,"Snooze",taskBuilder)
addAction(R.drawable.default_icon,"Action",taskBuilder)
priority = NotificationCompat.PRIORITY_HIGH
if(isVibrationEnabled){
notification.setVibrate(vibratePattern)
}
}
NotificationManagerCompat.from(applicationContext).notify(counter++,notification.build())
}
The solution to my issue was to simply set default sound as following
setDefaults(NotificationCompat.DEFAULT_SOUND)