fetch a list of available contacts at NewMessageActivity

This commit is contained in:
tibbi 2020-04-05 21:18:33 +02:00
parent d1f2046f2a
commit b67d2a8dfb
2 changed files with 156 additions and 0 deletions

View File

@ -1,9 +1,17 @@
package com.simplemobiletools.smsmessenger.activities package com.simplemobiletools.smsmessenger.activities
import android.database.Cursor
import android.os.Bundle import android.os.Bundle
import android.provider.ContactsContract
import android.provider.ContactsContract.CommonDataKinds
import android.text.TextUtils
import android.view.WindowManager import android.view.WindowManager
import com.simplemobiletools.commons.extensions.getIntValue
import com.simplemobiletools.commons.extensions.getStringValue
import com.simplemobiletools.commons.extensions.updateTextColors import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.models.Contact
import kotlinx.android.synthetic.main.activity_new_message.* import kotlinx.android.synthetic.main.activity_new_message.*
class NewMessageActivity : SimpleActivity() { class NewMessageActivity : SimpleActivity() {
@ -15,5 +23,118 @@ class NewMessageActivity : SimpleActivity() {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
new_message_to.requestFocus() new_message_to.requestFocus()
// Contact permission is not mandatory, but without it we won't be able to show any suggestions during typing
handlePermission(PERMISSION_READ_CONTACTS) {
initContacts()
}
}
private fun initContacts() {
val names = getNames()
val contacts = getPhoneNumbers()
contacts.forEach {
val contactId = it.contactId
val contact = names.firstOrNull { it.contactId == contactId }
val name = contact?.name
if (name != null) {
it.name = name
}
val photoUri = contact?.photoUri
if (photoUri != null) {
it.photoUri = photoUri
}
}
}
private fun getNames(): List<Contact> {
val contacts = ArrayList<Contact>()
val uri = ContactsContract.Data.CONTENT_URI
val projection = arrayOf(
ContactsContract.Data.CONTACT_ID,
CommonDataKinds.StructuredName.PREFIX,
CommonDataKinds.StructuredName.GIVEN_NAME,
CommonDataKinds.StructuredName.MIDDLE_NAME,
CommonDataKinds.StructuredName.FAMILY_NAME,
CommonDataKinds.StructuredName.SUFFIX,
CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI,
CommonDataKinds.Organization.COMPANY,
CommonDataKinds.Organization.TITLE,
ContactsContract.Data.MIMETYPE
)
val selection = "${ContactsContract.Data.MIMETYPE} = ? OR ${ContactsContract.Data.MIMETYPE} = ?"
val selectionArgs = arrayOf(
CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
CommonDataKinds.Organization.CONTENT_ITEM_TYPE
)
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor?.moveToFirst() == true) {
do {
val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE)
val photoUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: ""
val isPerson = mimetype == CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
if (isPerson) {
val prefix = cursor.getStringValue(CommonDataKinds.StructuredName.PREFIX) ?: ""
val firstName = cursor.getStringValue(CommonDataKinds.StructuredName.GIVEN_NAME) ?: ""
val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: ""
val familyName = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: ""
val suffix = cursor.getStringValue(CommonDataKinds.StructuredName.SUFFIX) ?: ""
if (firstName.isNotEmpty() || middleName.isNotEmpty() || familyName.isNotEmpty()) {
val names = arrayOf(prefix, firstName, middleName, familyName, suffix).filter { it.isNotEmpty() }
val fullName = TextUtils.join(" ", names)
val contact = Contact(id, fullName, photoUri, "")
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) ?: ""
if (company.isNotEmpty() || jobTitle.isNotEmpty()) {
val fullName = "$company $jobTitle".trim()
val contact = Contact(id, fullName, photoUri, "")
contacts.add(contact)
}
}
} while (cursor.moveToNext())
}
} catch (ignored: Exception) {
} finally {
cursor?.close()
}
return contacts
}
private fun getPhoneNumbers(): ArrayList<Contact> {
val contacts = ArrayList<Contact>()
val uri = CommonDataKinds.Phone.CONTENT_URI
val projection = arrayOf(
ContactsContract.Data.CONTACT_ID,
CommonDataKinds.Phone.NORMALIZED_NUMBER
)
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, null, null, null)
if (cursor?.moveToFirst() == true) {
do {
val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
val phoneNumber = cursor.getStringValue(CommonDataKinds.Phone.NORMALIZED_NUMBER) ?: continue
val contact = Contact(id, "", "", phoneNumber)
contacts.add(contact)
} while (cursor.moveToNext())
}
} catch (ignored: Exception) {
} finally {
cursor?.close()
}
return contacts
} }
} }

View File

@ -0,0 +1,35 @@
package com.simplemobiletools.smsmessenger.models
import android.content.Context
import android.graphics.drawable.Drawable
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
data class Contact(
val contactId: Int,
var name: String,
var photoUri: String,
var phoneNumber: String
) {
fun updateImage(context: Context, imageView: ImageView, placeholder: Drawable) {
if (photoUri.isEmpty()) {
imageView.setImageDrawable(placeholder)
} else {
val options = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(placeholder)
.centerCrop()
Glide.with(context)
.load(photoUri)
.transition(DrawableTransitionOptions.withCrossFade())
.placeholder(placeholder)
.apply(options)
.apply(RequestOptions.circleCropTransform())
.into(imageView)
}
}
}