From 453e6daa9352116ac8c85a2b545e5ab23262b9d0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Nov 2021 11:52:07 +0100 Subject: [PATCH] Make the Cursor extensions public And make the code more efficient, since we call getColumnIndexOrNull only once and not on each cursor iteration --- .../lib/multipicker/utils/CursorExtensions.kt | 23 +++++++++ .../app/core/contacts/ContactsDataSource.kt | 50 +++++++++---------- 2 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 multipicker/src/main/java/im/vector/lib/multipicker/utils/CursorExtensions.kt diff --git a/multipicker/src/main/java/im/vector/lib/multipicker/utils/CursorExtensions.kt b/multipicker/src/main/java/im/vector/lib/multipicker/utils/CursorExtensions.kt new file mode 100644 index 0000000000..87cf48d0a7 --- /dev/null +++ b/multipicker/src/main/java/im/vector/lib/multipicker/utils/CursorExtensions.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.lib.multipicker.utils + +import android.database.Cursor + +fun Cursor.getColumnIndexOrNull(column: String): Int? { + return getColumnIndex(column).takeIf { it != -1 } +} diff --git a/vector/src/main/java/im/vector/app/core/contacts/ContactsDataSource.kt b/vector/src/main/java/im/vector/app/core/contacts/ContactsDataSource.kt index f5a5e240c6..f99048501d 100644 --- a/vector/src/main/java/im/vector/app/core/contacts/ContactsDataSource.kt +++ b/vector/src/main/java/im/vector/app/core/contacts/ContactsDataSource.kt @@ -17,10 +17,10 @@ package im.vector.app.core.contacts import android.content.Context -import android.database.Cursor import android.net.Uri import android.provider.ContactsContract import androidx.annotation.WorkerThread +import im.vector.lib.multipicker.utils.getColumnIndexOrNull import timber.log.Timber import javax.inject.Inject import kotlin.system.measureTimeMillis @@ -57,16 +57,20 @@ class ContactsDataSource @Inject constructor( ) ?.use { cursor -> if (cursor.count > 0) { + val idColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Contacts._ID) ?: return@use + val displayNameColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Contacts.DISPLAY_NAME) ?: return@use + val photoUriColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Data.PHOTO_URI) while (cursor.moveToNext()) { - val id = cursor.getLong(ContactsContract.Contacts._ID) ?: continue - val displayName = cursor.getString(ContactsContract.Contacts.DISPLAY_NAME) ?: continue + val id = cursor.getLong(idColumnIndex) + val displayName = cursor.getString(displayNameColumnIndex) val mappedContactBuilder = MappedContactBuilder( id = id, displayName = displayName ) - cursor.getString(ContactsContract.Data.PHOTO_URI) + photoUriColumnIndex + ?.let { cursor.getString(it) } ?.let { Uri.parse(it) } ?.let { mappedContactBuilder.photoURI = it } @@ -85,12 +89,15 @@ class ContactsDataSource @Inject constructor( null, null, null) - ?.use { innerCursor -> - while (innerCursor.moveToNext()) { - val mappedContactBuilder = innerCursor.getLong(ContactsContract.CommonDataKinds.Phone.CONTACT_ID) - ?.let { map[it] } + ?.use { cursor -> + val idColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.CommonDataKinds.Phone.CONTACT_ID) ?: return@use + val phoneNumberColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.CommonDataKinds.Phone.NUMBER) ?: return@use + + while (cursor.moveToNext()) { + val mappedContactBuilder = cursor.getLong(idColumnIndex) + .let { map[it] } ?: continue - innerCursor.getString(ContactsContract.CommonDataKinds.Phone.NUMBER) + cursor.getString(phoneNumberColumnIndex) ?.let { mappedContactBuilder.msisdns.add( MappedMsisdn( @@ -114,14 +121,17 @@ class ContactsDataSource @Inject constructor( null, null, null) - ?.use { innerCursor -> - while (innerCursor.moveToNext()) { + ?.use { cursor -> + val idColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.CommonDataKinds.Email.CONTACT_ID) ?: return@use + val emailColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.CommonDataKinds.Email.DATA) ?: return@use + + while (cursor.moveToNext()) { // This would allow you get several email addresses // if the email addresses were stored in an array - val mappedContactBuilder = innerCursor.getLong(ContactsContract.CommonDataKinds.Email.CONTACT_ID) - ?.let { map[it] } + val mappedContactBuilder = cursor.getLong(idColumnIndex) + .let { map[it] } ?: continue - innerCursor.getString(ContactsContract.CommonDataKinds.Email.DATA) + cursor.getString(emailColumnIndex) ?.let { mappedContactBuilder.emails.add( MappedEmail( @@ -140,16 +150,4 @@ class ContactsDataSource @Inject constructor( .filter { it.emails.isNotEmpty() || it.msisdns.isNotEmpty() } .map { it.build() } } - - private fun Cursor.getString(column: String): String? { - return getColumnIndex(column) - .takeIf { it != -1 } - ?.let { getString(it) } - } - - private fun Cursor.getLong(column: String): Long? { - return getColumnIndex(column) - .takeIf { it != -1 } - ?.let { getLong(it) } - } }