Извлечение сохраненного адреса из телефонной книги с помощью намерения выбора - PullRequest
0 голосов
/ 15 февраля 2019

Я хочу выбрать контакт из телефонной книги, используя намерение, и выбранный контакт должен также содержать соответствующий город и штат (если он был сохранен пользователем).

Вот что я пытаюсь за последние несколько дней:

private void accessContacts() {
 Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
    intent.setDataAndType(ContactsContract.Contacts.CONTENT_URI,
        ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
    startActivityForResult(intent, PICK_CONTACT);
  } 

@Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
      case PICK_CONTACT:
        if (resultCode == Activity.RESULT_OK) {
          Uri contactData = data.getData();
          String[] projection = {
              ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
              ContactsContract.CommonDataKinds.Phone.NUMBER
          };
          String name = null;
          String phoneNumber = null;
          String city = null;
          String state = null;

          Cursor c =
              getActivity().getContentResolver().query(contactData, null, null, null, null);
          if (c != null) {
            if (c.moveToFirst()) {
              int nameIdx = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
              int phoneNumberIdx = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
              name = c.getString(nameIdx);
              phoneNumber = c.getString(phoneNumberIdx);

              String id = c.getString(c.getColumnIndex(ContactsContract.PhoneLookup._ID));

              String addrWhere = ContactsContract.Data.CONTACT_ID + " = ? AND "
                  + ContactsContract.Data.MIMETYPE + " = ?";
              String[] addrWhereParams = new String[]{id,
                  ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE};
              Cursor addrCur = getActivity().getContentResolver()
                  .query(ContactsContract.Data.CONTENT_URI,
                  null, addrWhere, addrWhereParams, null);

              if (addrCur.moveToFirst()) {
                city = addrCur.getString(
                    addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
                state = addrCur.getString(
                    addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
              }
              addrCur.close();

            }
            c.close();
          }

          if (name == null) {
            name = "No Name";
          }

          if (TextUtils.isEmpty(phoneNumber) || phoneNumber.length() < 10) {
            handleAddConnectionError(getContext().getString(R.string.invalid_phone_number));
            return;
          }

          Phonenumber.PhoneNumber number =
              Utils.validateMobileNumber2(phoneNumber, Device.getCountryCode(getActivity()));
          if (number == null) {
            handleAddConnectionError(getContext().getString(R.string.invalid_phone_number));
            return;
          }


          this.moveToCategoryPage(name, String.valueOf(number.getNationalNumber()),
              Utils.getCountryCodeWithPlusSign(number), false, null,
              city, state);
        }
        break;
    }

  }

При удалении / изменении:

intent.setDataAndType (ContactsContract.Contacts.CONTENT_URI, ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);

выдает исключение.

Как получить сохраненный адрес из намерения выбора?

1 Ответ

0 голосов
/ 17 февраля 2019

Есть одна большая ошибка, которую я вижу здесь:

String id = c.getString(c.getColumnIndex(ContactsContract.PhoneLookup._ID));

Вы не должны использовать PhoneLookup.XXX столбцы при запросе к Phone.CONTENT_URI, этот код фактически возвращает столбец Phone._ID вместо этого (потому чтооба имеют одинаковое имя строки констант), которое НЕ является идентификатором контакта, это определенный идентификатор телефона (или Data._ID).Вы также не можете получить доступ к столбцам из курсора, который вы не указали в своей проекции.

Поэтому измените вашу проекцию на:

      String[] projection = {
          ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
          ContactsContract.CommonDataKinds.Phone.NUMBER,
          ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
      };

и замените эту строку на:

Long contactId = c.getLong(2);

Еще одна вещь, которую вы можете сделать, это упростить ваш второй запрос, выполнив запрос к StructuredPostal.CONTENT_URI, например так:

String addrWhere = StructuredPostal.CONTACT_ID + " = " + contactId;
Cursor addrCur = getActivity().getContentResolver().query(StructuredPostal.CONTENT_URI, null, addrWhere, null, null);

Обратите внимание, что в отличие от вашего первого запроса информации Phone.NUMBER, выприложению необходимо READ_CONTACTS разрешение на второй запрос адреса, это потому, что вы запрашиваете намерение выбора телефона, которое предоставляет вашему приложению временную привязку.разрешение на доступ к выбранному номеру телефона только из API контактов, кроме того, что требует разрешения.

...