首页 > 解决方案 > intent.getParcelableExtra() 仅在第一次发送推送通知时返回空值

问题描述

我有 2 个文件。一个文件是一个名为的消息服务 MyFirebaseMessagingService.kt

class MyFirebaseMessagingService : FirebaseMessagingService() {

    private val ADMIN_CHANNEL_ID = "admin_channel"

    override fun onMessageReceived(p0: RemoteMessage) {
        super.onMessageReceived(p0)

        val intent = Intent(this, ChatActivity::class.java)

        val username = p0.data["title"]

        val ref = FirebaseDatabase.getInstance().getReference("/users/").orderByChild("username").equalTo(username).addValueEventListener(object: ValueEventListener{
            override fun onCancelled(error: DatabaseError) {

            }

            override fun onDataChange(snapshot: DataSnapshot) {
                for(child in snapshot.children){
                    var user : User? = child.getValue(User::class.java)
                    if(user != null){
                        Log.d("TAG", user.username)
                        Log.d("TAG", user.image_url)
                        Log.d("TAG", user.uid)
                    }
                    intent.putExtra(USER_KEY, user)
                }
            }
            })

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val notificationID = Random().nextInt(3000)


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            setupChannels(notificationManager)
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent,
            PendingIntent.FLAG_ONE_SHOT
        )
        /*
        val largeIcon = BitmapFactory.decodeResource(
            resources,
            R.drawable.ic_delete
        )*/

        val notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder = NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
            .setSmallIcon(R.drawable.custom_user_icon)
            //.setLargeIcon(largeIcon)
            .setContentTitle(p0?.data?.get("title"))
            .setContentText(p0?.data?.get("message"))
            .setAutoCancel(true)
            .setSound(notificationSoundUri)
            .setContentIntent(pendingIntent)

        //Set notification color to match app color template
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            notificationBuilder.color = resources.getColor(R.color.black)
        }
        notificationManager.notify(notificationID, notificationBuilder.build())
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun setupChannels(notificationManager: NotificationManager?) {
        val adminChannelName = "New notification"
        val adminChannelDescription = "Device to device notification"

        val adminChannel: NotificationChannel
        adminChannel = NotificationChannel(ADMIN_CHANNEL_ID, adminChannelName, NotificationManager.IMPORTANCE_HIGH)
        adminChannel.description = adminChannelDescription
        adminChannel.enableLights(true)
        adminChannel.lightColor = Color.GREEN
        adminChannel.enableVibration(true)
        notificationManager?.createNotificationChannel(adminChannel)
    }
}

第二个文件是一个名为ChatActivity.kt

class ChatActivity : AppCompatActivity() {

    val adapter = GroupAdapter<GroupieViewHolder>()

    var receiver : User? = null

    private val FCM_API = "https://fcm.googleapis.com/fcm/send"
    private val serverKey =
        "key=" + "my api key"
    private val contentType = "application/json"

    private val requestQueue: RequestQueue by lazy {
        Volley.newRequestQueue(this.applicationContext)
    }

    companion object{
        var date_object: Message? = null
        var sender_name :String? = null
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chat)

        val recycler_view = findViewById<RecyclerView>(R.id.recycler_view_messages)
        recycler_view.adapter = adapter
        receiver = intent.getParcelableExtra<User>(NewMessageActivity.USER_KEY)
        supportActionBar?.title = receiver?.username

        val ref = FirebaseDatabase.getInstance().getReference("/users/${FirebaseAuth.getInstance().uid}"+"/username").addValueEventListener(object: ValueEventListener{
            override fun onCancelled(error: DatabaseError) {

            }

            override fun onDataChange(snapshot: DataSnapshot) {
                sender_name = snapshot.getValue(String::class.java)
                Log.e("TAG", "Ricevuta stringa "+sender_name)
            }})

       }
       ....
}

我使用 Parcelable 类的对象User作为方法中的数据putParcelableExtra(),这是 User 类。

class User(val uid:String, val username:String, val image_url:String): Parcelable{
    constructor(): this("", "", "")
}

问题是第一次按下通知时,该getParcelableExtra ()方法没有返回对象,因此该receiver对象为空。但是,当再次按下新通知时,该方法会返回可以使用的对象。该问题仅在您第一次点击通知时发生,在应用程序打开后(并且它还没有在后台)。

我该如何解决?

标签: javaandroidkotlinpush-notification

解决方案


似乎您在 onDataChange 回调中使用 intent.putExtra(USER_KEY, user) 保存了用户。发生的情况是通知在 onDataChange 回调中的代码执行之前显示,因此尚未在意图中设置用户。

要解决此问题,您应该在 intent.putExtra(USER_KEY, user) 调用之后在 MyFirebaseMessagingService 类的 onDataChange 方法中显示通知。

编辑:

一个可能的解决方案是:

class MyFirebaseMessagingService : FirebaseMessagingService() {

private val ADMIN_CHANNEL_ID = "admin_channel"

override fun onMessageReceived(p0: RemoteMessage) {
    super.onMessageReceived(p0)

    val intent = Intent(this, ChatActivity::class.java)

    val username = p0.data["title"]

    val ref = FirebaseDatabase.getInstance().getReference("/users/").orderByChild("username").equalTo(username).addValueEventListener(object: ValueEventListener{
        override fun onCancelled(error: DatabaseError) {

        }

        override fun onDataChange(snapshot: DataSnapshot) {
            for(child in snapshot.children){
                var user : User? = child.getValue(User::class.java)
                if(user != null){
                    Log.d("TAG", user.username)
                    Log.d("TAG", user.image_url)
                    Log.d("TAG", user.uid)
                }
                intent.putExtra(USER_KEY, user)
                showNotification(intent)
            }
        }
        })
}

fun showNotification(intent: Intent){
    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    val notificationID = Random().nextInt(3000)


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        setupChannels(notificationManager)
    }

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    val pendingIntent = PendingIntent.getActivity(
        this, 0, intent,
        PendingIntent.FLAG_ONE_SHOT
    )
    /*
    val largeIcon = BitmapFactory.decodeResource(
        resources,
        R.drawable.ic_delete
    )*/

    val notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
    val notificationBuilder = NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
        .setSmallIcon(R.drawable.custom_user_icon)
        //.setLargeIcon(largeIcon)
        .setContentTitle(p0?.data?.get("title"))
        .setContentText(p0?.data?.get("message"))
        .setAutoCancel(true)
        .setSound(notificationSoundUri)
        .setContentIntent(pendingIntent)

    //Set notification color to match app color template
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        notificationBuilder.color = resources.getColor(R.color.black)
    }
    notificationManager.notify(notificationID, notificationBuilder.build())
}

推荐阅读