如何在我的 android 程序中访问联系人

Posted

技术标签:

【中文标题】如何在我的 android 程序中访问联系人【英文标题】:how to access contacts in my android program 【发布时间】:2011-11-11 21:50:49 【问题描述】:

我正在制作一个短信应用程序并想在我的 android 应用程序中访问联系人 .

我想访问联系人,就像他们在实际联系人列表中的位置一样。选择后,我需要返回我可以向该人发送 SMS 的活动。或者是否可以访问存储联系人的数据库?

我的代码如下所示:

String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); 
String no = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));

我的 LogCat 如下所示:

09-07 12:46:15.458: DEBUG/AndroidRuntime(473): Shutting down VM
09-07 12:46:15.458: WARN/dalvikvm(473): threadid=1: thread exiting with uncaught exception (group=0x40015560)
09-07 12:46:15.478: ERROR/AndroidRuntime(473): FATAL EXCEPTION: main
09-07 12:46:15.478: ERROR/AndroidRuntime(473): java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=0, result=-1, data=Intent  dat=content://com.android.contacts/contacts/lookup/0r1-512D3F3D533B/1 flg=0x1 (has extras)  to activity task.list/task.list.Msgactivity: java.lang.IllegalArgumentException: column 'data1' does not exist
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:2574)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.access$2000(ActivityThread.java:117)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.os.Looper.loop(Looper.java:123)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.main(ActivityThread.java:3683)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at java.lang.reflect.Method.invokeNative(Native Method)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at java.lang.reflect.Method.invoke(Method.java:507)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at dalvik.system.NativeStart.main(Native Method)
09-07 12:46:15.478: ERROR/AndroidRuntime(473): Caused by: java.lang.IllegalArgumentException: column 'data1' does not exist
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:99)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at task.list.Msgactivity.onActivityResult(Msgactivity.java:99)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.Activity.dispatchActivityResult(Activity.java:3908)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2528)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     ... 11 more
09-07 12:46:15.489: WARN/ActivityManager(61):   Force finishing activity task.list/.Msgactivity

谁能帮帮我?

【问题讨论】:

你确实需要添加权限。 【参考方案1】:

使用此代码选择联系人:

 Button button = (Button)findViewById(R.id.pickcontact);

    button.setOnClickListener(new OnClickListener() 
        
            @Override
            public void onClick(View v) 
            
                 Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
                 startActivityForResult(intent, PICK_CONTACT);
             
         );



    @Override 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);
          if (c.moveToFirst())
          
          String id = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));

          String hasPhone =
          c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

          if (hasPhone.equalsIgnoreCase("1")) 
          
         Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, 
          ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
            phones.moveToFirst();
            String cNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
           // Toast.makeText(getApplicationContext(), cNumber, Toast.LENGTH_SHORT).show();
            setCn(cNumber);
          
         
       
    
   

【讨论】:

谢谢,但我如何将选定的联系电话存储到变量中 如果所选 ID 有多个号码,会发生什么情况。根据上面的代码,这将检索第一个数字。用户没有任何选项可以选择他想要的号码吗?【参考方案2】:

检查这些链接:

How to call Android contacts list?

How to get contacts from native phonebook in android

How to obtain all details of a contact in Android

How to get the first name and last name from Android contacts?

How to import contacts from phonebook to our application

Android contacts extraction

How to get all android contacts but without those which are on SIM

http://mobile.tutsplus.com/tutorials/android/android-essentials-using-the-contact-picker/

【讨论】:

【参考方案3】:

试试这个代码。这将所有联系人存储在 ArrayList 中

ArrayList<HashMap<String,String>> contactData=new ArrayList<HashMap<String,String>>();
ContentResolver cr = getContentResolver();
 Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
 while (cursor.moveToNext()) 
     try
     String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 
     String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
     String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); 
     if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
         Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
         while (phones.moveToNext())  
             String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER));
             HashMap<String,String> map=new HashMap<String,String>();
             map.put("name", name);
             map.put("number", phoneNumber);
             contactData.add(map);
          
         phones.close(); 
     
 catch(Exception e)
 

如果要存储特定联系人,请使用 if 条件。

【讨论】:

hasPhone 返回值为 1,但 String phoneNumber =phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));执行,会有什么问题 “hasPhone 返回值 1”的含义。没有得到你的问题 String hasPhone =c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));【参考方案4】:

我能够使用@Balaji.K 的示例进行一些修改。我遇到的主要问题是

while (cursor.moveToNext()) 

将跳过第一个结果。

我还想建立一个电话号码列表供用户选择,如果没有标记为“移动”的话。我还传递了一个名称以进行搜索(在此示例中替换为变量),但可以修改此代码以通过将“selection”和“selection_args”替换为 null 并迭代“联系人”中的所有内容来构建一个集合,就像我为“电话”。这是我最终得到的结果(在 Kotlin 中):

val selection = "lower($ContactsContract.Contacts.DISPLAY_NAME_PRIMARY) LIKE ?"
val selectionArgs = arrayOf("<SEARCH_TERM>")
selectionArgs[0] = "%<SEARCH_TERM>%"

// Query contacts for someone with a matching name
val contacts = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,
        null, selection, selectionArgs, null)
contacts!!.moveToFirst()
if (contacts.count > 1) 
    // TODO: Disambiguate and move to the correct position

val contactId = contacts.getString(contacts.getColumnIndex(
        ContactsContract.Contacts._ID))

// Check if contact has at least one phone number
if (contacts.getString(contacts.getColumnIndex(
                ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER)) == "1") 

    val sel = "$ContactsContract.CommonDataKinds.Email.CONTACT_ID = ?"
    val selArgs = arrayOf(name)
    val sort = "$ContactsContract.CommonDataKinds.Email.LAST_TIME_CONTACTED DESC"
    selArgs[0] = contactId

    val phones = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, sel, selArgs, sort)
    phones!!.moveToFirst()

    // Iterate through phone numbers if multiple
    if (phones.count > 1) 
        val phoneNumbers = mutableMapOf<Int, ContactData>()
        var loop = true
        var mobileIndex: Int? = null
        while (loop) 
            val phoneType = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE))
            val phoneName = ContactsContract.CommonDataKinds.Phone.getTypeLabel(resources, phoneType, null).toString()
            phoneNumbers[phones.position] = ContactData(phoneName, phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))
            // Remember what position the mobile number was in
            if (phoneType == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) 
                mobileIndex = phones.position
            
            loop = phones.moveToNext()
        
        phones.moveToPosition(mobileIndex)
    

【讨论】:

以上是关于如何在我的 android 程序中访问联系人的主要内容,如果未能解决你的问题,请参考以下文章

在我的意图android中选择联系人后如何删除联系人

如何在我的应用程序中显示隐私政策

如何在我的 android 应用程序中的任何位置使实例可用或可访问

如何从 android 的电话簿中选择联系人号码到我的应用程序中?

我的 android 应用程序中出现了联系人列表。单击名称后,如何将数字保存到字符串中?

如何在android上的listview中快速加载联系人