Android 13中未显示通知。

6
由于Android 13 SDK中通知权限的最近更改,我需要更新我的应用程序并集成FCM以遵守通知规则。我已将compileSdk升级到33,targetSdk也升级到33。我编写了代码来请求POST_NOTIFICATIONS,提示出现了。在按下“允许”后,通知权限被启用。但是,在发送推送通知时,应用程序没有收到任何通知。
我只更改了请求通知权限的内容,没有更改FirebaseMessagingService类中的任何内容。该应用程序先前的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)
        }

    }
}

而在清单文件中

<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>

添加一些清单代码,以及你的消息处理等内容。 - jayesh gurudayalani
你根据这个指南更新了你的实现吗? - Yuji Bry
嘿,@SanjuSabu,你的应用程序模块的build.gradle中使用了targetSdk 33吗? - Vall0n
@Vall0n 是的,我已经升级到 targetSdk 33。 - Sanju Sabu
@SanjuSabu,仅将“targetSdk”设置为33并不能解决您的问题。您必须自己在运行时请求权限。请参见最佳实践和此处的请求权限。只需测试您的通知服务,您可以从应用程序设置中手动允许通知权限。 - Vall0n
显示剩余8条评论
2个回答

8
在Manifest文件中获得许可后,您还需要请求通知运行时权限。
<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)
        }
    }
}

您还可以检查通知是否已启用。
val notificationManager = getSystemService(NotificationManager::class.java)
val isEnabled = notificationManager.areNotificationsEnabled()

如果你遇到了权限问题Manifest.permission.POST_NOTIFICATIONS未解决,请确保你导入了这个。
import android.Manifest

2

这取决于目标SDK的使用。因此,针对Android 13(API级别33)通知默认关闭。请参考来自{{link1:android notification-permission documentation}}的下文。至少对于新安装的应用程序。

如果用户在运行Android 13或更高版本的设备上安装您的应用程序,则默认情况下关闭您的应用程序的通知。您的应用必须等待,在请求新权限并用户授予该权限给您的应用程序之后才能发送通知。

权限对话框出现的时间基于您的应用程序的目标SDK版本:

如果您的应用程序针对Android 13或更高版本,则您的应用程序完全控制何时显示权限对话框。利用这个机会向用户解释应用需要此权限的原因,并鼓励他们授予它。

如果您的应用程序针对12L(API级别32)或更低版本,则系统在创建通知通道后,您的应用程序启动活动的第一次启动或者在启动活动后创建其第一个通知通道时显示权限对话框。这通常在应用程序启动时进行。


我按照这些说明操作了,但仍然无法收到帖子通知。 - Sanju Sabu
1
@SanjuSabu 你需要请求运行时权限来启用它。虽然你可以在应用设置->权限中手动允许它。 - moonLander_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接