194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/* 294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Copyright (C) 2011 The Android Open Source Project 394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * in compliance with the License. You may obtain a copy of the License at 694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * http://www.apache.org/licenses/LICENSE-2.0 894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * Unless required by applicable law or agreed to in writing, software distributed under the License 1056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * or implied. See the License for the specific language governing permissions and limitations under 1256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * the License. 1394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 1494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpackage com.android.dialer.calllog; 1694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.Context; 1894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.database.Cursor; 1994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.net.Uri; 2058ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport android.provider.ContactsContract; 2158ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport android.provider.ContactsContract.CommonDataKinds.Phone; 2294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.Contacts; 2358ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport android.provider.ContactsContract.DisplayNameSources; 2494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.PhoneLookup; 2594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.telephony.PhoneNumberUtils; 2694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.TextUtils; 2794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 2858ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport com.android.contacts.common.util.Constants; 2937d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Leeimport com.android.contacts.common.util.PhoneNumberHelper; 3035071c06d1587942f5a66c8f12e6247e8f904d26Chiao Chengimport com.android.contacts.common.util.UriUtils; 31034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Leeimport com.android.dialer.service.CachedNumberLookupService; 32c089b0d2b1bf1bd511cd54dc51d9186b6ce41681Jay Shraunerimport com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; 33704acc087ce359295475a46695c2821c55778344Chiao Chengimport com.android.dialerbind.ObjectFactory; 3494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 3558ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport org.json.JSONException; 3658ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport org.json.JSONObject; 3758ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee 3856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Leeimport java.util.List; 3956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee 4094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/** 4194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Utility class to look up the contact information for a given number. 4294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 4394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpublic class ContactInfoHelper { 4494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final Context mContext; 4594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final String mCurrentCountryIso; 4694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 47034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee private static final CachedNumberLookupService mCachedNumberLookupService = 48704acc087ce359295475a46695c2821c55778344Chiao Cheng ObjectFactory.newCachedNumberLookupService(); 49034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee 5094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public ContactInfoHelper(Context context, String currentCountryIso) { 5194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContext = context; 5294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCurrentCountryIso = currentCountryIso; 5394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 5494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 5594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 5694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Returns the contact information for the given number. 5794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 5894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If the number does not match any contact, returns a contact info containing only the number 5994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * and the formatted number. 6094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 6194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If an error occurs during the lookup, it returns null. 6294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 6394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @param number the number to look up 6494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @param countryIso the country associated with this number 6594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 6694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public ContactInfo lookupNumber(String number, String countryIso) { 6794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final ContactInfo info; 6894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 6994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Determine the contact info. 7037d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee if (PhoneNumberHelper.isUriNumber(number)) { 7194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This "number" is really a SIP address. 7294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ContactInfo sipInfo = queryContactInfoForSipAddress(number); 7394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (sipInfo == null || sipInfo == ContactInfo.EMPTY) { 7494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Check whether the "username" part of the SIP address is 7594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // actually the phone number of a contact. 7637d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee String username = PhoneNumberHelper.getUsernameFromUriNumber(number); 7794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (PhoneNumberUtils.isGlobalPhoneNumber(username)) { 7894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng sipInfo = queryContactInfoForPhoneNumber(username, countryIso); 7994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 8094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 8194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info = sipInfo; 8294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 8394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Look for a contact that has the given phone number. 8494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ContactInfo phoneInfo = queryContactInfoForPhoneNumber(number, countryIso); 8594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 8694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (phoneInfo == null || phoneInfo == ContactInfo.EMPTY) { 8794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Check whether the phone number has been saved as an "Internet call" number. 8894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng phoneInfo = queryContactInfoForSipAddress(number); 8994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 9094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info = phoneInfo; 9194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 9294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final ContactInfo updatedInfo; 9494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (info == null) { 9594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The lookup failed. 9694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng updatedInfo = null; 9794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 9894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If we did not find a matching contact, generate an empty contact info for the number. 9994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (info == ContactInfo.EMPTY) { 10094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Did not find a matching contact. 10194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng updatedInfo = new ContactInfo(); 10294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng updatedInfo.number = number; 10394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso); 104746dba885dc50c9f723456b01cfc7dbfcc9a49b0Tyler Gunn updatedInfo.normalizedNumber = PhoneNumberUtils.formatNumberToE164( 105746dba885dc50c9f723456b01cfc7dbfcc9a49b0Tyler Gunn number, countryIso); 10656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee updatedInfo.lookupUri = createTemporaryContactUri(updatedInfo.formattedNumber); 10794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 10894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng updatedInfo = info; 10994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 11094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 11194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return updatedInfo; 11294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 11394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 11494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 11558ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee * Creates a JSON-encoded lookup uri for a unknown number without an associated contact 11658ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee * 11758ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee * @param number - Unknown phone number 11856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * @return JSON-encoded URI that can be used to perform a lookup when clicking on the quick 11956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * contact card. 12058ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee */ 12158ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee private static Uri createTemporaryContactUri(String number) { 12258ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee try { 12356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee final JSONObject contactRows = new JSONObject().put(Phone.CONTENT_ITEM_TYPE, 12456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee new JSONObject().put(Phone.NUMBER, number).put(Phone.TYPE, Phone.TYPE_CUSTOM)); 12558ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee 12656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee final String jsonString = new JSONObject().put(Contacts.DISPLAY_NAME, number) 12756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.PHONE) 12856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee .put(Contacts.CONTENT_ITEM_TYPE, contactRows).toString(); 12958ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee 13056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee return Contacts.CONTENT_LOOKUP_URI 13156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee .buildUpon() 13258ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee .appendPath(Constants.LOOKUP_URI_ENCODED) 13358ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, 13458ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee String.valueOf(Long.MAX_VALUE)) 13595b2537946f2af718122a796662b025206cffd91Yorke Lee .encodedFragment(jsonString) 13658ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee .build(); 13758ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee } catch (JSONException e) { 13858ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee return null; 13958ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee } 14058ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee } 14158ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee 14258ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee /** 14394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Looks up a contact using the given URI. 14494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 14594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is 14694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * found, or the {@link ContactInfo} for the given contact. 14794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 14894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned 14994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * value. 15094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 15194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ContactInfo lookupContactFromUri(Uri uri) { 15294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final ContactInfo info; 15394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Cursor phonesCursor = 15456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee mContext.getContentResolver().query(uri, PhoneQuery._PROJECTION, null, null, null); 15594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 15694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (phonesCursor != null) { 15794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng try { 15894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (phonesCursor.moveToFirst()) { 15994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info = new ContactInfo(); 16094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID); 16194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY); 16256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee info.lookupKey = lookupKey; 16394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.lookupUri = Contacts.getLookupUri(contactId, lookupKey); 16494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.name = phonesCursor.getString(PhoneQuery.NAME); 16594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE); 16694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.label = phonesCursor.getString(PhoneQuery.LABEL); 16794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.number = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER); 16894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.normalizedNumber = phonesCursor.getString(PhoneQuery.NORMALIZED_NUMBER); 16994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID); 17094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.photoUri = 17194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng UriUtils.parseUriOrNull(phonesCursor.getString(PhoneQuery.PHOTO_URI)); 17294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.formattedNumber = null; 17394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 17494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info = ContactInfo.EMPTY; 17594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 17694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } finally { 17794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng phonesCursor.close(); 17894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 17994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 18094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Failed to fetch the data, ignore this request. 18194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info = null; 18294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 18394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return info; 18494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 18594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 18694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 18794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Determines the contact information for the given SIP address. 18894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 18994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It returns the contact info if found. 19094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 19194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If no contact corresponds to the given SIP address, returns {@link ContactInfo#EMPTY}. 19294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 19394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If the lookup fails for some other reason, it returns null. 19494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 19594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ContactInfo queryContactInfoForSipAddress(String sipAddress) { 19694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final ContactInfo info; 19794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 19894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // "contactNumber" is a SIP address, so use the PhoneLookup table with the SIP parameter. 19994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Uri.Builder uriBuilder = PhoneLookup.CONTENT_FILTER_URI.buildUpon(); 20094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng uriBuilder.appendPath(Uri.encode(sipAddress)); 20194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng uriBuilder.appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1"); 20294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return lookupContactFromUri(uriBuilder.build()); 20394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 20494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 20594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 20694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Determines the contact information for the given phone number. 20794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 20894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It returns the contact info if found. 20994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 21094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If no contact corresponds to the given phone number, returns {@link ContactInfo#EMPTY}. 21194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 21294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If the lookup fails for some other reason, it returns null. 21394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 21494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso) { 21594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng String contactNumber = number; 21694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (!TextUtils.isEmpty(countryIso)) { 21794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Normalize the number: this is needed because the PhoneLookup query below does not 21894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // accept a country code as an input. 21994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng String numberE164 = PhoneNumberUtils.formatNumberToE164(number, countryIso); 22094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (!TextUtils.isEmpty(numberE164)) { 22194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Only use it if the number could be formatted to E164. 22294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng contactNumber = numberE164; 22394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 22494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 22594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 22694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The "contactNumber" is a regular phone number, so use the PhoneLookup table. 22794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactNumber)); 22894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ContactInfo info = lookupContactFromUri(uri); 22994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (info != null && info != ContactInfo.EMPTY) { 23094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng info.formattedNumber = formatPhoneNumber(number, null, countryIso); 231034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee } else if (mCachedNumberLookupService != null) { 23256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee CachedContactInfo cacheInfo = 23356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee mCachedNumberLookupService.lookupCachedContactFromNumber(mContext, number); 234ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati if (cacheInfo != null) { 235ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati info = cacheInfo.getContactInfo().isBadData ? null : cacheInfo.getContactInfo(); 236ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati } else { 237ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati info = null; 238ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati } 23994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 24094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return info; 24194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 24294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 24394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 24494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Format the given phone number 24594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 24694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @param number the number to be formatted. 24794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @param normalizedNumber the normalized number of the given number. 24856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * @param countryIso the ISO 3166-1 two letters country code, the country's convention will be 24956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * used to format the number if the normalized phone is null. 25094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 25194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @return the formatted number, or the given number if it was formatted. 25294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 25356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee private String formatPhoneNumber(String number, String normalizedNumber, String countryIso) { 25494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(number)) { 25594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return ""; 25694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 25794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If "number" is really a SIP address, don't try to do any formatting at all. 25837d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee if (PhoneNumberHelper.isUriNumber(number)) { 25994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return number; 26094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 26194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(countryIso)) { 26294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng countryIso = mCurrentCountryIso; 26394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 26494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso); 26594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 26656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee 26756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee /** 26856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * Parses the given URI to determine the original lookup key of the contact. 26956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee */ 27056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee public static String getLookupKeyFromUri(Uri lookupUri) { 27156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee // Would be nice to be able to persist the lookup key somehow to avoid having to parse 27256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee // the uri entirely just to retrieve the lookup key, but every uri is already parsed 27356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee // once anyway to check if it is an encoded JSON uri, so this has negligible effect 27456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee // on performance. 27556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee if (lookupUri != null && !UriUtils.isEncodedContactUri(lookupUri)) { 27656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee final List<String> segments = lookupUri.getPathSegments(); 27756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee // This returns the third path segment of the uri, where the lookup key is located. 27856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee // See {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}. 279774c0a924d00544e40a61a6d3bd13e967c5fd428Yorke Lee return (segments.size() < 3) ? null : Uri.encode(segments.get(2)); 28056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee } else { 28156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee return null; 28256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee } 28356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee } 28456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee 28556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee /** 28656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * Given a contact's sourceType, return true if the contact is a business 28756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * 28856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * @param sourceType sourceType of the contact. This is usually populated by 28956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * {@link #mCachedNumberLookupService}. 29056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee */ 29156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee public boolean isBusiness(int sourceType) { 292b98da724ee52d0ff63739998c8d72d0fc9cabfa6Yorke Lee return mCachedNumberLookupService != null 293b98da724ee52d0ff63739998c8d72d0fc9cabfa6Yorke Lee && mCachedNumberLookupService.isBusiness(sourceType); 29456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee } 295b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati 296b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati /** 29755733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee * This function looks at a contact's source and determines if the user can 29855733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee * mark caller ids from this source as invalid. 299b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati * 30055733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee * @param sourceType The source type to be checked 30155733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee * @param objectId The ID of the Contact object. 30255733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee * @return true if contacts from this source can be marked with an invalid caller id 303b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati */ 30455733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee public boolean canReportAsInvalid(int sourceType, String objectId) { 305b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati return mCachedNumberLookupService != null 30655733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee && mCachedNumberLookupService.canReportAsInvalid(sourceType, objectId); 307b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati } 30855733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee 30955733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee 31094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng} 311