java - 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
对象为空。但是,当再次按下新通知时,该方法会返回可以使用的对象。该问题仅在您第一次点击通知时发生,在应用程序打开后(并且它还没有在后台)。
我该如何解决?
解决方案
似乎您在 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())
}
推荐阅读
- python - 将列表参数传递给 zeep 方法
- java - 用户如何通过点击 google maps android 添加标记?
- python - 如何在鼠标所在的地方转动精灵
- elasticsearch - 弹性搜索中的“标准”类型
- c# - 我不知道如何从 'float' 转换为 'int'
- android - 如何修复 android studio 中的 getWritableDatabase() 错误?
- php - Mysql IN(1,2,3) 运算符正在获取与 1 匹配的数据
- php - 用php重复合并或组合一个数组中的N(6)行文本
- objective-c - 如何修复“架构 x86_64 的未定义符号”委托
- c++ - 为什么在 EventWrite 函数调用成功后我有空的 Windows 日志