Пример #1
0
  /**
   * getCallerInfo given a phone number and subscription, look up in the call-log database for the
   * matching caller id info.
   *
   * @param context the context used to get the ContentResolver
   * @param number the phone number used to lookup caller id
   * @param subId the subscription for checking for if voice mail number or not
   * @return the CallerInfo which contains the caller id for the given number. The returned
   *     CallerInfo is null if no number is supplied. If a matching number is not found, then a
   *     generic caller info is returned, with all relevant fields empty or null.
   */
  public static CallerInfo getCallerInfo(Context context, String number, int subId) {

    if (TextUtils.isEmpty(number)) {
      return null;
    }

    // Change the callerInfo number ONLY if it is an emergency number
    // or if it is the voicemail number.  If it is either, take a
    // shortcut and skip the query.
    if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
      return new CallerInfo().markAsEmergency(context);
    } else if (PhoneNumberUtils.isVoiceMailNumber(subId, number)) {
      return new CallerInfo().markAsVoiceMail();
    }

    Uri contactUri =
        Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(number));

    CallerInfo info = getCallerInfo(context, contactUri);
    info = doSecondaryLookupIfNecessary(context, number, info);

    // if no query results were returned with a viable number,
    // fill in the original number value we used to query with.
    if (TextUtils.isEmpty(info.phoneNumber)) {
      info.phoneNumber = number;
    }

    return info;
  }
    /**
     * Overrides onQueryComplete from AsyncQueryHandler.
     *
     * <p>This method takes into account the state of this class; we construct the CallerInfo object
     * only once for each set of listeners. When the query thread has done its work and calls this
     * method, we inform the remaining listeners in the queue, until we're out of listeners. Once we
     * get the message indicating that we should expect no new listeners for this CallerInfo object,
     * we release the AsyncCursorInfo back into the pool.
     */
    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
      if (DBG) log("query complete for token: " + token);

      // get the cookie and notify the listener.
      CookieWrapper cw = (CookieWrapper) cookie;
      if (cw == null) {
        // Normally, this should never be the case for calls originating
        // from within this code.
        // However, if there is any code that calls this method, we should
        // check the parameters to make sure they're viable.
        if (DBG) log("Cookie is null, ignoring onQueryComplete() request.");
        return;
      }

      if (cw.event == EVENT_END_OF_QUEUE) {
        release();
        return;
      }

      // check the token and if needed, create the callerinfo object.
      if (mCallerInfo == null) {
        if ((mQueryContext == null) || (mQueryUri == null)) {
          throw new QueryPoolException(
              "Bad context or query uri, or CallerInfoAsyncQuery already released.");
        }

        // adjust the callerInfo data as needed, and only if it was set from the
        // initial query request.
        // Change the callerInfo number ONLY if it is an emergency number or the
        // voicemail number, and adjust other data (including photoResource)
        // accordingly.
        if (cw.event == EVENT_EMERGENCY_NUMBER) {
          // Note we're setting the phone number here (refer to javadoc
          // comments at the top of CallerInfo class).
          mCallerInfo = new CallerInfo().markAsEmergency(mQueryContext);
        } else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
          mCallerInfo = new CallerInfo().markAsVoiceMail();
        } else {
          mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
          // Use the number entered by the user for display.
          if (!TextUtils.isEmpty(cw.number)) {
            mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
          }
        }

        if (DBG) log("constructing CallerInfo object for token: " + token);

        // notify that we can clean up the queue after this.
        CookieWrapper endMarker = new CookieWrapper();
        endMarker.event = EVENT_END_OF_QUEUE;
        startQuery(token, endMarker, null, null, null, null, null);
      }

      // notify the listener that the query is complete.
      if (cw.listener != null) {
        if (DBG)
          log(
              "notifying listener: "
                  + cw.listener.getClass().toString()
                  + " for token: "
                  + token
                  + mCallerInfo);
        cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
      }
    }
Пример #3
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;
  }