【问题标题】:How can I choose a phone number with Android's contacts dialog如何使用 Android 的联系人对话框选择电话号码
【发布时间】:2011-12-23 05:23:37
【问题描述】:

我正在使用旧的联系人 API 来选择带有电话号码的联系人。我想使用较新的 ContactsContracts API。我要……

  1. ...显示所有联系人的对话框。
  2. ...用户选择一个联系人和他们的一个电话号码。
  3. ...访问所选电话号码。

ContactsContracts 非常复杂。我找到了很多例子,但没有一个符合我的需要。我不想选择一个联系人然后查询联系人的详细信息,因为这会给我一个他们的电话号码列表。我需要用户选择一个联系人的电话号码。我不想编写自己的对话框来显示联系人或让用户选择电话号码。有什么简单的方法可以得到我想要的吗?

这是我正在使用的旧 API 代码:

static public final int CONTACT = 0;
...
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.Phones.CONTENT_URI);
startActivityForResult(intent, CONTACT);
...
public void onActivityResult (int requestCode, int resultCode, Intent intent) {
  if (resultCode != Activity.RESULT_OK || requestCode != CONTACT) return;
  Cursor c = managedQuery(intent.getData(), null, null, null, null);
  if (c.moveToFirst()) {
     String phone = c.getString(c.getColumnIndexOrThrow(Contacts.Phones.NUMBER));
     // yay
  }
}      

【问题讨论】:

标签: android contacts


【解决方案1】:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT); 

此代码可能会对您有所帮助。我认为 PICK 操作只返回所选联系人的 ID。从中您可以查询联系人提供商,如果有多个电话号码,提示用户选择其中一个。

你也可以使用这个(更新):

public void readcontact(){
    try {
        Intent intent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts/people"));
        startActivityForResult(intent, PICK_CONTACT);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onActivityResult(int reqCode, int resultCode, Intent data) {
      super.onActivityResult(reqCode, resultCode, data);

      switch (reqCode) {
        case (PICK_CONTACT) :
          if (resultCode == Activity.RESULT_OK) {
              Uri contactData = data.getData();
                Cursor c =  managedQuery(contactData, null, null, null, null);
                startManagingCursor(c);
                if (c.moveToFirst()) {
                    String name = c.getString(c.getColumnIndexOrThrow(People.NAME));    
                    String number = c.getString(c.getColumnIndexOrThrow(People.NUMBER));
                    personname.setText(name);
                    Toast.makeText(this,  name + " has number " + number, Toast.LENGTH_LONG).show();
                 }
           }
         break;
      }

}

28/12 -2011 年更新

你可以用这个:

@Override  
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (resultCode == RESULT_OK) {  
        switch (requestCode) {  
        case CONTACT_PICKER_RESULT:
            final EditText phoneInput = (EditText) findViewById(R.id.phoneNumberInput);
            Cursor cursor = null;  
            String phoneNumber = "";
            List<String> allNumbers = new ArrayList<String>();
            int phoneIdx = 0;
            try {  
                Uri result = data.getData();  
                String id = result.getLastPathSegment();  
                cursor = getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + "=?", new String[] { id }, null);  
                phoneIdx = cursor.getColumnIndex(Phone.DATA);
                if (cursor.moveToFirst()) {
                    while (cursor.isAfterLast() == false) {
                        phoneNumber = cursor.getString(phoneIdx);
                        allNumbers.add(phoneNumber);
                        cursor.moveToNext();
                    }
                } else {
                    //no results actions
                }  
            } catch (Exception e) {  
               //error actions
            } finally {  
                if (cursor != null) {  
                    cursor.close();
                }

                final CharSequence[] items = allNumbers.toArray(new String[allNumbers.size()]);
                AlertDialog.Builder builder = new AlertDialog.Builder(your_class.this);
                builder.setTitle("Choose a number");
                builder.setItems(items, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int item) {
                        String selectedNumber = items[item].toString();
                        selectedNumber = selectedNumber.replace("-", "");
                        phoneInput.setText(selectedNumber);
                    }
                });
                AlertDialog alert = builder.create();
                if(allNumbers.size() > 1) {
                    alert.show();
                } else {
                    String selectedNumber = phoneNumber.toString();
                    selectedNumber = selectedNumber.replace("-", "");
                    phoneInput.setText(selectedNumber);
                }

                if (phoneNumber.length() == 0) {  
                    //no numbers found actions  
                }  
            }  
            break;  
        }  
    } else {
       //activity result error actions
    }  
}

您需要对其进行调整以与您的应用一起使用。

【讨论】:

  • 你是说没有内置的方法来选择电话号码?
  • 只选择一个联系人很好,但我需要选择一个联系人的电话号码。使用旧 API 的问题中的代码显示了一个联系人选择器,当显示一个联系人时,如果它有多个电话号码,则会显示一个小对话框来选择一个电话号码(至少在我的 HTC Thunderbolt 上)。这就是我想做的,但使用新的 API。我不知道这个功能是内置的,还是需要自定义对话框来选择电话号码。
  • developer.android.com/resources/samples/BusinessCard/src/com/… 将此链接用于联系人选择 n,即使是数字 n 我也尝试为其编写代码。希望
  • Intent intent = new Intent(Intent.ACTION_PICK, Contacts.Phones.CONTENT_URI); startActivityForResult(意图,PICK_CONTACT_RQCODE_OLD);显示电话号码以及联系人... :)
  • @Rizvan:您的解决方案在我运行 Android 4.4.4 的手机上运行良好。但是当我尝试在我 gf 的手机(Android 4.1.2)上使用这个解决方案时,它根本没有显示任何联系人。我认为这是因为有几种方法已被弃用。
【解决方案2】:

您可以在这里找到一个很棒的代码:http://developer.android.com/training/basics/intents/result.html

static final int PICK_CONTACT_REQUEST = 1;  // The request code
...
private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
    pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request it is that we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // Get the URI that points to the selected contact
            Uri contactUri = data.getData();
            // We only need the NUMBER column, because there will be only one row in the result
            String[] projection = {Phone.NUMBER};

            // Perform the query on the contact to get the NUMBER column
            // We don't need a selection or sort order (there's only one result for the given URI)
            // CAUTION: The query() method should be called from a separate thread to avoid blocking
            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
            // Consider using CursorLoader to perform the query.
            Cursor cursor = getContentResolver()
                    .query(contactUri, projection, null, null, null);
            cursor.moveToFirst();

            // Retrieve the phone number from the NUMBER column
            int column = cursor.getColumnIndex(Phone.NUMBER);
            String number = cursor.getString(column);

            // Do something with the phone number...
        }
    }
}

【讨论】:

    【解决方案3】:

    根据较早的答案和我自己的测试,我最终使用了这个:

    启动联系人列表:

    import android.content.Intent;
    import android.provider.ContactsContract;
    import android.provider.ContactsContract.CommonDataKinds.Phone;
    

    ...

    public static final int PICK_CONTACT = 100;
    

    ...

    Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
    intent.setType(Phone.CONTENT_TYPE);  //should filter only contacts with phone numbers
    startActivityForResult(intent, PICK_CONTACT);
    

    onActivityResult 处理程序:

    private static final String[] phoneProjection = new String[] { Phone.DATA };
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (PICK_CONTACT != requestCode || RESULT_OK != resultCode) return;
        Uri contactUri = data.getData();
        if (null == contactUri) return;
        //no tampering with Uri makes this to work without READ_CONTACTS permission
        Cursor cursor = getContentResolver().query(contactUri, phoneProjection, null, null, null);
        if (null == cursor) return;
        try {
            while (cursor.moveToNext()) {
                String number = cursor.getString(0);
                // ... use "number" as you wish
            }
        } finally {
            cursor.close();
        }
        // "cursor" is closed here already
    }
    

    那么和 Rizvan 的回答有什么不同呢?

    在我的测试设备(三星 S3)上:

    • 应用NOT需要READ_CONTACS权限(因为我使用返回的uri,当我只使用它的“id”并创建select ID=?查询类型时,发生权限崩溃)
    • 当联系人有多个电话号码时,选择器本身会显示对话框以仅选择其中一个,然后返回 uri 直接指向该单个选定号码
    • 即使某些电话会将uri 返回到多个号码,建议的 onActivityResult 处理程序也可以扩展为读取所有号码,并且您可以执行自己的选择对话框。

    所以在我看来,这完全符合 OP 的要求。

    现在我只是想知道:

    1. 在哪些手机上需要READ_CONTACTS 权限(根据http://developer.android.com/guide/topics/providers/content-provider-basics.html#Intents 应该不需要)
    2. 它将在哪些手机上返回多个号码,而不是执行选择对话框

    如果你有实际经验,请告诉我,谢谢。

    更新: HTC Desire S,android 4.0.3 的自定义 rom -> 有这两个问题,需要 READ_CONTACTS 权限才能工作,并且将返回多个数字而无需额外的选择对话框。

    【讨论】:

    • HTC M8 需要带有此代码的 READ_CONTACTS,但他们似乎在额外的意图中提供了电话号码,并带有键 Intent.EXTRA_PHONE_NUMBER
    • 我在查询行得到IllegalArgumentException: Invalid column data1
    • 关于IllegalArgumentException - 它可能来自Phone.DATA,在内容解析器中不可用...我需要您的特定手机型号来查看可用的内容以及如何检测。我对 Android 实现的普遍低质量感到非常恼火,没有遵循 API,就像在这个例子中,没有READ_CONTACTS 许可的手机会失败,等等......代码在正确的 Android 上应该是正确的,您可以通过将其包含在try-catch 中来加强它,甚至尝试为您的特定手机找到一些解决方法,但我没有。
    【解决方案4】:

    我找到了一种从联系人列表中准确选择电话号码的方法。 下面是sn-p。

    1.启动联系人以选择片段中的电话号码。

    Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);        
    // filter the contacts with phone number only
    intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); 
    startActivityForResult(intent, PICK_CONTACT);
    

    2.在fragment中选择选中的电话号码。

    @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();
                    Cursor cur =  getActivity().getContentResolver().query(contactData, null, null, null, null);
                    if (cur == null) return;
                    try {
                        if (cur.moveToFirst()) {
                            int phoneIndex = cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                            mobileNoEditText.setText(cur.getString(phoneIndex));
                        }
                    }
                    finally {
                        cur.close();
                    }
                }
        }
    }
    

    附: private final int PICK_CONTACT = 666;

    【讨论】:

      猜你喜欢
      • 2012-06-13
      • 2018-01-08
      • 2017-05-28
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 2011-06-11
      相关资源
      最近更新 更多