Use system getOrCreateThreadId if available

This commit is contained in:
Moez Bhatti
2018-06-11 15:10:37 -04:00
parent 82332207d2
commit 9ced706ff0
3 changed files with 84 additions and 68 deletions
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package compat
import android.content.Context
import android.database.sqlite.SqliteWrapper
import android.net.Uri
import android.os.Build
import android.provider.BaseColumns
import android.provider.Telephony
import android.text.TextUtils
import android.util.Patterns
import timber.log.Timber
import java.util.regex.Pattern
object TelephonyCompat {
private val ID_PROJECTION = arrayOf(BaseColumns._ID)
private val THREAD_ID_CONTENT_URI = Uri.parse("content://mms-sms/threadID")
val NAME_ADDR_EMAIL_PATTERN = Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*")
fun getOrCreateThreadId(context: Context, recipients: Set<String>): Long {
return if (Build.VERSION.SDK_INT >= 23) {
Telephony.Threads.getOrCreateThreadId(context, recipients)
} else {
val uriBuilder = THREAD_ID_CONTENT_URI.buildUpon()
recipients
.map { recipient -> if (isEmailAddress(recipient)) extractAddrSpec(recipient) else recipient }
.forEach { recipient -> uriBuilder.appendQueryParameter("recipient", recipient) }
val uri = uriBuilder.build()
SqliteWrapper.query(context, context.contentResolver, uri, ID_PROJECTION, null, null, null)?.use { cursor ->
if (cursor.moveToFirst()) {
return cursor.getLong(0)
} else {
Timber.e("getOrCreateThreadId returned no rows!")
}
}
Timber.e("getOrCreateThreadId failed with " + recipients.size + " recipients")
throw IllegalArgumentException("Unable to find or allocate a thread ID.")
}
}
fun extractAddrSpec(address: String): String {
val match = NAME_ADDR_EMAIL_PATTERN.matcher(address)
return if (match.matches()) {
match.group(2)
} else address
}
fun isEmailAddress(address: String): Boolean {
if (TextUtils.isEmpty(address)) {
return false
}
val s = extractAddrSpec(address)
val match = Patterns.EMAIL_ADDRESS.matcher(s)
return match.matches()
}
}
@@ -24,11 +24,8 @@ import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.database.sqlite.SqliteWrapper
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.provider.BaseColumns
import android.provider.Telephony
import android.telephony.PhoneNumberUtils
import android.telephony.SmsManager
@@ -37,6 +34,7 @@ import com.klinker.android.send_message.BroadcastUtils
import com.klinker.android.send_message.Settings
import com.klinker.android.send_message.StripAccents
import com.klinker.android.send_message.Transaction
import compat.TelephonyCompat
import filter.ConversationFilter
import io.realm.Case
import io.realm.Realm
@@ -51,10 +49,10 @@ import model.Conversation
import model.Message
import model.MmsPart
import model.SearchResult
import util.MessageUtils
import util.Preferences
import util.extensions.anyOf
import util.extensions.map
import util.tryOrNull
import java.io.ByteArrayOutputStream
import javax.inject.Inject
import javax.inject.Singleton
@@ -153,20 +151,7 @@ class MessageRepositoryImpl @Inject constructor(
}
override fun getOrCreateConversation(addresses: List<String>): Conversation? {
return addresses
.map { address ->
when (MessageUtils.isEmailAddress(address)) {
true -> MessageUtils.extractAddrSpec(address)
false -> address
}
}
.let { recipients ->
Uri.parse("content://mms-sms/threadID").buildUpon().apply {
recipients.forEach { recipient -> appendQueryParameter("recipient", recipient) }
}.build()
}
.let { uri -> SqliteWrapper.query(context, context.contentResolver, uri, arrayOf(BaseColumns._ID), null, null, null) }
?.use { cursor -> if (cursor.moveToFirst()) cursor.getLong(0) else null }
return tryOrNull { TelephonyCompat.getOrCreateThreadId(context, addresses.toSet()) }
?.takeIf { threadId -> threadId != 0L }
?.let { threadId ->
var conversation = getConversation(threadId)
-50
View File
@@ -1,50 +0,0 @@
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package util
import android.text.TextUtils
import android.util.Patterns
import java.util.regex.Pattern
/**
* Utils for using Telephony functions on lower API levels
*
* Adapted from https://android.googlesource.com/platform/packages/apps/Messaging/+/master/src/com/android/messaging/sms/MmsSmsUtils.java
*/
object MessageUtils {
val NAME_ADDR_EMAIL_PATTERN = Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*")
fun extractAddrSpec(address: String): String {
val match = NAME_ADDR_EMAIL_PATTERN.matcher(address)
return if (match.matches()) {
match.group(2)
} else address
}
fun isEmailAddress(address: String): Boolean {
if (TextUtils.isEmpty(address)) {
return false
}
val s = extractAddrSpec(address)
val match = Patterns.EMAIL_ADDRESS.matcher(s)
return match.matches()
}
}