【问题标题】:java.lang.NullPointerException: Uri must not be null when trying to insert to Telephony.Sms.Conversationsjava.lang.NullPointerException:尝试插入 Telephony.Sms.Conversations 时,Uri 不能为空
【发布时间】: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 上出现同样的问题。有人找到解决方法了吗?

标签: android kotlin sms


【解决方案1】:

要调查此类问题,您需要为您的应用关闭 logcat 过滤。然后你会发现一个 SQLiteException 可以帮助你找出问题所在。

NPE 指的是插入失败并返回空 Uri 而不是新元素的适当 Uri 路径。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多