public void testLookupUri() throws Exception { TestRawContact rawContact = mBuilder.newRawContact().insert().load(); TestContact contact = rawContact.getContact().load(); Uri contactUri = contact.getUri(); long contactId = contact.getId(); String lookupKey = contact.getString(Contacts.LOOKUP_KEY); Uri lookupUri = Contacts.getLookupUri(contactId, lookupKey); assertEquals( ContentUris.withAppendedId( Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), contactId), lookupUri); Uri nullLookupUri = Contacts.getLookupUri(contactId, null); assertNull(nullLookupUri); Uri emptyLookupUri = Contacts.getLookupUri(contactId, ""); assertNull(emptyLookupUri); Uri lookupUri2 = Contacts.getLookupUri(mResolver, contactUri); assertEquals(lookupUri, lookupUri2); Uri contactUri2 = Contacts.lookupContact(mResolver, lookupUri); assertEquals(contactUri, contactUri2); }
private @NonNull RecipientDetails getIndividualRecipientDetails( Context context, long recipientId, String number) { Optional<RecipientsPreferences> preferences = DatabaseFactory.getRecipientPreferenceDatabase(context) .getRecipientsPreferences(new long[] {recipientId}); MaterialColor color = preferences.isPresent() ? preferences.get().getColor() : null; Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION, null, null, null); try { if (cursor != null && cursor.moveToFirst()) { Uri contactUri = Contacts.getLookupUri(cursor.getLong(2), cursor.getString(1)); String name = cursor.getString(3).equals(cursor.getString(0)) ? null : cursor.getString(0); ContactPhoto contactPhoto = ContactPhotoFactory.getContactPhoto( context, Uri.withAppendedPath(Contacts.CONTENT_URI, cursor.getLong(2) + ""), name); return new RecipientDetails( cursor.getString(0), cursor.getString(3), contactUri, contactPhoto, color); } } finally { if (cursor != null) cursor.close(); } return new RecipientDetails( null, number, null, ContactPhotoFactory.getDefaultContactPhoto(null), color); }
@Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { CheckBox checkbox = (CheckBox) v.findViewWithTag(position); if (checkbox.isChecked()) checkbox.setChecked(false); else checkbox.setChecked(true); // Gets the Cursor object currently bound to the ListView final Cursor cursor = mAdapter.getCursor(); // Moves to the Cursor row corresponding to the ListView item that was // clicked cursor.moveToPosition(position); // Creates a contact lookup Uri from contact ID and lookup_key final Uri uri = Contacts.getLookupUri( cursor.getLong(ContactsQuery.ID), cursor.getString(ContactsQuery.LOOKUP_KEY)); // Notifies the parent activity that the user selected a contact. In a // two-pane layout, the // parent activity loads a ContactDetailFragment that displays the // details for the selected // contact. In a single-pane layout, the parent activity starts a new // activity that // displays contact details in its own Fragment. mOnContactSelectedListener.onContactSelected(uri); // If two-pane layout sets the selected item to checked so it remains // highlighted. In a // single-pane layout a new activity is started so this is not needed. }
@SuppressLint("InlinedApi") public static ArrayList<Message_Thread> allMessage_Thread(Context context) { ArrayList<Integer> has = new ArrayList<Integer>(); ArrayList<Message_Thread> list = new ArrayList<Message_Thread>(); String[] projection = new String[] {Sms.THREAD_ID, Sms.DATE, Sms.BODY, Sms.READ, Sms.ADDRESS}; String selection = null; String[] selectionArgs = null; String sortOrder = Sms.DATE + " desc"; Cursor cursor = context .getContentResolver() .query(sms_uri, projection, selection, selectionArgs, sortOrder); while (cursor.moveToNext()) { int thread_id = cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID)); if (has.contains(thread_id)) { continue; } has.add(thread_id); long thread_date = cursor.getLong(cursor.getColumnIndex(Sms.DATE)); String thread_snippet = cursor.getString(cursor.getColumnIndex(Sms.BODY)); int thread_read = cursor.getInt(cursor.getColumnIndex(Sms.READ)); String phone = cursor.getString(cursor.getColumnIndex(Sms.ADDRESS)); String name = ""; byte[] photo = null; if (phone != null) { phone = phone.replace("+86", ""); } // <------------ 通过phone查找头像、姓名 ---------------> Uri uriNumber2Contacts = Uri.parse("content://com.android.contacts/data/phones/filter/" + phone); Cursor cursorCantacts = context.getContentResolver().query(uriNumber2Contacts, null, null, null, null); if (cursorCantacts.getCount() > 0) { // 若游标不为0则说明有头像,游标指向第一条记录 cursorCantacts.moveToFirst(); Long contactID = cursorCantacts.getLong(cursorCantacts.getColumnIndex("contact_id")); name = cursorCantacts.getString(cursorCantacts.getColumnIndex(Contacts.DISPLAY_NAME)); Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactID); InputStream input = Contacts.openContactPhotoInputStream(context.getContentResolver(), uri); if (input != null) { try { photo = toByteArray(input); } catch (IOException e) { e.printStackTrace(); } } } Message_Thread thread = new Message_Thread( thread_id, thread_date, 0, thread_snippet, thread_read, name, phone, photo); list.add(thread); cursorCantacts.close(); } cursor.close(); return list; }
public Member( long rawContactId, String lookupKey, long contactId, String displayName, String photoUri) { mRawContactId = rawContactId; mContactId = contactId; mLookupKey = lookupKey; mLookupUri = Contacts.getLookupUri(contactId, lookupKey); mDisplayName = displayName; mPhotoUri = (photoUri != null) ? Uri.parse(photoUri) : null; }
public void testMarkAsContacted() throws Exception { TestRawContact rawContact = mBuilder.newRawContact().insert().load(); TestContact contact = rawContact.getContact().load(); long oldLastContacted = contact.getLong(Contacts.LAST_TIME_CONTACTED); Contacts.markAsContacted(mResolver, contact.getId()); contact.load(); // Reload long lastContacted = contact.getLong(Contacts.LAST_TIME_CONTACTED); assertTrue(oldLastContacted < lastContacted); oldLastContacted = lastContacted; Contacts.markAsContacted(mResolver, contact.getId()); contact.load(); lastContacted = contact.getLong(Contacts.LAST_TIME_CONTACTED); assertTrue(oldLastContacted < lastContacted); }
@Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // Gets the Cursor object currently bound to the ListView final Cursor cursor = mAdapter.getCursor(); // Moves to the Cursor row corresponding to the ListView item that was clicked cursor.moveToPosition(position); // Creates a contact lookup Uri from contact ID and lookup_key final Uri uri = Contacts.getLookupUri( cursor.getLong(ContactsQuery.ID), cursor.getString(ContactsQuery.LOOKUP_KEY)); // NOTIFIES THE PARENT ACTIVITY that the user selected a contact. Then the parent activity // starts a new activity that // displays contact details in its own Fragment. mOnContactSelectedListener.onContactSelected(uri); }
/* * Load the avatar data from the cursor into memory. Don't decode the data * until someone calls for it (see getAvatar). Hang onto the raw data so that * we can compare it when the data is reloaded. * TODO: consider comparing a checksum so that we don't have to hang onto * the raw bytes after the image is decoded. */ private byte[] loadAvatarData(Contact entry) { byte[] data = null; if ((!entry.mIsMe && entry.mPersonId == 0) || entry.mAvatar != null) { return null; } if (Log.isLoggable(LogTag.CONTACT, Log.DEBUG)) { log("loadAvatarData: name=" + entry.mName + ", number=" + entry.mNumber); } // If the contact is "me", then use my local profile photo. Otherwise, build a // uri to get the avatar of the contact. Uri contactUri = entry.mIsMe ? Profile.CONTENT_URI : ContentUris.withAppendedId(Contacts.CONTENT_URI, entry.mPersonId); InputStream avatarDataStream = Contacts.openContactPhotoInputStream(mContext.getContentResolver(), contactUri); try { if (avatarDataStream != null) { data = new byte[avatarDataStream.available()]; avatarDataStream.read(data, 0, data.length); } } catch (IOException ex) { // } finally { try { if (avatarDataStream != null) { avatarDataStream.close(); } } catch (IOException e) { } } return data; }
public Bitmap getSystemAvatarViaSystemContactId(long systemContactId) { if (systemContactId <= 0) { NmsLog.error(TAG, "getSystemAvatarViaSystemContactId. sysContactId is invalid!"); return null; } Bitmap result = null; Cursor cursor = null; try { cursor = NmsContentResolver.query( mContext.getContentResolver(), Contacts.CONTENT_URI, new String[] {Contacts.PHOTO_ID}, Contacts._ID + "=?", new String[] {String.valueOf(systemContactId)}, null); if (cursor != null && cursor.moveToFirst()) { long photoId = cursor.getLong(cursor.getColumnIndex(Contacts.PHOTO_ID)); if (photoId > 0) { Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, systemContactId); InputStream input = Contacts.openContactPhotoInputStream(mContext.getContentResolver(), uri); result = BitmapFactory.decodeStream(input); } } } catch (Exception e) { NmsLog.nmsPrintStackTrace(e); } finally { if (cursor != null) { cursor.close(); cursor = null; } } return result; }
/** Binds data from the Cursor to the provided view. */ @Override public void bindView(View view, Context context, Cursor cursor) { // Gets handles to individual view resources final ViewHolder holder = (ViewHolder) view.getTag(); // For Android 3.0 and later, gets the thumbnail image Uri from the current Cursor row. // For platforms earlier than 3.0, this isn't necessary, because the thumbnail is // generated from the other fields in the row. final String photoUri = cursor.getString(ContactsQuery.PHOTO_THUMBNAIL_DATA); final String displayName = cursor.getString(ContactsQuery.DISPLAY_NAME); final int startIndex = indexOfSearchQuery(displayName); if (startIndex == -1) { // If the user didn't do a search, or the search string didn't match a display // name, show the display name without highlighting holder.text1.setText(displayName); if (TextUtils.isEmpty(mSearchTerm)) { // If the search search is empty, hide the second line of text holder.text2.setVisibility(View.GONE); } else { // Shows a second line of text that indicates the search string matched // something other than the display name holder.text2.setVisibility(View.VISIBLE); } } else { // If the search string matched the display name, applies a SpannableString to // highlight the search string with the displayed display name // Wraps the display name in the SpannableString final SpannableString highlightedName = new SpannableString(displayName); // Sets the span to start at the starting point of the match and end at "length" // characters beyond the starting point highlightedName.setSpan( highlightTextSpan, startIndex, startIndex + mSearchTerm.length(), 0); // Binds the SpannableString to the display name View object holder.text1.setText(highlightedName); // Since the search string matched the name, this hides the secondary message holder.text2.setVisibility(View.GONE); } // Processes the QuickContactBadge. A QuickContactBadge first appears as a contact's // thumbnail image with styling that indicates it can be touched for additional // information. When the user clicks the image, the badge expands into a dialog box // containing the contact's details and icons for the built-in apps that can handle // each detail type. // Generates the contact lookup Uri final Uri contactUri = Contacts.getLookupUri( cursor.getLong(ContactsQuery.ID), cursor.getString(ContactsQuery.LOOKUP_KEY)); // Binds the contact's lookup Uri to the QuickContactBadge holder.icon.assignContactUri(contactUri); // Loads the thumbnail image pointed to by photoUri into the QuickContactBadge in a // background worker thread mImageLoader.loadImage(photoUri, holder.icon); }
@Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { try { if (this != mQueryHandler) { Log.d(TAG, "onQueryComplete: discard result, the query handler is reset!"); return; } if (ConfirmAddDetailActivity.this.isFinishing()) { return; } switch (token) { case TOKEN_PHOTO_QUERY: { // Set the photo Bitmap photoBitmap = null; if (cursor != null && cursor.moveToFirst() && !cursor.isNull(PhotoQuery.PHOTO)) { byte[] photoData = cursor.getBlob(PhotoQuery.PHOTO); photoBitmap = BitmapFactory.decodeByteArray(photoData, 0, photoData.length, null); } if (photoBitmap != null) { mPhotoView.setImageBitmap(photoBitmap); } break; } case TOKEN_CONTACT_INFO: { // Set the contact's name if (cursor != null && cursor.moveToFirst()) { // Get the cursor values mDisplayName = cursor.getString(ContactQuery.DISPLAY_NAME); final long photoId = cursor.getLong(ContactQuery.PHOTO_ID); // If there is no photo ID, then do a disambiguation // query because other contacts could have the same // name as this contact. if (photoId == 0) { mContactId = cursor.getLong(ContactQuery._ID); startDisambiguationQuery(mDisplayName); } else { // Otherwise do the photo query. Uri lookupUri = Contacts.getLookupUri(mContactId, cursor.getString(ContactQuery.LOOKUP_KEY)); startPhotoQuery(photoId, lookupUri); // Display the name because there is no // disambiguation query. setDisplayName(); showDialogContent(); } } break; } case TOKEN_DISAMBIGUATION_QUERY: { // If a cursor was returned with more than 0 results, // then at least one other contact exists with the same // name as this contact. Extra info on this contact must // be displayed to disambiguate the contact, so retrieve // those additional fields. Otherwise, no other contacts // with this name exists, so do nothing further. if (cursor != null && cursor.getCount() > 0) { startExtraInfoQuery(); } else { // If there are no other contacts with this name, // then display the name. setDisplayName(); showDialogContent(); } break; } case TOKEN_EXTRA_INFO_QUERY: { // This case should only occur if there are one or more // other contacts with the same contact name. if (cursor != null && cursor.moveToFirst()) { HashMap<String, String> hashMapCursorData = new HashMap<String, String>(); // Convert the cursor data into a hashmap of // (mimetype, data value) pairs. If a contact has // multiple values with the same mimetype, it's fine // to override that hashmap entry because we only // need one value of that type. while (!cursor.isAfterLast()) { final String mimeType = cursor.getString(ExtraInfoQuery.MIMETYPE); if (!TextUtils.isEmpty(mimeType)) { String value = cursor.getString(ExtraInfoQuery.DATA1); if (!TextUtils.isEmpty(value)) { // As a special case, phone numbers // should be formatted in a specific way. if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) { value = PhoneNumberUtils.formatNumber(value); } hashMapCursorData.put(mimeType, value); } } cursor.moveToNext(); } // Find the first non-empty field according to the // mimetype priority list and display this under the // contact's display name to disambiguate the contact. for (String mimeType : MIME_TYPE_PRIORITY_LIST) { if (hashMapCursorData.containsKey(mimeType)) { setDisplayName(); setExtraInfoField(hashMapCursorData.get(mimeType)); break; } } showDialogContent(); } break; } } } finally { if (cursor != null) { cursor.close(); } } }
private static Cursor getCursorForConstruction( Context context, long contactId, Long directoryId, String lookupKey, int queryType) { final Cursor cursor; final String desiredMimeType; if (queryType == QUERY_TYPE_EMAIL) { final Uri uri; final StringBuilder selection = new StringBuilder(); selection.append(Queries.EMAIL.getProjection()[Queries.Query.CONTACT_ID]); selection.append(" = ?"); if (directoryId == null || lookupKey == null) { uri = Queries.EMAIL.getContentUri(); desiredMimeType = null; } else { final Uri.Builder builder = Contacts.getLookupUri(contactId, lookupKey).buildUpon(); builder .appendPath(Contacts.Entity.CONTENT_DIRECTORY) .appendQueryParameter( ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)); uri = builder.build(); desiredMimeType = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE; } cursor = context .getContentResolver() .query( uri, Queries.EMAIL.getProjection(), selection.toString(), new String[] {String.valueOf(contactId)}, null); } else { final Uri uri; final StringBuilder selection = new StringBuilder(); selection.append(Queries.PHONE.getProjection()[Queries.Query.CONTACT_ID]); selection.append(" = ?"); if (lookupKey == null) { uri = Queries.PHONE.getContentUri(); desiredMimeType = null; } else { final Uri.Builder builder = Contacts.getLookupUri(contactId, lookupKey).buildUpon(); builder .appendPath(Contacts.Entity.CONTENT_DIRECTORY) .appendQueryParameter( ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)); uri = builder.build(); desiredMimeType = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE; } cursor = context .getContentResolver() .query( uri, Queries.PHONE.getProjection(), selection.toString(), new String[] {String.valueOf(contactId)}, null); } final Cursor resultCursor = removeUndesiredDestinations(cursor, desiredMimeType, lookupKey); cursor.close(); return resultCursor; }
public void testProjection() throws Exception { final TestRawContact rawContact = mBuilder.newRawContact().insert().load(); rawContact .newDataRow(StructuredName.CONTENT_ITEM_TYPE) .with(StructuredName.GIVEN_NAME, "xxx") .insert(); final TestContact contact = rawContact.getContact().load(); final long contactId = contact.getId(); final String lookupKey = contact.getString(Contacts.LOOKUP_KEY); final String[] PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME_PRIMARY, Contacts.DISPLAY_NAME_ALTERNATIVE, Contacts.DISPLAY_NAME_SOURCE, Contacts.PHONETIC_NAME, Contacts.PHONETIC_NAME_STYLE, Contacts.SORT_KEY_PRIMARY, Contacts.SORT_KEY_ALTERNATIVE, Contacts.LAST_TIME_CONTACTED, Contacts.TIMES_CONTACTED, Contacts.STARRED, Contacts.PINNED, Contacts.IN_DEFAULT_DIRECTORY, Contacts.IN_VISIBLE_GROUP, Contacts.PHOTO_ID, Contacts.PHOTO_FILE_ID, Contacts.PHOTO_URI, Contacts.PHOTO_THUMBNAIL_URI, Contacts.CUSTOM_RINGTONE, Contacts.HAS_PHONE_NUMBER, Contacts.SEND_TO_VOICEMAIL, Contacts.IS_USER_PROFILE, Contacts.LOOKUP_KEY, Contacts.NAME_RAW_CONTACT_ID, Contacts.CONTACT_PRESENCE, Contacts.CONTACT_CHAT_CAPABILITY, Contacts.CONTACT_STATUS, Contacts.CONTACT_STATUS_TIMESTAMP, Contacts.CONTACT_STATUS_RES_PACKAGE, Contacts.CONTACT_STATUS_LABEL, Contacts.CONTACT_STATUS_ICON, Contacts.CONTACT_LAST_UPDATED_TIMESTAMP }; // Contacts.CONTENT_URI DatabaseAsserts.checkProjection( mResolver, Contacts.CONTENT_URI, PROJECTION, new long[] {contact.getId()}); // Contacts.CONTENT_FILTER_URI DatabaseAsserts.checkProjection( mResolver, Contacts.CONTENT_FILTER_URI.buildUpon().appendEncodedPath("xxx").build(), PROJECTION, new long[] {contact.getId()}); // Contacts.CONTENT_LOOKUP_URI DatabaseAsserts.checkProjection( mResolver, Contacts.getLookupUri(contactId, lookupKey), PROJECTION, new long[] {contact.getId()}); }
/** * getCallerInfo given a Cursor. * * @param context the context used to retrieve string constants * @param contactRef the URI to attach to this CallerInfo object * @param cursor the first object in the cursor is used to build the CallerInfo object. * @return the CallerInfo which contains the caller id for the given number. The returned * CallerInfo is null if no number is supplied. */ public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) { CallerInfo info = new CallerInfo(); info.photoResource = 0; info.phoneLabel = null; info.numberType = 0; info.numberLabel = null; info.cachedPhoto = null; info.isCachedPhotoCurrent = false; info.contactExists = false; if (VDBG) Rlog.v(TAG, "getCallerInfo() based on cursor..."); if (cursor != null) { if (cursor.moveToFirst()) { // TODO: photo_id is always available but not taken // care of here. Maybe we should store it in the // CallerInfo object as well. int columnIndex; // Look for the name columnIndex = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); if (columnIndex != -1) { info.name = cursor.getString(columnIndex); } // Look for the number columnIndex = cursor.getColumnIndex(PhoneLookup.NUMBER); if (columnIndex != -1) { info.phoneNumber = cursor.getString(columnIndex); } // Look for the normalized number columnIndex = cursor.getColumnIndex(PhoneLookup.NORMALIZED_NUMBER); if (columnIndex != -1) { info.normalizedNumber = cursor.getString(columnIndex); } // Look for the label/type combo columnIndex = cursor.getColumnIndex(PhoneLookup.LABEL); if (columnIndex != -1) { int typeColumnIndex = cursor.getColumnIndex(PhoneLookup.TYPE); if (typeColumnIndex != -1) { info.numberType = cursor.getInt(typeColumnIndex); info.numberLabel = cursor.getString(columnIndex); info.phoneLabel = Phone.getDisplayLabel(context, info.numberType, info.numberLabel).toString(); } } // Look for the person_id. columnIndex = getColumnIndexForPersonId(contactRef, cursor); if (columnIndex != -1) { final long contactId = cursor.getLong(columnIndex); if (contactId != 0 && !Contacts.isEnterpriseContactId(contactId)) { info.contactIdOrZero = contactId; if (VDBG) { Rlog.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero); } } } else { // No valid columnIndex, so we can't look up person_id. Rlog.w(TAG, "Couldn't find contact_id column for " + contactRef); // Watch out: this means that anything that depends on // person_id will be broken (like contact photo lookups in // the in-call UI, for example.) } // Contact lookupKey columnIndex = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY); if (columnIndex != -1) { info.lookupKey = cursor.getString(columnIndex); } // Display photo URI. columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI); if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { info.contactDisplayPhotoUri = Uri.parse(cursor.getString(columnIndex)); } else { info.contactDisplayPhotoUri = null; } // look for the custom ringtone, create from the string stored // in the database. columnIndex = cursor.getColumnIndex(PhoneLookup.CUSTOM_RINGTONE); if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { info.contactRingtoneUri = Uri.parse(cursor.getString(columnIndex)); } else { info.contactRingtoneUri = null; } // look for the send to voicemail flag, set it to true only // under certain circumstances. columnIndex = cursor.getColumnIndex(PhoneLookup.SEND_TO_VOICEMAIL); info.shouldSendToVoicemail = (columnIndex != -1) && ((cursor.getInt(columnIndex)) == 1); info.contactExists = true; } cursor.close(); cursor = null; } info.needUpdate = false; info.name = normalize(info.name); info.contactRefUri = contactRef; return info; }