Reputation: 71
Due to the recent changes in Notification permissions in the Android 13 SDK, I need to update my app with FCM integration to obey the notifications rule. I have upgraded the compileSdk to 33 and also the targetSdk to 33. I have written code to ask POST_NOTIFICATIONS and the prompt appears. On pressing "Allow" the Notification Permission is enabled. But on sending a push notification the app receives no notification.
I only made changes in asking for the notification permission. Did not change anything in FirebaseMessagingService Class. The app was previously targetSdk 30.
class MyFirebaseMessagingService : FirebaseMessagingService() {
var intent: Intent? = null
var badgecount: Int = 0
override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (remoteMessage.data.isNotEmpty()) {
try {
val json = JSONObject(remoteMessage.data.toString())
handleDataMessage(json)
} catch (e: Exception) {
Log.e("FIREBASEEXCEPTION:", e.message.toString())
}
}
if (remoteMessage.notification != null) {
sendNotification(remoteMessage.notification!!.body)
println("Message Notification Body:" + remoteMessage.notification!!.body)
}
super.onMessageReceived(remoteMessage)
}
private fun handleDataMessage(json: JSONObject) {
try {
val data = json.getJSONObject("body")
val badge = data.getString("badge")
val message = data.getString("message")
Log.e("FIREBASE_MSG:", message)
badgecount = badge.toInt()
sendNotification(message)
} catch (e: JSONException) {
Log.e("JSONEXCEPTION:", e.message.toString())
} catch (e: java.lang.Exception) {
}
}
@SuppressLint("ObsoleteSdkInt")
private fun sendNotification(messageBody: String?) {
ShortcutBadger.applyCount(this, badgecount)
intent = Intent(this, HomeActivity::class.java)
intent!!.action = System.currentTimeMillis().toString()
intent!!.putExtra("Notification_Recieved", 1)
val notId = NotificationID.getID()
val stackBuilder = TaskStackBuilder.create(this)
stackBuilder.addNextIntentWithParentStack(intent!!)
val pendingIntent = stackBuilder.getPendingIntent(notId, PendingIntent.FLAG_UPDATE_CURRENT)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder =
NotificationCompat.Builder(this)
.setContentTitle(resources.getString(R.string.app_name))
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel_id = getString(R.string.app_name) + "_01"
val name: CharSequence = getString(R.string.app_name)
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(channel_id, name, importance)
notificationBuilder.setChannelId(mChannel.id)
mChannel.setShowBadge(true)
mChannel.canShowBadge()
mChannel.enableLights(true)
mChannel.lightColor = resources.getColor(R.color.split_bg)
mChannel.enableVibration(true)
mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500)
notificationManager.createNotificationChannel(mChannel)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setSmallIcon(R.drawable.notify_small)
notificationBuilder.color = resources.getColor(R.color.split_bg)
} else {
notificationBuilder.setSmallIcon(R.drawable.nas_large)
notificationBuilder.color = resources.getColor(R.color.split_bg)
}
notificationManager.notify(notId, notificationBuilder.build())
}
}
class MyFirebaseInstanceIDService : FirebaseInstanceIdService() {
var mContext: Context = this
override fun onTokenRefresh() {
//val refreshedToken = FirebaseInstanceId.getInstance().token
val refreshedToken = FirebaseInstanceId.getInstance().token.toString()
Log.e("FIREBASETOKEN", refreshedToken)
sendRegistrationToServer(refreshedToken)
super.onTokenRefresh()
}
private fun sendRegistrationToServer(refreshedToken: String) {
if (refreshedToken != null) {
PreferenceManager.setFcmID(mContext, refreshedToken)
}
}
}
And in manifest
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<service
android:name=".fcm.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".fcm.MyFirebaseInstanceIDService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Upvotes: 7
Views: 22886
Reputation: 71
I had followed everything answered here and referred the documentation, still couldn't find a solution to this issue. But somehow when I added the below flags, I could receive Notifications.
PendingIntent pendingIntent =
stackBuilder.getPendingIntent(notId, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
Upvotes: 0
Reputation: 4712
With the permission on the Manifest file, you also need to ask for Notification Runtime permissions
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
// Can post notifications.
} else {
// Inform user that that your app will not show notifications.
}
}
private fun askNotificationPermission() {
// This is only necessary for API level >= 33 (TIRAMISU)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTED
) {
// Can post notifications.
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
// Display an educational UI explaining to the user the features that will be enabled
// by them granting the POST_NOTIFICATION permission. This UI should provide the user
// "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
// If the user selects "No thanks," allow the user to continue without notifications.
} else {
// Directly ask for the permission
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
}
You can also check if notifications are enabled or not
val notificationManager = getSystemService(NotificationManager::class.java)
val isEnabled = notificationManager.areNotificationsEnabled()
If you faced the problem that is permission Manifest.permission.POST_NOTIFICATIONS
not resolved make sure you have this import
import android.Manifest
Upvotes: 13
Reputation: 1688
It depends on the targetSdk in use. So for targeting android 13 (API Level 33) notifications are off by default. See below from the android notification-permission documentation. At least for newly installed apps.
If a user installs your app on a device that runs Android 13 or higher, your app's notifications are off by default. Your app must wait to send notifications until after you request the new permission and the user grants that permission to your app.
The time at which the permissions dialog appears is based on your app's target SDK version:
If your app targets Android 13 or higher, your app has complete control over when the permission dialog is displayed. Use this opportunity to explain to users why the app needs this permission, encouraging them to grant it.
If your app targets 12L (API level 32) or lower, the system shows the permission dialog the first time your app starts an activity after you create a notification channel, or when your app starts an activity and then creates its first notification channel. This is usually on app startup.
Upvotes: 3