intent.getParcelableExtra() 仅在第一次发送推送通知时返回空值
Posted
技术标签:
【中文标题】intent.getParcelableExtra() 仅在第一次发送推送通知时返回空值【英文标题】:intent.getParcelableExtra() return a null value only the first time on sending push notification 【发布时间】:2021-07-05 13:03:10 【问题描述】:我有 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
的Activity
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
对象为空。但是,当再次按下新通知时,该方法会返回可以使用的对象。该问题仅在您第一次点击通知时出现,在应用打开后(并且它尚未在后台)。
我该如何解决?
【问题讨论】:
您想获取用户列表吗?intent.putExtra(USER_KEY, user)
,这段代码在for循环里面
不,我只想获得一个特定的用户。 for 将只执行一次,因为我的查询基于唯一的用户名。
【参考方案1】:
您似乎在 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())
【讨论】:
是的,我发现了错误。我尝试在intent.putExtra() 上传递一个对象,使用构造函数手动创建一个用户,问题解决了,谢谢。 我找到了问题,但是不知道在哪里写puExtra()方法。我必须在 onDataChange() 方法中创建对象,然后将其传递给 putExtra() 方法。 尝试将创建通知的代码(从创建 notificationManager 到 notificationManager.notify())移动到新函数,并在设置用户后在 onDataChange() 方法中调用此函数在额外内容中。只需将意图传递给新函数并将其传递给 pendingIntent - 请参阅我的答案的编辑。 现在似乎工作正常,非常感谢以上是关于intent.getParcelableExtra() 仅在第一次发送推送通知时返回空值的主要内容,如果未能解决你的问题,请参考以下文章