【发布时间】:2020-10-06 19:48:26
【问题描述】:
无法插入新对话到 Telephony.Sms.Conversations.CONTENT_URI。
不断收到 Caused by: java.lang.NullPointerException: Uri must not be null 异常。
即使 uri 的值为 "content://sms/conversations"。
情况-逻辑流程
我收到来自未知号码的短信。
我为未知号码插入了一个对话(如果没有找到)。
我插入 message 并将其与新创建的 conversation 相关联。
开发设置
出于学习目的,我正在使用 Kotlin 创建一个 Android SMS 应用程序。
Android Emulator 使用 Pixel XL API 26。
我正在处理的应用程序设置为默认短信应用程序。
可以成功发送、接收和插入(代码如下)个人消息。
createMessage() - 有效
以下是我编写的用于在手机收到短信时插入消息的工作代码。
fun createMessage(
resolver: ContentResolver,
threadId: Number,
body: String,
sentByUs: Boolean
): Message? {
val messageType = if (sentByUs) Telephony.Sms.MESSAGE_TYPE_SENT else Telephony.Sms.MESSAGE_TYPE_INBOX
val values = ContentValues()
values.put(Telephony.Sms.THREAD_ID, threadId.toInt())
values.put(Telephony.Sms.BODY, body)
values.put(Telephony.Sms.TYPE, messageType)
val result = resolver.insert(Telephony.Sms.CONTENT_URI, values)
return this.getMessage(resolver, result)
}
createConversation() - 不起作用
下面是我正在处理的代码,它试图插入一个新的对话。
fun createConversation(
resolver: ContentResolver,
senderPhoneNumber: String,
latestMessageText: String,
latestMessageTimestamp: Long,
latestMessageIsOurs: Boolean,
latestMessageWasRead: Boolean
): Conversation? {
val wasRead = if (latestMessageWasRead) 1 else 0
val isOurs = if (latestMessageIsOurs) Telephony.Sms.Conversations.MESSAGE_TYPE_SENT else Telephony.Sms.Conversations.MESSAGE_TYPE_INBOX
val values = ContentValues()
values.put(Telephony.Sms.Conversations.ADDRESS, senderPhoneNumber)
values.put(Telephony.Sms.Conversations.BODY, latestMessageText)
values.put(Telephony.Sms.Conversations.DATE, latestMessageTimestamp)
values.put(Telephony.Sms.Conversations.TYPE, isOurs)
values.put(Telephony.Sms.Conversations.READ, wasRead)
// -------------------------------------------------------------------------
// ------ Throws java.lang.NullPointerException: Uri must not be null ------
// -------------------------------------------------------------------------
val result = resolver.insert(Telephony.Sms.Conversations.CONTENT_URI, values)
return this.getConversation(resolver, result)
}
在执行 resolver.insert() 时,应用程序崩溃并显示以下错误消息:
原因:java.lang.NullPointerException:Uri 不能为空
附加调试器后,我可以看到 uri 确实有一个值。
Telephony.Sms.Conversations.CONTENT_URI 是 "content:/ /sms/conversations”
Google 是如何做到的?
发现 Google 开源了其常见的 Android 应用程序。
下面是 Messaging 应用程序的代码:
https://android.googlesource.com/platform/packages/apps/Messaging/
在分析 DatabaseHelper.java 时,我得出的结论是他们从头开始创建了一个完全独立的数据库。
然后在应用程序的整个生命周期中使用它。
这让我更加困惑 - 为什么他们不使用 resolver.insert()?
我可能是错的,对于像我这样的新人来说,这个程序是压倒性的。
问题
如果 Telephony.Sms.Conversations.CONTENT_URI 的值为 "content://sms/conversations",为什么会出现异常?
【问题讨论】:
-
您在哪种手机型号上遇到异常?
-
@Amir Hossein Ghasemi,我模拟的手机是 Google Pixel XL (API 26)。
-
最近我只在一部手机小米 Mi Mix5 上看到这个用户在他有 uri 时得到
uri must not be null。直到现在我才能修复它,如果可以,会通知你 -
在运行 Android 9 的 Pixel 3XL 上出现同样的问题。有人找到解决方法了吗?