push notification enable and disable by using switch - android

I'm using firebase push notification(FCM).. and I want to enable and disable notifications using a switch button.
For that I have shared preferences to enable and disable notifications but it seems my logic is not at all working.
It doesn't make any difference if the switch is turn on or off. I am still receiving notifications.
I need help thanks.
activity:--
val sharedPreferences = getSharedPreferences("myname", MODE_PRIVATE)
simpleSwitch.setChecked(sharedPreferences.getBoolean("SWITCH_PARTIDOS_STATE", false))
simpleSwitch.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
sharedPreferences.edit().putBoolean("SWITCH_PARTIDOS_STATE", isChecked).commit()
if (isChecked) {
// FirebaseMessaging.getInstance().subscribeToTopic("Partidos")
Toast.makeText(applicationContext, "Activado Correctamente",
Toast.LENGTH_LONG).show()
} else {
// FirebaseMessaging.getInstance().unsubscribeFromTopic("Partidos")
Toast.makeText(applicationContext, "Desactivado Correctamente",
Toast.LENGTH_LONG).show()
}
PreferenceHelper.prefernceHelperInstace.setBoolean(applicationContext, Constants.MessageNotificationKeys.ENABLE_NOTIFICATION, true);
})
firebasemessagingservice:---
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
if (PreferenceHelper.prefernceHelperInstace.getBoolean(getApplicationContext(),
Constants.MessageNotificationKeys.ENABLE_NOTIFICATION, true)
) {
Log.d("msg", "onMessageReceived: " + remoteMessage.notification?.body)
val intent = Intent(this, HomeActivity::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 = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(remoteMessage.getNotification()?.getTitle())
.setContentText(remoteMessage.getNotification()?.getBody()).setAutoCancel(true)
.setContentIntent(pendingIntent)
.setStyle(NotificationCompat.BigTextStyle()
.bigText(remoteMessage.getNotification()?.getBody()))
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Default channel",
NotificationManager.IMPORTANCE_DEFAULT
)
manager!!.createNotificationChannel(channel)
}
manager!!.notify(0, builder.build())
}
else {
Log.e("TAG", "ReactFireBaseMessagingService: Notifications Are Disabled by User");
}
}
preferencehelper:--
class PreferenceHelper private constructor() {
fun setBoolean(appContext: Context?, key: String?, value: Boolean?) {
PreferenceManager.getDefaultSharedPreferences(appContext).edit()
.putBoolean(key, value!!).apply()
}
fun getBoolean(
appContext: Context?, key: String?,
defaultValue: Boolean?
): Boolean {
return PreferenceManager.getDefaultSharedPreferences(appContext)
.getBoolean(key, defaultValue!!)
}
fun getInteger(appContext: Context?, key: String?, defaultValue: Int): Int {
return PreferenceManager.getDefaultSharedPreferences(appContext)
.getInt(key, defaultValue)
}
companion object {
val prefernceHelperInstace = PreferenceHelper()
}
}
using the method of topic(need help ):---------
val sharedPreferences = getSharedPreferences("myname", MODE_PRIVATE)
simpleSwitch.setChecked(sharedPreferences.getBoolean("SWITCH_STATE", false))
simpleSwitch.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
sharedPreferences.edit().putBoolean("SWITCH_STATE", isChecked).commit()
if (isChecked) {
// FirebaseMessaging.getInstance().subscribeToTopic("Partidos")
FirebaseMessaging.getInstance().subscribeToTopic("main_notification");
Toast.makeText(applicationContext, "enabled notification",
Toast.LENGTH_LONG).show()
}
else {
FirebaseMessaging.getInstance().unsubscribeFromTopic("main_notification");
Toast.makeText(applicationContext, "disabled notification",
Toast.LENGTH_LONG).show()
}
})
The problem of this code is it doesn't worked at first(it receives notification at on off both) after switching on off (switching buttons) it works(when on receives notification and off doesn't receive).

FirebaseMessagingService runs in the background even when the app's not in the foreground so you won't be able to get the preferences using applicationContext.
You should use Topic messaging - https://firebase.google.com/docs/cloud-messaging/android/topic-messaging
Use this in your switch's change listener:
To enable push notifications -
FirebaseMessaging.getInstance().subscribeToTopic("your_topic");
To disable push notifications -
FirebaseMessaging.getInstance().unsubscribeFromTopic("your_topic");
This way you will notify Firebase that you don't want to get notifications about a particular topic.

Related

How to Play a sound when a critical notification received in FirebaseMessagingService

I developing an application that receives a push notification when there is an emergency alert and needs to play a sound even when the device is in silent mode.
the sound aslo need to be custom.
I tried all kinds of ways without any success.
How do you do it on Android?
#AndroidEntryPoint
class AlertFirebaseMessagingService : FirebaseMessagingService() {
companion object {
private const val CHANNEL_ID = "HEADS_UP_NOTIFICATION"
}
#Inject
lateinit var dbRepository : DBRepositoryImpl
#Inject
lateinit var networkRepository : RepositoryImpl
override fun onNewToken(token : String) {
super.onNewToken(token)
Log.d("hofitTest", token)
AppSharedPreferences.saveToken(token)
if (AppSharedPreferences.getPhoneNumber().isEmpty().not()) {
sendRegistrationToServer(token)
}
}
// The method is called every time it receives a notification from Firebase.
#RequiresApi(Build.VERSION_CODES.O)
override fun onMessageReceived(
remoteMessage : RemoteMessage) {
Log.d("hofitTest", "From: ${remoteMessage.from}")
if (remoteMessage.data.isNullOrEmpty().not()) {
val type = remoteMessage.data["type"] ?: "1"
sendNotification(
remoteMessage.data["title"] ?: "", remoteMessage.data["body"] ?: "", type)
Log.d("hofitTest", "Message data payload: ${remoteMessage.data}")
}
// } else if(remoteMessage.notification != null){
// //TODO change def 1
// sendNotification(remoteMessage.notification?.title ?: "", remoteMessage.notification?.body ?: "", "1")
// }
super.onMessageReceived(remoteMessage)
}
private fun sendNotification(title : String, body : String, type : String) {
createChannel()
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
notification.setContentTitle(title)
notification.setContentText(body)
notification.priority = NotificationCompat.PRIORITY_HIGH
val intent = Intent(this, SplashActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
notification.setSmallIcon(R.drawable.icon_lifeguard_orange_rounded)
notification.color = ContextCompat.getColor(this, R.color.orange)
notification.setContentIntent(pendingIntent)
notification.setAutoCancel(true)
NotificationManagerCompat.from(this).notify(Random.nextInt(), notification.build())
CoroutineScope(Dispatchers.IO).launch {
dbRepository.saveEvent(
NotificationAlert(name = title ?: "", body = body ?: "", type = type, date = Date().time))
a()
}
}
private fun createChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID, "Heads Up Notification", NotificationManager.IMPORTANCE_HIGH)
channel.enableLights(true)
channel.enableVibration(true)
channel.lightColor = Color.BLUE
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
}
}
}
use RingtoneManager - this not works in silent mode
try {
val notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
val r = RingtoneManager.getRingtone(LifeguardApplication.context, notification)
r.play()
} catch (e : Exception) {
e.printStackTrace()
}

How to create multiple notifications in Kotlin in foreground service

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

Check payload of notification in onMessageReceived()

I am trying to send a data notification to my app and then use the data therein to open a fragment:
override fun onMessageReceived(message: RemoteMessage) {
Timber.d("onMessageReceived")
try {
val data = message.data
if (data != null && (data.containsKey(KEY_MSG) || data.containsKey(KEY_URL))) {
val url = data[KEY_URL]
if (!url.isNullOrEmpty()) {
val clickAction = message.notification?.clickAction
val intent = Intent(clickAction)
intent.putExtra(KEY_URL, url).putUseStateExtra(UseState(UseState.COME_FROM_NOTIFICATION)).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
} else {
sendNotification(data)
}
}
} catch (e: Throwable) {
Timber.e(e, "We didn't send the notification because ${e.message}")
}
}
I then after onMessageReceived() is called I build the notification and send it with the following methods. One to parse out the payload:
private fun sendNotification(data: Map<String, String>) {
Timber.d("Notification sent: $data type: ${data[KEY_CLOUD8_TYPE]}")
if (Interactors.preferences.notificationsEnabled == true) {
Timber.d(data.toString())
val title = data[KEY_TITLE]
val msg = data[KEY_MSG]
var cloud8Type = data[KEY_CLOUD8_TYPE] ?: ""
var notificationType = data[NOTIFICATION_TYPE] ?: ""
val campaignId = (data[KEY_CAMPAIGN_ID] ?: "0")
val url = data[KEY_URL]
if (!url.isNullOrBlank()) {
cloud8Type = Cloud8Type.Link
}
sendNotification(title, msg, cloud8Type, notificationType, campaignId, url)
}
}
One to build the notification:
private fun sendNotification(title: String?, message: String?, cloud8Type: String, notificationType: String, offerId: String, url: String?) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "Main"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(channelId, "My Notifications", NotificationManager.IMPORTANCE_HIGH)
// Configure the notification channel.
notificationChannel.description = "Channel description"
notificationChannel.enableVibration(true)
notificationManager.createNotificationChannel(notificationChannel)
}
val pendingIntent = getNotificationIntent(cloud8Type, notificationType, offerId, url)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
notificationBuilder.setSmallIcon(R.drawable.ic_notification)
notificationBuilder.setContentTitle(title)
notificationBuilder.setContentText(message)
notificationBuilder.setAutoCancel(true)
notificationBuilder.setSound(defaultSoundUri)
notificationBuilder.setContentIntent(pendingIntent)
notificationManager.notify(0, notificationBuilder.build())
}
And two to use the content of the payload to build an intent:
private fun getNotificationIntent(cloud8Type: String, notificationType: String, offerId: String, url: String?): PendingIntent {
Timber.d("Notification type: $cloud8Type}")
val useState = UseState(UseState.COME_FROM_NOTIFICATION)
val intent = getNotificationIntent(this, cloud8Type, notificationType, useState, offerId, url = url)
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
internal fun getNotificationIntent(
context: Context,
cloud8Type: String?,
notificationType: String,
useState: UseState,
offerId: String?,
url: String?
): Intent {
var intent = Intent()
when (cloud8Type) {
Cloud8Type.NewOffer, Cloud8Type.NewChallengeOffer, Cloud8Type.Link ->
intent = StartActivity.newInstance(context, useState, offerId, url)
Cloud8Type.DailyEarning, Cloud8Type.YouDidIt, Cloud8Type.FundsTransfered, Cloud8Type.OfferPayment, Cloud8Type.OfferDonation -> {
intent = if (Interactors.preferences.the8CloudSdkInfo.showPayoutTab) {
openSponsorTree(context, useState, ASponsorTree.TAB_PAYOUT, null)
} else {
APayoutMain.newIntent(context)
}
}
Cloud8Type.NewOffers ->
intent = openSponsorTree(context, useState, ASponsorTree.TAB_FEED, null)
else -> {
when (notificationType) {
NotificationType.Payment -> intent = openSponsorTree(context, useState, ASponsorTree.TAB_PAYOUT, null)
}
}
}
return intent
}
I'm trying to debug the payload being received when the notification comes, but none of my log statements are showing up when the app is closed. Is there any way to see what is coming back with the RemoteMessage in onMessageReceived()? Is there anyting else I should know about how to accomplish what I want to accomplish?
I added the "notification" attribute to the payload and gave it a click_action, and then intercepted it in my start activity.
Please don't send your payload in the notification attribute. It will only hit when the app is in the foreground state. For getting notification also while in background state you have to send your payload into data attribute, not notification.
Example :
{
"condition": " Better now",
"priority" : "normal",
"time_to_live" : 0,,
"data" : {
"id" : 1,
"text" : "text is here!",
"link" : "www.gmail.com"
}
}

Handle Push Notification in Kotlin

i am using Kotlin Navigation component architecture for my chat app, and i am using Firebase Messaging service to integrate push notification, my requirement is to hide or disable the notifications when i am on User chat screen.Please let me know, how can i achieve this.
this is my code of displaying notification
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
Log.d(TAG, "From: ${remoteMessage?.from}")
remoteMessage?.data?.let {
Log.d(TAG, "data payload: " + remoteMessage.data.toString())
val params =remoteMessage.data.get("body")
val objects = JSONObject(params)
Log.e("JSON OBJECT", objects.toString())
val title = remoteMessage.data.get("title").toString()
sendNotification(messageBody,title, applicationContext)
} }
my notification class is:
fun NotificationManager.sendNotification(messageBody: String, title: String, applicationContext: Context) {
notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// TODO: Step 1.12 create PendingIntent
if(title.equals("Ride Request")) {
fragmentId = R.id.notificationFragment
}
else if(title.equals("Ride Accepted")) {
fragmentId = R.id.inboxFragment
}
else if(title.equals("New Message")) {
fragmentId = R.id.inboxFragment
}
// ---------- creating navgraph intent to open specific fragment ------------
var contentPendingIntent = NavDeepLinkBuilder(applicationContext)
.setComponentName(HomeActivity::class.java)
.setGraph(R.navigation.home_bottom_navigation)
.setDestination(fragmentId)
.setArguments(bundle)
.createPendingIntent()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = NotificationChannel(channel_id, description,
NotificationManager.IMPORTANCE_HIGH)
notificationChannel.enableLights(true)
notificationChannel.lightColor = R.color.colorPrimary
notificationChannel.enableVibration(true)
notificationManager.createNotificationChannel(notificationChannel)
builder = NotificationCompat.Builder(applicationContext, channel_id)
.setSmallIcon(R.drawable.icon_car)
.setContentTitle(applicationContext.getString(R.string.app_name))
.setContentText(messageBody)
.setContentIntent(contentPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
}else {
builder = NotificationCompat.Builder(applicationContext,
applicationContext.getString(R.string.app_name))
.setSmallIcon(R.drawable.icon_car)
.setContentTitle(applicationContext.getString(R.string.app_name))
.setContentText(messageBody)
.setContentIntent(contentPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
}
notify(NOTIFICATION_ID, builder.build())
}
I don't if this is the perfect but you can try it as well
If the user is in chat screen you can create a sharedPref and set value of the variable to true (that the user is in chat screen)
So in the onMessageReceived() check it the value of the sharedPref is true (which mean the user is in chat screen)
If it's true then don't send notifications if false send notification
To set the sharedPref value
In the onResume of that chat activity set to true
In the onPause set to false
try this
class InboxFragment : Fragment() {
companion object {
var userId: String? = null
}
override fun onStart() {
userId = navArgs.userId
}
override fun onStop() {
userId = null
}
}
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
...
if (InboxFragment.userId != remoteMessage.data.get("userId"))
sendNotification(messageBody, title, applicationContext)
}
}

"<App> is having trouble with Google Play Services. Please try again" while usiing Google NearBy Messages API

While using google NearBy Messages API I am getting error " is having trouble with Google Play Services. Please try again"
Please guide me for this issue.
Below is import for Google Messaging API
implementation 'com.google.android.gms:play-services-nearby:17.0.0'
Here is how I am subscribing using code
val options = SubscribeOptions.Builder()
.setStrategy(Strategy.BLE_ONLY)
.build()
Nearby.getMessagesClient(
this, MessagesOptions.Builder()
.setPermissions(NearbyPermissions.BLE)
.build())
Nearby.getMessagesClient(this).subscribe(getPendingIntent(), options)
I resolved it.
Nearby suggest using activity, on activty, the function will work better (https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient#subscribe(android.app.PendingIntent,%20com.google.android.gms.nearby.messages.SubscribeOptions))
All of the Messages APIs should be used from a foreground Activity,
with the exception of the variants of subscribe that take a
PendingIntent parameter. Your Activity should publish(Message) or
subscribe(MessageListener) either in onStart() or in response to a
user action in a visible Activity, and you should always symmetrically
unpublish(Message) or unsubscribe(MessageListener) in onStop().
When subcribe, if using activity, it will ask to grant permission to bluetooth, location, microphone, if using service it will not ask
So if you use the service, you must combine using the activity.
When you subscribe in mainActivity, if another activity appears on top (then MainActivty will be onStop), a notification will appear.
Therefore, when subcribe, you must click OK to allow the another activity to be displayed
This is sample:
MainActivity.tk
private val mMessageListener: MessageListener = object : MessageListener() {
override fun onFound(message: Message) {
Log.d(TAG, "onFound message:"+ String(message.content))
}
override fun onLost(message: Message) {
Log.d(TAG, "Lost sight of message: " + String(message.content))
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val sharedPref: SharedPreferences = getSharedPreferences("MyPref", Context.MODE_PRIVATE)
val isFirstTime = sharedPref.getBoolean("FIRST_TIME", true)
if(isFirstTime) {
Nearby.getMessagesClient(this).subscribe(mMessageListener).addOnCompleteListener(this, OnCompleteListener {
requestPermissionFirstTime()
}).addOnCanceledListener(this, OnCanceledListener {
requestPermissionFirstTime()
})
} else {
requestPermissionCapture()
checkPermissionAccessibility()
startService(Intent(this, NearbyMessageService::class.java))
}
}
private fun requestPermissionFirstTime() {
val sharedPref: SharedPreferences = getSharedPreferences(Utils.IAMHERE_PREF, Context.MODE_PRIVATE)
val editor = sharedPref.edit()
editor.putBoolean("FIRST_TIME", false)
editor.apply()
Nearby.getMessagesClient(this).unsubscribe(mMessageListener)
requestPermissionCapture()
checkPermissionAccessibility()
}
NearbyMessageService.tk
class NearbyMessageService: IntentService("NearbyMessageService") {
private val mMessageListener: MessageListener = object : MessageListener() {
override fun onFound(message: Message) {
Log.d(TAG, "onFound message:"+ String(message.content))
}
override fun onLost(message: Message) {
Log.d(TAG, "Lost sight of message: " + String(message.content))
}
}
override fun onCreate() {
super.onCreate()
startForeground()
Nearby.getMessagesClient(this).subscribe(mMessageListener)
}
private fun startForeground() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "002"
val channelName = "Nearby Service Channel"
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE)
channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
val notification: Notification = Notification.Builder(applicationContext, channelId)
.setOngoing(true)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentTitle(getString(R.string.app_name))
.build()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(Utils.NOTICATION_ID_NEARBY, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION)
} else {
startForeground(Utils.NOTICATION_ID_NEARBY, notification)
}
} else {
startForeground(Utils.NOTICATION_ID_NEARBY, Notification())
}
}
}

Categories

Resources