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.

  }
Beispiel #4
0
  @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);
  }
Beispiel #8
0
    /*
     * 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()});
  }
Beispiel #14
0
  /**
   * 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;
  }