Sanju Sabu
Sanju Sabu

Reputation: 71

Notification not being shown in Android 13

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

Answers (3)

Sanju Sabu
Sanju Sabu

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

AmrDeveloper
AmrDeveloper

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

Vall0n
Vall0n

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

Related Questions