Challenge: Another Implicit Intent - Solution

Hi guys,

I want to share with you my proposed solution to this challenge, here is the steps:

1- create the UI elements
2- create a new field in Crime class: phone field where i’ll save the phone number of suspect

data class Crime(
@PrimaryKey val id: UUID = UUID.randomUUID(),
var title: String = “”,
var date: Date = Date(),
var isSolved: Boolean = false,
var suspect: String = “”,
var phone: String = “”)

3- In CrimeDatabase, i modified its version and added a new Migration object to it

@Database(entities = [Crime::class], version = 3)
abstract class CrimeDatabase : RoomDatabase() {
abstract fun crimeDao(): CrimeDao
val migration_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {

4- To apply this migration, i added it in the crimeRepository when creating the database

class CrimeRepository private constructor(context: Context){

private val database: CrimeDatabase= Room.databaseBuilder(


After finishing with the model layer, i will change the CrimeFragment,
5- i create the callSuspectButton object, then i get its reference in onCreateView

callSuspectButton = view.findViewById( as Button

6- To get the suspect phone number , i modified the overrided function onActivityResult (Here is the central part of this challenge):

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    when {
        resultCode != Activity.RESULT_OK -> return

        requestCode == REQUEST_CONTACT && data != null -> {

            val contactUri: Uri? =
     // queryFieldsName: a List to return the DISPLAY_NAME Column Only
            queryFieldsName = arrayOf(ContactsContract.Contacts.DISPLAY_NAME)

     // queryFieldsId: a List to return the _ID Column Only, i will use it to get the suspect Id
            val queryFieldsId = arrayOf(ContactsContract.Contacts._ID)

            val cursorName = requireActivity().contentResolver
                .query(contactUri!!, queryFieldsName, null, null, null)
            cursorName?.use {
                if (it.count == 0) {

                val suspect = it.getString(0)
                crime.suspect = suspect
                suspectButton.text = suspect

      // I created another Cursor to get the suspect Id 
            val cursorId = requireActivity().contentResolver
                .query(contactUri!!, queryFieldsId, null, null, null)
            cursorId?.use {
                if (it.count == 0) {

     // here i put the suspect Id in contactId to use it later (to get the phone number)
                val contactId = it.getString(0)

     // This is the Uri to get a Phone number
                val phoneURI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI

     // phoneNumberQueryFields: a List to return the PhoneNumber Column Only

                val phoneNumberQueryFields = arrayOf(ContactsContract.CommonDataKinds.Phone.NUMBER)

     // phoneWhereClause: A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself)
                val phoneWhereClause = "${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} = ?"

     // This val replace the question mark in the phoneWhereClause  val
                val phoneQueryParameters = arrayOf(contactId)

                val phoneCursor = requireActivity().contentResolver
                    .query(phoneURI, phoneNumberQueryFields, phoneWhereClause, phoneQueryParameters, null )

                phoneCursor?.use { cursorPhone ->
                    val phoneNumValue = cursorPhone.getString(0)

     // after retrieving the phone number i put it in the        
           = phoneNumValue

7- in onStart() function, i implementd an onClickListener on callSuspectButton

    callSuspectButton.setOnClickListener {
        val callContactIntent =
            Intent(Intent.ACTION_DIAL).apply {
                val phone =
                data = Uri.parse("tel:$phone")

  // this intent will call the phone number given in Uri.parse("tel:$phone")

I hope this solution help you in your challenge