Challenge 2 - calling suspect's phone number

Thanks to asett and cstewart for the hint to look at chapter 33.

This is what I came up with.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

final Intent callContact = new Intent(Intent.ACTION_DIAL);
mCallSuspectButton = (Button) v.findViewById(R.id.call_suspect);
mCallSuspectButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Uri number = Uri.parse(“tel:” + mCrime.getPhone()); // the “tel:” is needed to start activity
callContact.setData(number);
startActivity(callContact);
}
});

    return v;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    ...
    } else if (requestCode == REQUEST_CONTACT && data != null) {
        // Get the suspect's name.
        String suspectName = getSuspectName(data);
        mCrime.setSuspect(suspectName);
        mSuspectButton.setText(suspectName);

       // Get the suspect's mobile phone (cell phone) number.
        if (hasContactPermission()) {
            updateSuspectPhone();
        } else {
            // This will call onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults).
            requestPermissions(CONTACTS_PERMISSIONS, REQUEST_CONTACTS_PERMISSIONS);
        }
    }
}


private String getSuspectName(Intent data) {
    Uri contactUri = data.getData();

    // Specify which fields you want your query to return values for
    String[] queryFields = new String[] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME
    };

    // Perform your query - the contactUri is like a "where" clause here.
    Cursor c = getActivity().getContentResolver()
            .query(contactUri, queryFields, null, null, null);

    try {
        // Double-check that you actually got results.
        if (c.getCount() == 0) {
            return null;
        }

        // Pull out the first column of the first row of data -
        // that is your suspect's name
        c.moveToFirst();

        mSuspectId = c.getString(0);
        String suspectName = c.getString(1);
        return suspectName;
    } finally {
        c.close();
    }
}

private String getSuspectPhoneNumber(String contactId) {
    String suspectPhoneNumber = null;

    // The content URI of the CommonDataKinds.Phone
    Uri phoneContactUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

    // The columns to return for each row
    String[] queryFields = new String[] {
            ContactsContract.Data.CONTACT_ID,
            ContactsContract.CommonDataKinds.Phone.NUMBER,   // which is the default phone number.
            ContactsContract.CommonDataKinds.Phone.TYPE,
    };

    // Selection criteria
    String mSelectionClause = ContactsContract.Data.CONTACT_ID + " = ?";

    // Selection criteria
    String[] mSelectionArgs = {""};
    mSelectionArgs[0] = contactId;

    // Does a query against the table and returns a Cursor object
    Cursor c = getActivity().getContentResolver()
            .query(phoneContactUri,queryFields, mSelectionClause, mSelectionArgs, null );

    try {
        // Double-check that you actually got results.
        if (c.getCount() == 0) {
            return null;
        }

        while (c.moveToNext()) {
            int phoneType = c.getInt(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
            if (phoneType == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) {
                suspectPhoneNumber = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
                break;
            }
        }
    } finally {
        c.close();
    }

    return suspectPhoneNumber;
}

private void updateSuspectPhone () {
    String suspectPhoneNumber = getSuspectPhoneNumber(mSuspectId);
    mCrime.setPhone(suspectPhoneNumber);
}

private boolean hasContactPermission() {
    int result = ContextCompat.checkSelfPermission(getActivity(), CONTACTS_PERMISSIONS[0]);
    return result == PackageManager.PERMISSION_GRANTED;
}

public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CONTACTS_PERMISSIONS:
            if (hasContactPermission()) {
                updateSuspectPhone();
            }
    }
}

}

I haven’t included changed to he model to incorporate the suspect’s phone number. I’ll assume you know how to work this out. I did this to avoid introducing an annoying bug when making the phone call to the suspect. At the beginning I didn’t change the model but it became apparent that to focus on what I was supposed to be learning from this challenge I did need to change the model at some stage.

For runtime permissions - refer to https://developer.android.com/training/permissions/requesting.html

Cheers

1 Like

Thank you for the help, I had a really hard time with this challenge. Did you ever get an issue with the number coming back as incorrect? The number returned for me is 685-5 regardless of the contact I pick.

1 Like

i was having the same issue, but i added new Column to the DB that contains the value of phone number and the issue with 6855 disappeared and every time it picks the right number :slight_smile:

1 Like

Hello, thanks a lot for your solution. Was just wondering as to how you managed to get the code to query the CommonDataKinds.Phone table. I found the information listed in the android developer website not very useful and could not even begin to understand how to go about solving this challenge.

For instance, how did you know you had to include “ContactsContract.CommonDataKinds.Phone.TYPE” as one of the query fields ?

Thanks in advance!

I’ve also got the following error when running your code which I think is because the mSuspectId variable is null. May I know what is the best way to use the mSuspectId variable obtained from the getSuspectName method and using it to find the contact number? I can’t seem to get it when using your code.

2021-08-28 13:41:19.242 24199-24199/com.example.criminalintent E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.criminalintent, PID: 24199
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=131074, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.criminalintent/com.example.criminalintent.CrimePagerActivity}: java.lang.IllegalArgumentException: the bind value at index 1 is null
      **com.example.criminalintent.CrimeFragment.getSuspectPhoneNumber(CrimeFragment.java:302)**
**        at com.example.criminalintent.CrimeFragment.updateSuspectNumber(CrimeFragment.java:322)**
**        at com.example.criminalintent.CrimeFragment.onRequestPermissionsResult(CrimeFragment.java:337)**