Android:关于加载联系信息的奇怪之处

时间:2011-07-14 18:54:27

标签: android contact

我创建了一个应用。它正在研究htc desire hd,但是当我在中兴Blade上测试时,出现了一个奇怪的问题。在我的应用程序中,当用户从微调器中选择联系人姓名时,会出现一个菜单。在菜单中,用户可以向用户发送短信,给他/她打电话或者只看他/她的联系信息。在HTC Desire HD上,一切正常。在中兴通讯上,联系信息按钮似乎存在一个令人恼火的问题:在某些情况下,当用户选择联系人并希望查看他的联系信息时,会显示其他联系人的信息。所以我从我的微调器中选择了Pete,但我得到了Dave的联系信息。在其他情况下,我从微调器中选择Tom,我得到Tom的联系信息。这个问题在我的HTC上不存在。我无法弄清楚导致问题的原因。顺便说一句,我在HTC上的联系人列表也是从gmail和facebook填充的,应用程序仍然正常工作,而中兴通讯的联系人列表从未见过任何gmail或facebook账号(我对此并不完全确定)。

这是我用来获取联系信息的代码:

         infobtn.setOnClickListener(new View.OnClickListener() 
         {
            public void onClick(View v) 
            { 
                ContentResolver cr = getContentResolver();
                Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

                if (cur.getCount() > 0) 
                {

                    while (cur.moveToNext()) {
                    id_contact = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                    name_contact = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                        if (name_contact.equals(name1))
                        {
                        Cursor pCur = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id_contact}, null);
                           id_contact2 = id_contact;

                            while (pCur.moveToNext()){
                            } 
                        pCur.close();
                        }
                    }
                    Intent intent_contacts = new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/" + id_contact2));
                    startActivity(intent_contacts);
                }

            }
         });

3 个答案:

答案 0 :(得分:0)

我的申请中也有类似的问题。该应用程序是一个小部件,可以快速使用收藏夹联系人。用户创建新窗口小部件并为其分配联系人。当他点击小部件时,他可以进行常见的联系动作 - 通话,短信,编辑等。

有些用户发送如下报告: “我选择了大约4个联系人,应用程序显示4个,但其中只有一个正确3个其他是同一个联系人,我甚至没有选择”。 “为什么选择错误的联系人?在我的机器人上难以置信”

我无法重现我身边的问题。我尝试了几种不同的设备,尝试进行导入/导出联系 - 没有结果。

无论如何,我对问题的根源有一些想法。

我的应用程序使用查找键来存储联系人according to sdk。因此,当用户选择联系人时,应用程序会存储联系人查找密钥。然后,它使用此查找键获取此联系人的联系人ID。之后,它仅在所有其他功能中使用收到的联系人ID。您的功能也是如此 - 它在子查询中仅使用联系人ID。

问题是:不同的联系人(具有不同的查找键)是否可能具有相同的联系人ID?在极少数情况下,在某些设备上看起来是可能的...... 如果是这样,我们需要始终使用Contact ID +查找键来识别联系。更新:建议不正确。查询密钥可以在修改联系信息后更改,您将找不到联系人)。

据我了解,您可以重现您身边的问题。我建议以这种方式更改您的代码:

     infobtn.setOnClickListener(new View.OnClickListener() 
     {
        public void onClick(View v) 
        { 
            ContentResolver cr = getContentResolver();
            Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

            if (cur.getCount() > 0) 
            {

                while (cur.moveToNext()) {
                id_contact = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                name_contact = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                String lookup_key = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
                    if (name_contact.equals(name1))
                    {
                    Cursor pCur = cr.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ? AND " + ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY + " = ?", new String[]{id_contact, lookup_key}, null);
                       id_contact2 = id_contact;

                        while (pCur.moveToNext()){
                        } 
                    pCur.close();
                    }
                }
                Intent intent_contacts = new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/" + id_contact2));
                startActivity(intent_contacts);
            }

        }
     });

并尝试再次重现此问题。

答案 1 :(得分:0)

您可以看到此链接,非常好:http://www.vtutorials.info/2014/08/working-with-android-contacts-how-to.html

private Map<Long, ArrayList<LocalContactInfo>> queryAllPhones(ContentResolver contentresolver)  
   {  
     HashMap<Long, ArrayList<LocalContactInfo>> hashmap = new HashMap<Long, ArrayList<LocalContactInfo>>();  
     Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;  
           String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;  
           String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;  
     Cursor cursor = contentresolver.query(PhoneCONTENT_URI, null, null, null, null);  
     do  
     {  
       if (!cursor.moveToNext())  
       {  
         cursor.close();  
         return hashmap;  
       }  
       long l = cursor.getLong(cursor.getColumnIndex(Phone_CONTACT_ID));  
       String s = cursor.getString(cursor.getColumnIndex(NUMBER));  
       LocalContactInfo temp = new LocalContactInfo(String.valueOf(l), "", s, "", 1);  
       if (hashmap.containsKey(Long.valueOf(l))){  
         ((List<LocalContactInfo>)hashmap.get(Long.valueOf(l))).add(temp);  
       } else{  
         ArrayList<LocalContactInfo> arraylist = new ArrayList<LocalContactInfo>();  
         arraylist.add(temp);  
         hashmap.put(Long.valueOf(l), arraylist);  
       }  
     } while (true);  
   } 

并且:

 public List<LocalContactInfo> doloadContacts() {  
           List<LocalContactInfo> _return = new ArrayList<LocalContactInfo>();  
           Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;  
           String _ID = ContactsContract.Contacts._ID;  
           String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;  
           String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;  
           ContentResolver contentResolver = mContext.getContentResolver();  
           Map<Long, ArrayList<LocalContactInfo>> map = queryAllPhones(contentResolver);  
           Cursor cursor = contentResolver.query(CONTENT_URI, null,null, null, null);  
           if(cursor == null || cursor.getCount()==0){  
             return _return;  
        }  
           if (cursor.getCount() > 0) {  
                while (cursor.moveToNext()) {  
                     Long contact_id = cursor.getLong(cursor.getColumnIndex( _ID ));  
                     String fullname = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME )).trim();  
                     int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex( HAS_PHONE_NUMBER )));  
                     if (hasPhoneNumber > 0 && map.get(contact_id) != null){  
                               Object obj = ((List<LocalContactInfo>)map.get(contact_id)).get(0);  
                               if(obj instanceof LocalContactInfo){  
                                    LocalContactInfo _temp = (LocalContactInfo)obj;  
                                    _return.add(new LocalContactInfo(String.valueOf(contact_id), fullname, _temp.getNumberPhone(), "",hasPhoneNumber));  
                               }  
                     }  
             }  
           }  
     return _return;  
      }  

答案 2 :(得分:0)

而不是使用&#34; contacts / people / xxx&#34;,请尝试使用contactsContract.Contacts.CONTENT_URI。

基本上,你想要替换。

Uri contactUri = Uri.parse("content://contacts/people/" + id_contact2)); 

Uri contactUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, 
    id_contact2); 

需要注意的另一件事是&#34; id_contact2&#34;如果在您使用之前发生同步,则可能会更改(例如,当Google同步合并联系人时)。为了防止这种情况,最好使用LookupKey。

ContactsContract.Contacts.LOOKUP_KEY

并使用

进行检索
Uri contactUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, 
    yourContactLookupKey);