Merge pull request #4607 from vector-im/feature/bma/cursor_crash
Add robustness when getting data from cursors.
This commit is contained in:
commit
9253a3664b
1
changelog.d/4605.bugfix
Normal file
1
changelog.d/4605.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add robustness when getting data from cursors
|
@ -20,6 +20,8 @@ import android.content.ContentResolver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
|
import androidx.core.database.getIntOrNull
|
||||||
|
import androidx.core.database.getStringOrNull
|
||||||
import im.vector.lib.multipicker.entity.MultiPickerContactType
|
import im.vector.lib.multipicker.entity.MultiPickerContactType
|
||||||
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
||||||
|
|
||||||
@ -54,9 +56,9 @@ class ContactPicker : Picker<MultiPickerContactType>() {
|
|||||||
val nameColumn = cursor.getColumnIndexOrNull(ContactsContract.Contacts.DISPLAY_NAME) ?: return@use
|
val nameColumn = cursor.getColumnIndexOrNull(ContactsContract.Contacts.DISPLAY_NAME) ?: return@use
|
||||||
val photoUriColumn = cursor.getColumnIndexOrNull(ContactsContract.Contacts.PHOTO_URI) ?: return@use
|
val photoUriColumn = cursor.getColumnIndexOrNull(ContactsContract.Contacts.PHOTO_URI) ?: return@use
|
||||||
|
|
||||||
val contactId = cursor.getInt(idColumn)
|
val contactId = cursor.getIntOrNull(idColumn) ?: return@use
|
||||||
var name = cursor.getString(nameColumn)
|
var name = cursor.getStringOrNull(nameColumn) ?: return@use
|
||||||
val photoUri = cursor.getString(photoUriColumn)
|
val photoUri = cursor.getStringOrNull(photoUriColumn)
|
||||||
val phoneNumberList = mutableListOf<String>()
|
val phoneNumberList = mutableListOf<String>()
|
||||||
val emailList = mutableListOf<String>()
|
val emailList = mutableListOf<String>()
|
||||||
|
|
||||||
@ -78,8 +80,8 @@ class ContactPicker : Picker<MultiPickerContactType>() {
|
|||||||
val data1ColumnIndex = innerCursor.getColumnIndexOrNull(ContactsContract.Data.DATA1) ?: return@inner
|
val data1ColumnIndex = innerCursor.getColumnIndexOrNull(ContactsContract.Data.DATA1) ?: return@inner
|
||||||
|
|
||||||
while (innerCursor.moveToNext()) {
|
while (innerCursor.moveToNext()) {
|
||||||
val mimeType = innerCursor.getString(mimeTypeColumnIndex)
|
val mimeType = innerCursor.getStringOrNull(mimeTypeColumnIndex)
|
||||||
val contactData = innerCursor.getString(data1ColumnIndex)
|
val contactData = innerCursor.getStringOrNull(data1ColumnIndex) ?: continue
|
||||||
|
|
||||||
if (mimeType == ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) {
|
if (mimeType == ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) {
|
||||||
name = contactData
|
name = contactData
|
||||||
@ -121,7 +123,7 @@ class ContactPicker : Picker<MultiPickerContactType>() {
|
|||||||
)?.use { cursor ->
|
)?.use { cursor ->
|
||||||
return if (cursor.moveToFirst()) {
|
return if (cursor.moveToFirst()) {
|
||||||
cursor.getColumnIndexOrNull(ContactsContract.RawContacts._ID)
|
cursor.getColumnIndexOrNull(ContactsContract.RawContacts._ID)
|
||||||
?.let { cursor.getInt(it) }
|
?.let { cursor.getIntOrNull(it) }
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package im.vector.lib.multipicker
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
|
import androidx.core.database.getLongOrNull
|
||||||
|
import androidx.core.database.getStringOrNull
|
||||||
import im.vector.lib.multipicker.entity.MultiPickerBaseType
|
import im.vector.lib.multipicker.entity.MultiPickerBaseType
|
||||||
import im.vector.lib.multipicker.entity.MultiPickerFileType
|
import im.vector.lib.multipicker.entity.MultiPickerFileType
|
||||||
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
||||||
@ -53,8 +55,8 @@ class FilePicker : Picker<MultiPickerBaseType>() {
|
|||||||
val nameColumn = cursor.getColumnIndexOrNull(OpenableColumns.DISPLAY_NAME) ?: return@use null
|
val nameColumn = cursor.getColumnIndexOrNull(OpenableColumns.DISPLAY_NAME) ?: return@use null
|
||||||
val sizeColumn = cursor.getColumnIndexOrNull(OpenableColumns.SIZE) ?: return@use null
|
val sizeColumn = cursor.getColumnIndexOrNull(OpenableColumns.SIZE) ?: return@use null
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
val name = cursor.getString(nameColumn)
|
val name = cursor.getStringOrNull(nameColumn)
|
||||||
val size = cursor.getLong(sizeColumn)
|
val size = cursor.getLongOrNull(sizeColumn) ?: 0
|
||||||
|
|
||||||
MultiPickerFileType(
|
MultiPickerFileType(
|
||||||
name,
|
name,
|
||||||
|
@ -20,6 +20,8 @@ import android.content.Context
|
|||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
|
import androidx.core.database.getLongOrNull
|
||||||
|
import androidx.core.database.getStringOrNull
|
||||||
import im.vector.lib.multipicker.entity.MultiPickerAudioType
|
import im.vector.lib.multipicker.entity.MultiPickerAudioType
|
||||||
import im.vector.lib.multipicker.entity.MultiPickerImageType
|
import im.vector.lib.multipicker.entity.MultiPickerImageType
|
||||||
import im.vector.lib.multipicker.entity.MultiPickerVideoType
|
import im.vector.lib.multipicker.entity.MultiPickerVideoType
|
||||||
@ -41,8 +43,8 @@ internal fun Uri.toMultiPickerImageType(context: Context): MultiPickerImageType?
|
|||||||
val sizeColumn = cursor.getColumnIndexOrNull(MediaStore.Images.Media.SIZE) ?: return@use null
|
val sizeColumn = cursor.getColumnIndexOrNull(MediaStore.Images.Media.SIZE) ?: return@use null
|
||||||
|
|
||||||
if (cursor.moveToNext()) {
|
if (cursor.moveToNext()) {
|
||||||
val name = cursor.getString(nameColumn)
|
val name = cursor.getStringOrNull(nameColumn)
|
||||||
val size = cursor.getLong(sizeColumn)
|
val size = cursor.getLongOrNull(sizeColumn) ?: 0
|
||||||
|
|
||||||
val bitmap = ImageUtils.getBitmap(context, this)
|
val bitmap = ImageUtils.getBitmap(context, this)
|
||||||
val orientation = ImageUtils.getOrientation(context, this)
|
val orientation = ImageUtils.getOrientation(context, this)
|
||||||
@ -79,8 +81,8 @@ internal fun Uri.toMultiPickerVideoType(context: Context): MultiPickerVideoType?
|
|||||||
val sizeColumn = cursor.getColumnIndexOrNull(MediaStore.Video.Media.SIZE) ?: return@use null
|
val sizeColumn = cursor.getColumnIndexOrNull(MediaStore.Video.Media.SIZE) ?: return@use null
|
||||||
|
|
||||||
if (cursor.moveToNext()) {
|
if (cursor.moveToNext()) {
|
||||||
val name = cursor.getString(nameColumn)
|
val name = cursor.getStringOrNull(nameColumn)
|
||||||
val size = cursor.getLong(sizeColumn)
|
val size = cursor.getLongOrNull(sizeColumn) ?: 0
|
||||||
var duration = 0L
|
var duration = 0L
|
||||||
var width = 0
|
var width = 0
|
||||||
var height = 0
|
var height = 0
|
||||||
@ -128,8 +130,8 @@ fun Uri.toMultiPickerAudioType(context: Context): MultiPickerAudioType? {
|
|||||||
val sizeColumn = cursor.getColumnIndexOrNull(MediaStore.Audio.Media.SIZE) ?: return@use null
|
val sizeColumn = cursor.getColumnIndexOrNull(MediaStore.Audio.Media.SIZE) ?: return@use null
|
||||||
|
|
||||||
if (cursor.moveToNext()) {
|
if (cursor.moveToNext()) {
|
||||||
val name = cursor.getString(nameColumn)
|
val name = cursor.getStringOrNull(nameColumn)
|
||||||
val size = cursor.getLong(sizeColumn)
|
val size = cursor.getLongOrNull(sizeColumn) ?: 0
|
||||||
var duration = 0L
|
var duration = 0L
|
||||||
|
|
||||||
context.contentResolver.openFileDescriptor(this, "r")?.use { pfd ->
|
context.contentResolver.openFileDescriptor(this, "r")?.use { pfd ->
|
||||||
|
@ -20,6 +20,8 @@ import android.content.Context
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
|
import androidx.core.database.getLongOrNull
|
||||||
|
import androidx.core.database.getStringOrNull
|
||||||
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -61,8 +63,8 @@ class ContactsDataSource @Inject constructor(
|
|||||||
val displayNameColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Contacts.DISPLAY_NAME) ?: return@use
|
val displayNameColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Contacts.DISPLAY_NAME) ?: return@use
|
||||||
val photoUriColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Data.PHOTO_URI)
|
val photoUriColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.Data.PHOTO_URI)
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
val id = cursor.getLong(idColumnIndex)
|
val id = cursor.getLongOrNull(idColumnIndex) ?: continue
|
||||||
val displayName = cursor.getString(displayNameColumnIndex)
|
val displayName = cursor.getStringOrNull(displayNameColumnIndex) ?: continue
|
||||||
|
|
||||||
val mappedContactBuilder = MappedContactBuilder(
|
val mappedContactBuilder = MappedContactBuilder(
|
||||||
id = id,
|
id = id,
|
||||||
@ -70,7 +72,7 @@ class ContactsDataSource @Inject constructor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
photoUriColumnIndex
|
photoUriColumnIndex
|
||||||
?.let { cursor.getString(it) }
|
?.let { cursor.getStringOrNull(it) }
|
||||||
?.let { Uri.parse(it) }
|
?.let { Uri.parse(it) }
|
||||||
?.let { mappedContactBuilder.photoURI = it }
|
?.let { mappedContactBuilder.photoURI = it }
|
||||||
|
|
||||||
@ -94,10 +96,10 @@ class ContactsDataSource @Inject constructor(
|
|||||||
val phoneNumberColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.CommonDataKinds.Phone.NUMBER) ?: return@use
|
val phoneNumberColumnIndex = cursor.getColumnIndexOrNull(ContactsContract.CommonDataKinds.Phone.NUMBER) ?: return@use
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
val mappedContactBuilder = cursor.getLong(idColumnIndex)
|
val mappedContactBuilder = cursor.getLongOrNull(idColumnIndex)
|
||||||
.let { map[it] }
|
?.let { map[it] }
|
||||||
?: continue
|
?: continue
|
||||||
cursor.getString(phoneNumberColumnIndex)
|
cursor.getStringOrNull(phoneNumberColumnIndex)
|
||||||
?.let {
|
?.let {
|
||||||
mappedContactBuilder.msisdns.add(
|
mappedContactBuilder.msisdns.add(
|
||||||
MappedMsisdn(
|
MappedMsisdn(
|
||||||
@ -128,10 +130,10 @@ class ContactsDataSource @Inject constructor(
|
|||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
// This would allow you get several email addresses
|
// This would allow you get several email addresses
|
||||||
// if the email addresses were stored in an array
|
// if the email addresses were stored in an array
|
||||||
val mappedContactBuilder = cursor.getLong(idColumnIndex)
|
val mappedContactBuilder = cursor.getLongOrNull(idColumnIndex)
|
||||||
.let { map[it] }
|
?.let { map[it] }
|
||||||
?: continue
|
?: continue
|
||||||
cursor.getString(emailColumnIndex)
|
cursor.getStringOrNull(emailColumnIndex)
|
||||||
?.let {
|
?.let {
|
||||||
mappedContactBuilder.emails.add(
|
mappedContactBuilder.emails.add(
|
||||||
MappedEmail(
|
MappedEmail(
|
||||||
|
@ -19,6 +19,7 @@ package im.vector.app.core.intent
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
|
import androidx.core.database.getStringOrNull
|
||||||
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
import im.vector.lib.multipicker.utils.getColumnIndexOrNull
|
||||||
|
|
||||||
fun getFilenameFromUri(context: Context?, uri: Uri): String? {
|
fun getFilenameFromUri(context: Context?, uri: Uri): String? {
|
||||||
@ -27,7 +28,7 @@ fun getFilenameFromUri(context: Context?, uri: Uri): String? {
|
|||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
return cursor.getColumnIndexOrNull(OpenableColumns.DISPLAY_NAME)
|
return cursor.getColumnIndexOrNull(OpenableColumns.DISPLAY_NAME)
|
||||||
?.let { cursor.getString(it) }
|
?.let { cursor.getStringOrNull(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user