i have a problem with chronometer in Notification. I want to get current tick if notification clicked and parsing value to MainActivity using Intent. i have no idea about this case, i was try and result is always 0.
here my notification code with RemoteView
fun showNotification(context: Context, value: Long, state: Int) {
val isPaused = state == Constant.MusicState.PAUSED
val intentTimer = Intent(context, MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val bundle = Bundle()
bundle.putLong(Constant.Key.CURRENT_TIME, value)
val pendingIntentButtonPause = PendingIntent.getActivity(context, 100, intentTimer, PendingIntent.FLAG_UPDATE_CURRENT, bundle)
val remoteViews = RemoteViews(context.packageName, R.layout.item_notification)
remoteViews.setChronometer(R.id.chronometer, value, null, !isPaused)
remoteViews.setOnClickPendingIntent(R.id.buttonPause, pendingIntentButtonPause)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val builder = NotificationCompat.Builder(context, "199102")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentText("Test")
.setAutoCancel(false)
.setOngoing(true)
.setOnlyAlertOnce(true)
.setUsesChronometer(true)
.setContentIntent(PendingIntent.getActivity(context, 10, intentTimer, PendingIntent.FLAG_UPDATE_CURRENT))
remoteViews
builder.setCustomContentView(remoteViews)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
checkNotificationChannel(context, "199102")
}
notificationManager.notify(199102, builder.build())
}
And this when i call function showNotification()
this.binding.apply {
this#MainActivity.musicState = Constant.MusicState.IDLE
this.chronometer.setOnChronometerTickListener {
try {
if (it.text == "00.10" || it.text == "00:10") {
Chronotification.showNotification(this#MainActivity, it.base, this#MainActivity.musicState)
this#MainActivity.musicState = Constant.MusicState.IDLE
this#MainActivity.binding.buttonStart.text = "Start"
it.text = "00.00"
it.stop()
}
}catch (e : Exception) {
e.printStackTrace()
}
}
GeneralHelper.makeClickable(this#MainActivity, this.buttonStart)
}
Thanks, any help or suggestion will be appreciate.
Related
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.
When I swipe up after the local notification comes, the application notifications don't appear on the screen for a while. What could be the reason for this? I've read something that when heads up notifications are swiped up, it sends a warning to the system to prevent heads up notifications for a certain period of time, but how can I prevent this? I don't have any problems getting notifications in my app other than that.
fun getChatChannels(): MutableList<NotificationChannel> {
val chatChannels = mutableListOf<NotificationChannel>()
val chatChannel = NotificationChannel(
IM_CHANNEL_ID,
Application.getString(R.string.chat_channel_name),
NotificationManager.IMPORTANCE_HIGH
)
chatChannel.setShowBadge(false)
chatChannel.group = MESSAGE_GROUP_ID
chatChannels.add(chatChannel)
return chatChannels }
private fun getChannelList(): MutableList<NotificationChannel> {
val channelList = mutableListOf<NotificationChannel>()
channelList.addAll(getChatChannels())
return channelList
}
fun createGroupsAndChannels() {
// 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 notificationManager =
Application.instance.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannelGroups(getGroupList())
notificationManager.createNotificationChannels(getChannelList())
}
Log.d(TAG, "Channels and groups created")
}
fun showChatNotification(destinationAddress: String, messageId: String, message: String) {
ThreadManager.createUITask {
val name = if (domainContact != null) {
"${domainContact.firstName} ${domainContact.lastName}"
} else {
destinationAddress
}
val notificationIntent = Intent(Application.instance, MainActivity::class.java)
notificationIntent.putExtra(
Application.getString(R.string.key_conversation_participant),
destinationAddress
)
notificationIntent.flags = Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
val pendingIntent = PendingIntent.getActivity(
Application.instance,
destinationAddress.hashCode(),
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
val notificationId = UUID.randomUUID().hashCode()
val builder = NotificationCompat.Builder(Application.instance, IM_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification_message)
.setColor(ContextCompat.getColor(Application.instance, R.color.colorPrimary))
.setContentTitle(name)
.setContentText(message)
.setStyle(
NotificationCompat.BigTextStyle() // Expandable-Collapsible notification
.bigText(message)
)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(pendingIntent)
.setVisibility(VISIBILITY_PUBLIC)
.setAutoCancel(true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.addAction(getChatNotificationReplyAction(destinationAddress, notificationId, messageId))
}
chatNotifications.add(mapOf(destinationAddress to notificationId))
createNotifications(builder, notificationId)
Log.d(TAG, "Chat notification created")
}
private fun createNotifications(builder: NotificationCompat.Builder, notificationId: Int) {
with(NotificationManagerCompat.from(Application.instance)) {
notify(notificationId, builder.build())
}
}
I am new to android studio. I was trying to create a notification when user click on a button embedded in recyclerView
user has to give time in Hours and Minutes only. I take user input as a string. And input is stored in SQLite database.
notifyMeUpdate function is working fine but Toast in Receiver class is not shown(I think Receiver class is not triggered).
Please ignore typo
Here is my code:
class User{
var id = 0
var time = ""
var amp = ""
var text = ""
var notifyMe = false
}
My User Class:
fun notifyMeUpdate(user: User) {
alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
var hour = 0
var min = 0
for(i in 0 until user.time.length) {
if (user.time[i] == ':'){
var str = user.time.subSequence(0, i).toString()
var minStr = user.time.subSequence(i+1, user.time.length).toString()
if(user.amp == "AM"){
hour = str.toInt()
min = minStr.toInt()
}
else{
hour = str.toInt() + 12
min = minStr.toInt()
}
}
}
val cur_cal: Calendar = GregorianCalendar()
cur_cal.timeInMillis = System.currentTimeMillis()
val cal: Calendar = GregorianCalendar()
cal.add(Calendar.DAY_OF_YEAR, cur_cal[Calendar.DAY_OF_YEAR])
cal[Calendar.HOUR_OF_DAY] = hour
cal[Calendar.MINUTE] = min
cal[Calendar.SECOND] = 0
cal[Calendar.MILLISECOND] = cur_cal[Calendar.MILLISECOND]
cal[Calendar.DATE] = cur_cal[Calendar.DATE]
cal[Calendar.MONTH] = cur_cal[Calendar.MONTH]
val intent = Intent(context, Receiever::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.timeInMillis, pendingIntent)
}
And here is my Receiever class
class Receiever: BroadcastReceiver(){
lateinit var notificationManager: NotificationManager
lateinit var notificationChannel: NotificationChannel
lateinit var builder: Notification.Builder
private var channelId = "package com.example.recyclerpractise"
private var description = "Text Notification"
override fun onReceive(context: Context?, intent: Intent?){
Toast.makeText(context, "Triggred", Toast.LENGTH_SHORT).show()
val intent = Intent(context, LauncherActivity::class.java)
val pintent = PendingIntent.getActivity(context, 0 , intent, PendingIntent.FLAG_UPDATE_CURRENT)
if (context != null) {
notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel =
NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(true)
notificationManager.createNotificationChannel(notificationChannel)
if (context != null) {
builder = Notification.Builder(context, channelId)
.setContentTitle("Hello Moto")
.setContentText("Test Notification")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.ic_launcher_foreground))
.setContentIntent(pintent)
}
else{
builder = Notification.Builder(context)
.setContentTitle("Hello Moto")
.setContentText("Test Notification")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(context?.resources, R.drawable.ic_launcher_foreground))
.setContentIntent(pintent)
}
notificationManager.notify(19867, builder.build())
}
}
}
Here is my onBindViewHolder of recycler list
override fun onBindViewHolder(p0: ViewHolder, p1: Int) {
val user: User = userList[p1]
p0.time.text = user.time
p0.text.text = user.text
p0.img.setOnClickListener{
val popup = PopupMenu(activity, p0.img)
popup.inflate(R.menu.schedulemenu)
popup.setOnMenuItemClickListener {
when(it.itemId){
R.id.menu_delete->{
activity.dbHelper.deleteData(userList[p1].id.toLong())
activity.refreshList()
}
R.id.menu_update->{
activity.updateUser(userList[p1])
}
R.id.notify->{
activity.notifyMeUpdate(userList[p1])
}
}
true
}
popup.show()
}
}
Thanks for Help
Thanks for all who tried. After several hours of debugging. I found that I did a very stupid mistake that haven't register my receiver in manifest file now it's working fine.
I have tried using "0" notification id and as well as unique notification id.
Also used setGroup() like below. It still generates a new notification every time. I want to merge the notification body and set the title as common.
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
super.onMessageReceived(remoteMessage)
remoteMessage?.let {
sendNotification(it.data["alert"])
}
}
private fun sendNotification(messageBody: String?) {
val channelId = "${this.packageName}-${this.getString(R.string.app_name)}"
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val builder = NotificationCompat.Builder(this, channelId).apply {
setDefaults(Notification.DEFAULT_ALL)
setSmallIcon(if (Build.VERSION.SDK_INT >= 21) R.mipmap.ic_launcher else R.mipmap.ic_launcher_round)
setContentTitle(getString(R.string.app_name))
setContentText(messageBody)
setDefaults(NotificationCompat.DEFAULT_SOUND or NotificationCompat.DEFAULT_VIBRATE or NotificationCompat.DEFAULT_LIGHTS)
setStyle(NotificationCompat.BigTextStyle().bigText(messageBody))
priority = NotificationCompat.PRIORITY_DEFAULT
setAutoCancel(true)
setSound(defaultSoundUri)
setGroup(getString(R.string.app_name))
setGroupSummary(true)
}
val manager = getSystemService(NOTIFICATION_SERVICE) as? NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, getString(R.string.default_channel_name), NotificationManager.IMPORTANCE_HIGH)
manager?.createNotificationChannel(channel)
}
val intent = Intent(this, DashboardFlowActivity::class.java)
intent.putExtra(DashboardFlowActivity.ISFROMNOTIFICATION, true)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
builder.setContentIntent(pendingIntent)
//manager?.cancelAll()
manager?.notify(this.getString(R.string.app_name), getID(), builder.build())
}
}
private val c = AtomicInteger(0)
private fun getID(): Int {
return c.incrementAndGet()
}
Anything I am doing wrong here? Also, I have gone through this answer. setgroup() in notification not working
Finally I got solution for this question using https://stackoverflow.com/a/41114135/6021469, https://www.developer.com/ws/android/creating-bundled-notifications-with-android.html
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
super.onMessageReceived(remoteMessage)
remoteMessage?.let {
sendNotification(it.data["alert"])
}
}
private fun sendNotification(messageBody: String?) {
val channelId = "${this.packageName}-${this.getString(R.string.app_name)}"
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val builder = NotificationCompat.Builder(this, channelId).apply {
setDefaults(Notification.DEFAULT_ALL)
setSmallIcon(if (Build.VERSION.SDK_INT >= 21) R.mipmap.ic_launcher else R.mipmap.ic_launcher_round)
setContentTitle(getString(R.string.app_name))
setShowWhen(true)
setContentText(messageBody)
setDefaults(NotificationCompat.DEFAULT_SOUND or NotificationCompat.DEFAULT_VIBRATE or NotificationCompat.DEFAULT_LIGHTS)
setStyle(NotificationCompat.BigTextStyle().bigText(messageBody))
priority = NotificationCompat.PRIORITY_DEFAULT
setAutoCancel(true)
setShowWhen(true)
setSound(defaultSoundUri)
setGroup(getString(R.string.app_name))
}
val builderSummary = NotificationCompat.Builder(this, channelId).apply {
setDefaults(Notification.DEFAULT_ALL)
setSmallIcon(if (Build.VERSION.SDK_INT >= 21) R.mipmap.ic_launcher else R.mipmap.ic_launcher_round)
setContentTitle(getString(R.string.app_name))
setShowWhen(true)
setContentText(messageBody)
setDefaults(NotificationCompat.DEFAULT_SOUND or NotificationCompat.DEFAULT_VIBRATE or NotificationCompat.DEFAULT_LIGHTS)
setStyle(NotificationCompat.BigTextStyle().bigText(messageBody))
priority = NotificationCompat.PRIORITY_DEFAULT
setAutoCancel(true)
setShowWhen(true)
setSound(defaultSoundUri)
setGroup(getString(R.string.app_name))
setGroupSummary(true)
}
val manager = getSystemService(NOTIFICATION_SERVICE) as? NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, getString(R.string.default_channel_name), NotificationManager.IMPORTANCE_HIGH)
manager?.createNotificationChannel(channel)
}
val intent = Intent(this, DashboardFlowActivity::class.java)
intent.putExtra(DashboardFlowActivity.ISFROMNOTIFICATION, true)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
builder.setContentIntent(pendingIntent)
manager?.notify(this.getString(R.string.app_name), getID(), builder.build())
manager?.notify(this.getString(R.string.app_name), 0, builderSummary.build())
}
}
private val c = AtomicInteger(0)
private fun getID(): Int {
return c.incrementAndGet()
}
I have checked in my onMessageReceived method whether the app is in foreground or background and I only show the notification when app is in background or the app is not visible, the notification is working fine but in both cases the notification sound gets played I don't want the notification sound to get played when the app is in foreground. Here is the code for onMessageReceived
override fun onMessageReceived(p0: RemoteMessage?) {
var sh = SharedPreferencesHelper.getInstance(applicationContext, Constants.PREFS)
if (sh.getInt(Constants.LOGIN_STATE)!=Constants.STATE_COMPLETED) {
return
}
var data = p0?.data
val send = Intent(Constants.NOTIFICATION_RECEIVED)
// You can also include some extra data.
send.putExtra(Constants.COUNT, data?.get(Constants.COUNT))
LocalBroadcastManager.getInstance(this).sendBroadcast(send)
var title = p0?.data?.get("title")
var message = p0?.data?.get("message")
var intent: Intent? = null
if (data?.get("status") == "follow") {
intent = Intent(this, ViewProfileActivity::class.java)
intent.putExtra(Constants.PROFILE_ID, data?.get("userid"))
intent.putExtra(Constants.SEEN_ID, data?.get("id"))
intent.putExtra(Constants.SEEN, "")
} else if (data?.get("status") == "reply" || data?.get("status") == "direct reply") {
val notify = Intent(Constants.REPLIES_AVAILABLE)
// You can also include some extra data.
LocalBroadcastManager.getInstance(this).sendBroadcast(notify)
intent = Intent(this, NowwtReplyActivity::class.java)
intent.putExtra(Constants.NOWWT_ID, data?.get("nowwtid"))
intent.putExtra(Constants.SEEN_ID, data?.get("id"))
intent.putExtra(Constants.SEEN, "")
} else if (data?.get("status") == "direct nowwt") {
intent = Intent(this, NowwtReplyActivity::class.java)
intent.putExtra(Constants.DIRECT_NOWWT, true)
intent.putExtra(Constants.NOWWT_ID, data?.get("nowwtid"))
intent.putExtra(Constants.SEEN_ID, data?.get("id"))
intent.putExtra(Constants.SEEN, "")
} else if(data?.get("status") == "people"){
intent = Intent(this, DashboardActivity::class.java)
intent.putExtra(Constants.NAVIGATE_PEOPLE,true)
} else if (data?.get("status") == "simple") {
intent = Intent(this, SplashActivity::class.java)
}
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
try {
if (FireNotificationUtils.isAppIsInBackground(applicationContext)) {
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
val notificationBuilder = NotificationCompat.Builder(applicationContext, "yoyo")
notificationBuilder.setContentTitle(title)
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher_round_nowwt)
notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(applicationContext.resources,
R.drawable.logo_))
notificationBuilder.setContentText(message)
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher)
notificationBuilder.setDefaults(0)
notificationBuilder.priority = NotificationCompat.PRIORITY_MAX
notificationBuilder.setAutoCancel(true)
// notificationBuilder.setSound(defaultSoundUri)
notificationBuilder.setContentIntent(pendingIntent)
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val CHANNEL_ID = "my_channel_01"// The id of the channel.
val name = getString(R.string.channel_name)// The user-visible name of the channel.
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(CHANNEL_ID, name, importance)
notificationBuilder.setChannelId(CHANNEL_ID)
notificationManager.createNotificationChannel(mChannel)
}
notificationManager.notify(0, notificationBuilder.build())
super.onMessageReceived(p0)
}
} catch (e: Exception) {
}
}