java .lang.NullPointerException: Uri не должен быть нулевым при попытке вставить в Telephony.Sms.Conversations - PullRequest
2 голосов
/ 13 февраля 2020

Невозможно вставить новый разговор с Telephony.Sms.Conversations.CONTENT_URI .
Продолжать получать Причина: java .lang.NullPointerException : Uri не должен быть пустым исключение.
Даже если значение URI "content: // sms / messages" .

Ситуация - logi c flow

Я получаю SMS-сообщение с неизвестного номера.
Я вставляю разговор для неизвестного номера (если не найдено).
Я вставляю сообщение и связываю его с только что созданным диалогом .

Dev setup

В целях обучения я создаю Android SMS-приложение с Kotlin.
Android Эмулятор с Pixel XL API 26 .
Приложение, над которым я работаю, настроено как приложение SMS по умолчанию .
Может успешно отправлять, получать и вставлять (код ниже) отдельные сообщения.

createMessage () - работает

Ниже приведен рабочий код, который я написал, чтобы вставить сообщение, когда телефон получает SMS.

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 is "content: // sms / разговоры "

Как Google это делает?

Обнаружено, что Google открывает исходные коды для своих распространенных Android приложений.
Вот код для приложения Messaging :
https://android.googlesource.com/platform/packages/apps/Messaging/

При анализе DatabaseHelper. java Я пришел к выводу, что они создают целую отдельную базу данных с нуля.
И затем работают с этим в течение всего жизненного цикла приложения.
Что еще больше смутило меня - почему они не используют resolver.insert () ?
Я могу ошибаться, программа была перегружена для новый парень, как я.

Вопрос

Если Telephony.Sms.Conversations.CONTENT_URI имеет значение "content: // sms / разговоры" , почему я получить исключение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...