Challenge 2 :: Phone Number shown in dialing app is wrong

Hi @cstewart,

I made a change to the DB schema to store the _ID of the suspect which I call later when creating the whereArgs array.
I was expecting the selected contact which has a mobile number of 650-123-1234 to show up in the dialing app screen, however it shows the number 900080005330 instead.

I have attached my project for your perusal

It is not the fault of SMS it is the Android OS. No other OS but Android displays the wrong contact. I have multiple incidences with my contacts. One example is my contacts with Veterans, multiple extensions therefore multiple dialing after the main number but the only number displayed is the one now that I did the capture the business card with before that it was the main number. When you can’t reach that party and you try to call again using the phone recent calls I will only get the business card number displayed but it won’t dial any of the rest of the dial pattern.

Android’s OS is so lame and what really sucks is this has been an ongoing problem, I’ve seen similar posts about this years old and Android either choose to ignore it or more than likely don’t care because the people responsible for it I am sure use a different OS, because if they didn’t it would have been taken care of the first time they saw it. Or they never call the same number with different extensions, is that even feasible.

Ethan Stark

Hi @EthanStark,
I appreciate the feedback as I am glad that I am not the only one facing the issue.
The point of my post is to get a clarification as to whether it is a coding error on my part or something else. In the past @cstewart has been immensely helpful in providing hints that resolved the issue and I am hoping he can come to my rescue in this case

Your code looks good to me. I’m not sure what the problem is.

Have you checked to see if you are getting back multiple results when you query for the phone number? Maybe there’s some invalid data in there? I’d use the debugger to see if you are getting more data back than you expect and that might give us a hint.

For example, I was looking at this solution where they filter out phone numbers based on type.

I’m only getting back one result however I think I found the issue.

I dumped the output of the cursor’s using the following code:

Within the onActivityResult method:

Cursor c = getActivity().getContentResolver()
                .query(contactUri, null, null, null, null);
Log.d("contactUri Cursor dump", DatabaseUtils.dumpCursorToString(c));

Within the dialSuspect method:

Cursor c = getActivity().getContentResolver()
                .query(phoneUri, null, null, null, null);
Log.d("phoneUri Cursor dump", DatabaseUtils.dumpCursorToString(c));

The _ID in the contactUri (ContactsContract.Contacts.CONTENT_URI) of the contact I wanted to dial was 3 however _ID of the same contact in the phoneUri (ContactsContract.CommonDataKinds.Phone.CONTENT_URI) was 1053.
Looking at the other columns in the two dumps I found that it may be better to use name_raw_contact_id which is 3 in both of the dumps

I added another contact to the phone book and switched back and forth between setting these contacts as the suspect and then dialing and confirmed that it brings up the correct number each time

Interesting. Thanks for posting the solution. :+1:

Thanks for posting the solution.

However, I faced the same problem but I use another solution from API Guides Contacts Provider which is using LOOKUP_KEY instead of _ID column. As mentioned:

The ContactsContract.Contacts table also has the column LOOKUP_KEY that is a “permanent” link to the contact row. Because the Contacts Provider maintains contacts automatically, it may change a contact row’s _ID value in response to an aggregation or sync. Even If this happens, the content URI CONTENT_LOOKUP_URI combined with contact’s LOOKUP_KEY will still point to the contact row, so you can use LOOKUP_KEY to maintain links to “favorite” contacts, and so forth. This column has its own format that is unrelated to the format of the _ID column.

Here is a subset of CrimeFragment.java that applying this solution:

@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != Activity.RESULT_OK) {
			return;
		}

		if (requestCode == REQUEST_DATE) {
			Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
			mCrime.setDate(date);
			updateDate();
		} else if (requestCode == REQUEST_CONTACT && data != null) {
			String contactLookupKey;
			Uri contactUri = data.getData();

			// Specify which field you want your query to return values for
			String[] queryFields = new String[] {
											ContactsContract.Contacts.LOOKUP_KEY,
											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 gor results
				if (c.getCount() == 0) {
					return;
				}

				// pull out the data of the first row that is your ID and suspect's name
				c.moveToFirst();
				int lookupColumn = c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
				int nameColumn = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);

				contactLookupKey = c.getString(lookupColumn);
				String suspect = c.getString(nameColumn);

				mCrime.setSuspect(suspect);
				mSuspectButton.setText(suspect);
			} finally {
				c.close();
			}

			/*
			 ** Now: find phone number
			 */

			contactUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
			queryFields = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };

			// Perform your query
			c = getActivity().getContentResolver()
					.query(contactUri,
							queryFields,
							ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY + " = ? ",   // where clause
							new String[] { contactLookupKey },   // where clause args
							null);  // sort by

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

				// pull out the data of the first row that is phone number
				c.moveToFirst();
				String phone = c.getString(0);

				mCallSuspectButton.setEnabled(true);
				mCrime.setPhoneNumber(phone);
			} finally {
				c.close();
			}

		}
	}

And finally, I use “public void dialPhoneNumber(String phoneNumber)” that I like it :star_struck: from API Guides Common Intents in a Button on click listener as:

mCallSuspectButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            dialPhoneNumber(mCrime.getPhoneNumber());
        }
    });

Hope this helps!
Thanks

Thanks for the tip on LOOKUP_KEY!

However since you are immediately using it to look up the phone number and store it in the Crime object, it isn’t delivering any value over _ID.

Instead of storing the phone number, store the LOOKUP_KEY. Then if the suspect changes their phone number, the Crime object will not be out of date.

1 Like

Thank you for the advice. I will consider it for future Apps.