使用选择意图从电话簿中检索保存的地址

Posted

技术标签:

【中文标题】使用选择意图从电话簿中检索保存的地址【英文标题】:Retrieveing saved address from phonebook by using a pick intent 【发布时间】:2019-07-09 08:30:55 【问题描述】:

我想使用意图从电话簿中选择一个联系人,并且所选联系人还应包含相应的城市和州(如果由用户保存)。

这是我过去几天尝试的:

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】:

我可以在这里看到一个大错误:

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

查询Phone.CONTENT_URI 时不应使用PhoneLookup.XXX 列,此代码实际上返回Phone._ID 列(因为两者具有相同的常量字符串名称),它不是联系人ID,它是特定的手机 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 访问所选电话号码的权限,除此之外的任何需要权限的内容。

【讨论】:

感谢您的回答。现在我的代码运行良好。

以上是关于使用选择意图从电话簿中检索保存的地址的主要内容,如果未能解决你的问题,请参考以下文章

从联系人选择器意图中获取人员的联系方式

从图库或相机中选择图像的对话框

如何通过 LookUpKey 获取联系电话号码?

当我从未检索到的联系人列表地址数据中选择联系人姓名和地址时

电话号码检索意图

从手机的电话簿中检索联系人