simplifying cursor querying

This commit is contained in:
tibbi 2020-04-07 12:39:34 +02:00
parent 3b83e93192
commit 10bc1d1278
2 changed files with 102 additions and 134 deletions

View File

@ -36,7 +36,7 @@ android {
} }
dependencies { dependencies {
implementation 'com.simplemobiletools:commons:5.24.18' implementation 'com.simplemobiletools:commons:5.24.19'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
implementation 'org.greenrobot:eventbus:3.2.0' implementation 'org.greenrobot:eventbus:3.2.0'
} }

View File

@ -3,7 +3,6 @@ package com.simplemobiletools.smsmessenger.extensions
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import android.database.Cursor
import android.provider.ContactsContract import android.provider.ContactsContract
import android.provider.ContactsContract.CommonDataKinds import android.provider.ContactsContract.CommonDataKinds
import android.provider.Telephony import android.provider.Telephony
@ -47,41 +46,31 @@ fun Context.getMessages(threadID: Int? = null): ArrayList<Message> {
arrayOf(threadID.toString()) arrayOf(threadID.toString())
} }
var cursor: Cursor? = null queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor ->
try { val id = cursor.getIntValue(Telephony.Sms._ID)
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) val subject = cursor.getStringValue(Telephony.Sms.SUBJECT) ?: ""
if (cursor?.moveToFirst() == true) { val body = cursor.getStringValue(Telephony.Sms.BODY)
do { val type = cursor.getIntValue(Telephony.Sms.TYPE)
val id = cursor.getIntValue(Telephony.Sms._ID) var senderName = cursor.getStringValue(Telephony.Sms.ADDRESS)
val subject = cursor.getStringValue(Telephony.Sms.SUBJECT) ?: "" val senderNumber = senderName
val body = cursor.getStringValue(Telephony.Sms.BODY) val date = (cursor.getLongValue(Telephony.Sms.DATE) / 1000).toInt()
val type = cursor.getIntValue(Telephony.Sms.TYPE) val read = cursor.getIntValue(Telephony.Sms.READ) == 1
var senderName = cursor.getStringValue(Telephony.Sms.ADDRESS) val person = cursor.getIntValue(Telephony.Sms.PERSON)
val senderNumber = senderName val thread = cursor.getIntValue(Telephony.Sms.THREAD_ID)
val date = (cursor.getLongValue(Telephony.Sms.DATE) / 1000).toInt()
val read = cursor.getIntValue(Telephony.Sms.READ) == 1
val person = cursor.getIntValue(Telephony.Sms.PERSON)
val thread = cursor.getIntValue(Telephony.Sms.THREAD_ID)
if (hasContactsPermission) { if (hasContactsPermission) {
if (senderName != null && person != 0) { if (senderName != null && person != 0) {
senderName = getPersonsName(person) ?: senderName senderName = getPersonsName(person) ?: senderName
} else if (senderName.areDigitsOnly()) { } else if (senderName.areDigitsOnly()) {
val contactId = getNameFromPhoneNumber(senderName) val contactId = getNameFromPhoneNumber(senderName)
if (contactId != null) { if (contactId != null) {
senderName = getPersonsName(contactId) ?: senderName senderName = getPersonsName(contactId) ?: senderName
}
}
} }
}
val message = Message(id, subject, body, type, senderName, senderNumber, date, read, thread)
messages.add(message)
} while (cursor.moveToNext())
} }
} catch (e: Exception) {
showErrorToast(e) val message = Message(id, subject, body, type, senderName, senderNumber, date, read, thread)
} finally { messages.add(message)
cursor?.close()
} }
return messages return messages
} }
@ -95,28 +84,27 @@ fun Context.getThreadInfo(id: Int): MessagingThread? {
) )
val selection = "${Telephony.Sms.THREAD_ID} = ?" val selection = "${Telephony.Sms.THREAD_ID} = ?"
val selectionArgs = arrayOf(id.toString()) val selectionArgs = arrayOf(id.toString())
var cursor: Cursor? = null
try { try {
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) val cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor?.moveToFirst() == true) { cursor?.use {
val person = cursor.getIntValue(Telephony.Sms.PERSON) if (cursor.moveToFirst()) {
val address = cursor.getStringValue(Telephony.Sms.ADDRESS) val person = cursor.getIntValue(Telephony.Sms.PERSON)
var title = address val address = cursor.getStringValue(Telephony.Sms.ADDRESS)
var title = address
if (title != null && person != 0) { if (title != null && person != 0) {
title = getPersonsName(person) ?: title title = getPersonsName(person) ?: title
} else if (title.areDigitsOnly()) { } else if (title.areDigitsOnly()) {
val contactId = getNameFromPhoneNumber(title) val contactId = getNameFromPhoneNumber(title)
if (contactId != null) { if (contactId != null) {
title = getPersonsName(contactId) ?: title title = getPersonsName(contactId) ?: title
}
} }
}
return MessagingThread(id, title, address) return MessagingThread(id, title, address)
}
} }
} catch (e: Exception) { } catch (e: Exception) {
} finally {
cursor?.close()
} }
return null return null
} }
@ -142,39 +130,38 @@ fun Context.getPersonsName(id: Int): String? {
id.toString() id.toString()
) )
var cursor: Cursor? = null
try { try {
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) val cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor?.moveToFirst() == true) { cursor?.use {
do { if (cursor.moveToFirst()) {
val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE) do {
val isPerson = mimetype == CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE)
if (isPerson) { val isPerson = mimetype == CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
val prefix = cursor.getStringValue(CommonDataKinds.StructuredName.PREFIX) ?: "" if (isPerson) {
val firstName = cursor.getStringValue(CommonDataKinds.StructuredName.GIVEN_NAME) ?: "" val prefix = cursor.getStringValue(CommonDataKinds.StructuredName.PREFIX) ?: ""
val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val firstName = cursor.getStringValue(CommonDataKinds.StructuredName.GIVEN_NAME) ?: ""
val familyName = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: ""
val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: "" val familyName = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: ""
if (firstName.isNotEmpty() || middleName.isNotEmpty() || familyName.isNotEmpty()) { val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: ""
val names = arrayOf(prefix, firstName, middleName, familyName, suffix).filter { it.isNotEmpty() } if (firstName.isNotEmpty() || middleName.isNotEmpty() || familyName.isNotEmpty()) {
return TextUtils.join(" ", names) val names = arrayOf(prefix, firstName, middleName, familyName, suffix).filter { it.isNotEmpty() }
return TextUtils.join(" ", names)
}
} }
}
val isOrganization = mimetype == CommonDataKinds.Organization.CONTENT_ITEM_TYPE val isOrganization = mimetype == CommonDataKinds.Organization.CONTENT_ITEM_TYPE
if (isOrganization) { if (isOrganization) {
val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: "" val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: ""
val jobTitle = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: "" val jobTitle = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: ""
if (company.isNotEmpty() || jobTitle.isNotEmpty()) { if (company.isNotEmpty() || jobTitle.isNotEmpty()) {
return "$company $jobTitle".trim() return "$company $jobTitle".trim()
}
} }
} } while (cursor.moveToNext())
} while (cursor.moveToNext()) }
} }
} catch (e: Exception) { } catch (e: Exception) {
showErrorToast(e) showErrorToast(e)
} finally {
cursor?.close()
} }
return null return null
@ -218,19 +205,16 @@ fun Context.getNameFromPhoneNumber(number: String): Int? {
val selection = "${CommonDataKinds.Phone.NUMBER} = ? OR ${CommonDataKinds.Phone.NORMALIZED_NUMBER} = ?" val selection = "${CommonDataKinds.Phone.NUMBER} = ? OR ${CommonDataKinds.Phone.NORMALIZED_NUMBER} = ?"
val selectionArgs = arrayOf(number, number) val selectionArgs = arrayOf(number, number)
var cursor: Cursor? = null
try { try {
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) val cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor?.moveToFirst() == true) { cursor.use {
return cursor.getIntValue(ContactsContract.Data.CONTACT_ID) if (cursor?.moveToFirst() == true) {
return cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
}
} }
} catch (e: Exception) { } catch (e: Exception) {
showErrorToast(e) showErrorToast(e)
} finally {
cursor?.close()
} }
return null return null
} }
@ -256,44 +240,35 @@ fun Context.getContactNames(): List<Contact> {
CommonDataKinds.Organization.CONTENT_ITEM_TYPE CommonDataKinds.Organization.CONTENT_ITEM_TYPE
) )
var cursor: Cursor? = null queryCursor(uri, projection, selection, selectionArgs) { cursor ->
try { val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE)
if (cursor?.moveToFirst() == true) { val photoUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: ""
do { val isPerson = mimetype == CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID) if (isPerson) {
val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE) val prefix = cursor.getStringValue(CommonDataKinds.StructuredName.PREFIX) ?: ""
val photoUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: "" val firstName = cursor.getStringValue(CommonDataKinds.StructuredName.GIVEN_NAME) ?: ""
val isPerson = mimetype == CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: ""
if (isPerson) { val familyName = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: ""
val prefix = cursor.getStringValue(CommonDataKinds.StructuredName.PREFIX) ?: "" val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: ""
val firstName = cursor.getStringValue(CommonDataKinds.StructuredName.GIVEN_NAME) ?: "" if (firstName.isNotEmpty() || middleName.isNotEmpty() || familyName.isNotEmpty()) {
val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val names = arrayOf(prefix, firstName, middleName, familyName, suffix).filter { it.isNotEmpty() }
val familyName = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" val fullName = TextUtils.join(" ", names)
val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: "" val contact = Contact(id, fullName, photoUri, "", false)
if (firstName.isNotEmpty() || middleName.isNotEmpty() || familyName.isNotEmpty()) { contacts.add(contact)
val names = arrayOf(prefix, firstName, middleName, familyName, suffix).filter { it.isNotEmpty() } }
val fullName = TextUtils.join(" ", names) }
val contact = Contact(id, fullName, photoUri, "", false)
contacts.add(contact) val isOrganization = mimetype == CommonDataKinds.Organization.CONTENT_ITEM_TYPE
} if (isOrganization) {
} val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: ""
val jobTitle = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: ""
val isOrganization = mimetype == CommonDataKinds.Organization.CONTENT_ITEM_TYPE if (company.isNotEmpty() || jobTitle.isNotEmpty()) {
if (isOrganization) { val fullName = "$company $jobTitle".trim()
val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: "" val contact = Contact(id, fullName, photoUri, "", true)
val jobTitle = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: "" contacts.add(contact)
if (company.isNotEmpty() || jobTitle.isNotEmpty()) { }
val fullName = "$company $jobTitle".trim()
val contact = Contact(id, fullName, photoUri, "", true)
contacts.add(contact)
}
}
} while (cursor.moveToNext())
} }
} catch (ignored: Exception) {
} finally {
cursor?.close()
} }
return contacts return contacts
} }
@ -306,20 +281,13 @@ fun Context.getContactPhoneNumbers(): ArrayList<Contact> {
CommonDataKinds.Phone.NORMALIZED_NUMBER CommonDataKinds.Phone.NORMALIZED_NUMBER
) )
var cursor: Cursor? = null queryCursor(uri, projection) { cursor ->
try { val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
cursor = contentResolver.query(uri, projection, null, null, null) val phoneNumber = cursor.getStringValue(CommonDataKinds.Phone.NORMALIZED_NUMBER)
if (cursor?.moveToFirst() == true) { if (phoneNumber != null) {
do { val contact = Contact(id, "", "", phoneNumber, false)
val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID) contacts.add(contact)
val phoneNumber = cursor.getStringValue(CommonDataKinds.Phone.NORMALIZED_NUMBER) ?: continue
val contact = Contact(id, "", "", phoneNumber, false)
contacts.add(contact)
} while (cursor.moveToNext())
} }
} catch (ignored: Exception) {
} finally {
cursor?.close()
} }
return contacts return contacts
} }