在两行 ListView 中列出联系信息

Posted

技术标签:

【中文标题】在两行 ListView 中列出联系信息【英文标题】:list contact information in two line ListView 【发布时间】:2015-12-16 11:03:38 【问题描述】:

我想在ListView(第一行:人名,第二行:电话号码)中列出联系方式(人名,人号)。我成功地获得了联系人的所有必要信息,但在ListView 中列出它们时遇到问题。 ListView 中仅显示第一个联系人。

onCreate()我创建ContentResolver对象,调用方法get_list( )获取姓名和电话号码并尝试显示ListView

 ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    int anzahl = cur.getCount();
    Log.d("anzahl09", "anzahl09 " + anzahl);

    telefonname = new String[anzahl];
    telefonnummer = new String[anzahl];
    zusammengesetzt = new String[anzahl];

    kontakte_laden = new String[anzahl][anzahl];

    String[] telefonname_telefonnummer = new String[anzahl];
    telefonname_telefonnummer = get_list(cur, cr);

    int i =0;
    do 
        Log.d("schleife09", "schleife09 " + i + "|" + telefonname_telefonnummer[i] + "|" +  telefonname[i] + "|" + telefonnummer[i] + "|" + kontakte_laden[i][i]);
        kontakte_laden[i][0] = telefonname[i];
        kontakte_laden[i][1] = telefonnummer[i];
        i++;
     while (i < anzahl);


    ListView listview = ( ListView ) findViewById ( android.R.id.list );

    listview.setPadding ( 20, 20, 20, 20 );

    @SuppressWarnings("Convert2Diamond") ArrayList< HashMap< String, String > > list = new ArrayList< HashMap< String, String > > ();


    for (String[] anAussehen : kontakte_laden) 
        //noinspection Convert2Diamond
        item = new HashMap<String, String>();
        item.put("line1", anAussehen[0]);
        item.put("line2", anAussehen[1]);
        list.add(item);
    


    SimpleAdapter sa = new SimpleAdapter(this, list,
            android.R.layout.two_line_list_item,
            new String[]"line1", "line2",
            new int[]android.R.id.text1, android.R.id.text2);


    listview.setAdapter(sa);


    listview.setOnItemClickListener(listViewOnItemClickListener);

读取联系信息get_list()的方法如下:

 private String[] get_list(Cursor cur, ContentResolver cr)

    if (cur.getCount() > 0) 

        while (cur.moveToNext()) 
            int i=0;
            String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
            telefonname[i] = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            Log.d("telefonname09", "telefonname09 " +telefonname[i]);

            if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]id, null);
                    while (pCur.moveToNext()) 
                        telefonnummer[i] = pCur.getString( pCur.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER ) );
                        Log.d("telefonnummer09", "telefonnummer09 " + telefonnummer[i]); // correct values
                    
                    pCur.close();
                
            

            zusammengesetzt[i] = telefonname[i] + "|" + telefonnummer[i];
        
    



// only one value
        for(int i=0; i < cur.getCount(); i++)
            Log.d("telefonnummer07", "telefonnummer07 " + telefonname[i] + "|" + telefonnummer[i]);
        
    cur.close();
    return zusammengesetzt;

但结果如下:

更新 问题是,人名 (telefonname[]) 和电话号码 (telefonnummer[]) 的数组仅在 get_list() 方法的 while 循环中获得了正确的内容。在while循环之外,数组只有最后一个值。参见上面的方法get_list()

解决方案 我改变了以下几点:

我之前直接定义了全局字符串数组的编号和名称。所以在get_list() 方法中我必须定义两个新的字符串数组 我将姓名和电话号码引用到这些新的本地字符串数组 将这些新的本地字符串数组引用到全局字符串数组

这是工作代码:

onCreate() 方法:

ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);


    int anzahl = cur.getCount();
    Log.d("anzahl09", "anzahl09 " + anzahl);

    telefonname_global = new String[anzahl];
    telefonnummer_global = new String[anzahl];


    kontakte_laden = new String[anzahl][anzahl];

    get_list(cur, cr);


    int i =0;
    do 
        Log.d("schleife09", "schleife09 " + i + "|" /*+ telefonname_telefonnummer[i] + "|" */ +  telefonname_global[i] + "|" + telefonnummer_global[i] + "|" + kontakte_laden[i][i]);
        kontakte_laden[i][0] = telefonname_global[i];
        kontakte_laden[i][1] = telefonnummer_global[i];
        i++;
     while (i < anzahl);


    ListView listview = ( ListView ) findViewById ( android.R.id.list );

    listview.setPadding ( 20, 20, 20, 20 );

    @SuppressWarnings("Convert2Diamond") ArrayList< HashMap< String, String > > list = new ArrayList< HashMap< String, String > > ();


    for (String[] anAussehen : kontakte_laden) 
        //noinspection Convert2Diamond
        item = new HashMap<String, String>();
        item.put("line1", anAussehen[0]);
        item.put("line2", anAussehen[1]);
        list.add(item);
    


    SimpleAdapter sa = new SimpleAdapter(this, list,
            android.R.layout.two_line_list_item,
            new String[]"line1", "line2",
            new int[]android.R.id.text1, android.R.id.text2);


    listview.setAdapter(sa);



    listview.setOnItemClickListener(listViewOnItemClickListener);

还有get_list() 方法:

private void get_list(Cursor cur, ContentResolver cr)

    int i = 0;

    if (cur.getCount() > 0) 

        String[] telefonname = new String[cur.getCount()];
        String[] telefonnummer = new String[cur.getCount()];


        while (cur.moveToNext()) 

            String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
            telefonname[i] = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            Log.d("telefonname09", "telefonname09 " +telefonname[i]);

            if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]id, null);

                    while (pCur.moveToNext()) 
                        telefonnummer[i] = pCur.getString( pCur.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER ) );
                        Log.d("telefonnummer09", "telefonnummer09 " + telefonnummer[i]);
                    

                    pCur.close();
                
            

            Log.d("telefonnummer08", "telefonnummer08 " + telefonnummer[i]);
            telefonname_global[i] = telefonname[i];
            telefonnummer_global[i] = telefonnummer[i];

            i++;
        
    

    // Fehler: Array telefonnummer hat nur einen Wert
    for(int j=0; j < cur.getCount(); j++)
        Log.d("telefonnummer07", "telefonnummer07 " + telefonname_global[j] + "|" + telefonnummer_global[j]);
    


     cur.close();


非常感谢您的帮助。

另一个问题是,没有电话号码的电子邮件地址或联系人不应出现在此列表中。如何做到这一点?

【问题讨论】:

感谢您的评论。不会发生异常。并且get_list()方法的name、number的值是正确的。 如果您说您的 get_list() 方法是正确的,那么显然这里没有错误,但是您的适配器的大小是多少,您检查了吗? 请看我编辑的帖子 将光标移动到第一行。 cursor.moveToFirst() 你的意思是之前 while(cursor.moveToNext() )?结果是,不再显示任何内容 【参考方案1】:

i 不是增量,这是问题

private String[] get_list(Cursor cur, ContentResolver cr)

if (cur.getCount() > 0) 
   // inialize outside
    int i=0;
    while (cur.moveToNext()) 

        String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
        telefonname[i] = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
        Log.d("telefonname09", "telefonname09 " +telefonname[i]);

        if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
            if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
                Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]id, null);
                while (pCur.moveToNext()) 
                    telefonnummer[i] = pCur.getString( pCur.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER ) );
                    Log.d("telefonnummer09", "telefonnummer09 " + telefonnummer[i]); // correct values
                
                pCur.close();
            
        

        zusammengesetzt[i] = telefonname[i] + "|" + telefonnummer[i];

       //i is need to increment
       i++;
    

仅在电话号码存在时添加

 for (String[] anAussehen : kontakte_laden) 
  if(anAussehen[1] != null)
  
    //noinspection Convert2Diamond
    item = new HashMap<String, String>();
    item.put("line1", anAussehen[0]);
    item.put("line2", anAussehen[1]);
    list.add(item);
  

【讨论】:

感谢您的回答。你说得对,我忘记了 i 的增量。但不幸的是结果是一样的。 在while循环开始前移动i声明 我找到了解决这个问题的方法并编辑了我的帖子。非常感谢您的帮助。但是还有另一个问题:我不想在没有电话号码的情况下显示电子邮件地址和联系人。如何做到这一点? @user3603935 如果只有电话号码,我更新了代码。【参考方案2】:

我已经结束了从 Android 手机中检索最快解决方案的搜索。 ContactDTO 是 pojo 类。

它会以“联系人显示名称”的升序返回结果。

public static List<ContactDTO> getPhone(Context context)
            List<ContactDTO> contactList = new ArrayList<ContactDTO>();
            ContentResolver cr = context.getContentResolver(); 
            String[] PROJECTION = new String[]  
                    ContactsContract.RawContacts._ID, 
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
                    ContactsContract.CommonDataKinds.Phone.NUMBER,
                    ContactsContract.CommonDataKinds.Photo.CONTACT_ID ;

            Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
            String filter = ""+ ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 and " + Phone.TYPE +"=" + Phone.TYPE_MOBILE;     
            String order = ContactsContract.Contacts.DISPLAY_NAME + " ASC";// LIMIT " + limit + " offset " + lastId + "";

            Cursor phoneCur = cr.query(uri, PROJECTION, filter, null, order);
            while(phoneCur.moveToNext())
                 ContactDTO dto = new ContactDTO();
                 dto.setName("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
                 dto.setMobileNo("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
                 dto.setPhotoUrl("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI)));
                 dto.setContactId("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Photo.CONTACT_ID)));
                 contactList.add(dto);
             
             phoneCur.close();
            return contactList;

【讨论】:

以上是关于在两行 ListView 中列出联系信息的主要内容,如果未能解决你的问题,请参考以下文章

UILabel 或 UITextView 在两行中带有第一个字母非常大的字体

两行ListView不显示内容

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

MySQL查询在两行中获取相同的列数据

用perl在两行之间插入新行[关闭]

Android_(控件)使用ListView显示Android系统中联系人信息