【问题标题】:Android capture and send notifications through bluetoothAndroid 通过蓝牙捕获和发送通知
【发布时间】:2021-09-22 10:25:39
【问题描述】:

我有两个安卓设备。我开发了两个代码库。一个是发送者代码库,另一个是接收者。这两个都是通过蓝牙套接字连接的,我可以在它们之间发送简单的字符串。

在发送方设备上,我实现了一个NotificationListenerService,它从该设备捕获通知。对于每个通知,我都会得到一个 StatusBarNotification 类型的对象。根据文档,此对象实现 Parcelable 接口。

为了传输这个对象,我尝试过使用 GSON,以及使用 Parcel 对象来编组和发送数据。这不起作用,所以我不再担心发送部分,并尝试在同一设备上查看这是否会正确编组和解组。

这是两者的 Kotlin 代码,

/*
 * Using Gson for serialization.
 * 
 * Parts of the object e.g. deserializedObject.notification are missing
 */
val serializedString = Gson().toJson(sbn)
val deserializedObject = Gson().fromJson<StatusBarNotification>(serializedString, StatusBarNotification::class.java)

/*
 * Using Parcel for serialization.
 *
 * Throws this error,
 * Caused by: java.lang.RuntimeException: Tried to marshall a Parcel that contained Binder objects.
 */
val parcel = Parcel.obtain()
parcel.writeValue(sbn)
val bytes = parcel.marshall()

val p2 = Parcel.obtain()
p2.unmarshall(bytes, 0, bytes.size)
val result = p2.readValue(StatusBarNotification::class.java.classLoader) as StatusBarNotification

任何方向都将不胜感激。

更新 1

我已尝试创建自定义数据类对象。序列化和反序列化在蓝牙上工作得非常好,我正在第二台设备上获取数据。但是我已经缩小了范围,我的问题仍然是 StatusBarNotification 对象不能很好地进行序列化。

val serializedCode = Gson().toJson(statusBarNotification) 在调试器中给出 {"id":1815187780,"pkg":"org.telegram.messenger","uid":10260}

任何线索将不胜感激。

更新 2

如果有任何通过 Android 实现通知回复的官方方式,也将不胜感激。

【问题讨论】:

  • 我一头雾水,你想实现对来自其他设备的通知的回复或正确的序列化/反序列化?
  • 我想回复其他设备的通知。序列化/反序列化是该过程的必要部分。
  • 这个问题好像太宽泛了?你的代码库中是否有 sn-ps 说明它实际失败的地方,或者你迷失了如何继续?
  • 就像我在问题中提到的那样,我无法序列化通知对象。这就是它失败的地方。

标签: android serialization android-notifications android-bluetooth parcelable


【解决方案1】:

即使正确反序列化,状态栏通知对象也不一定代表其他设备上有意义的任何内容。这是因为它包含上下文信息,例如在另一台设备上不同的用户和进程 ID。

编辑:Parcel 序列化失败的原因是,正如错误消息所示,有一个无法序列化的 Binder 对象(转换为字节数组)。由于同样的原因,json 序列化可能会失败。并非所有资源/对象都可以序列化,或者序列化是有意义的。可能有一种方法可以通过它的 ID 检索 Notification 对象,在这种情况下,只需保存它就足够了。

您可以做的只是将通知的基本信息作为字符串发送到第二台设备,在第二台设备上创建一个用户可以回答的新通知,仅将答案作为字符串发送回第一台设备,尝试使用该答案作为原始状态栏通知的回复。

一般来说,智能手表和 Chromebook 可以做到这一点。也许看看它是如何在 WearOS 中完成的会有所帮助

【讨论】:

  • 是的,我正在使用另一个自定义对象通过蓝牙进行传输,并且运行良好。但是,当回复到来时,我仍然需要从原始 android 设备上的某个本地存储中检索原始 sbn 对象。这是因为它包含远程输入和待定意图,我们可以使用它们将回复推送到原始应用程序(比如whatsapp)。在这种情况下,我将需要序列化和反序列化。是的,研究 Wear OS 的工作方式对我来说是下一步。
  • 所以我至少误解了部分问题。您需要编组通知吗?在很多情况下,传输对象的正确方法是按原样传递 parcel/parceable。
  • 如果我的问题不够清楚,我深表歉意。我在早期阶段就创建了它,从那以后我对这种情况有了更多的了解,因为我一直在努力解决它。如果有办法将 sbn 对象序列化为持久化到磁盘(或共享存储)的列表,这将解决我的问题。调试器中的val serializedCode = Gson().toJson(statusBarNotification) 给出了{"id":1815187780,"pkg":"org.telegram.messenger","uid":10260} 并没有给我完整的对象
  • 不确定这是否可能,但我缺乏理解。正如您在发布的错误“试图编组包含 Binder 对象的包裹”中看到的那样。有一个无法序列化的 Binder 对象。由于同样的原因,json 序列化可能会失败。并非所有资源/对象都可以序列化。我的猜测是,在这种情况下您需要做的是存储通知的 ID,然后“要求”Android 系统提供/重新创建与 ID 对应的对象,而不是反序列化它。但我不确定通知中隐藏了什么......
  • 我很高兴能以某种方式提供帮助,但我觉得我没有提供(好的)答案。谢谢你的提议:)!我建议您在找到任务的解决方案时自己发布答案。
猜你喜欢
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2019-01-29
  • 2014-07-12
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多