列表视图上的 Android 联系人

Posted

技术标签:

【中文标题】列表视图上的 Android 联系人【英文标题】:Android Contacts on listview 【发布时间】:2012-02-08 12:28:09 【问题描述】:

我想在我的应用程序的列表视图中添加选定的联系人。我正在使用以下代码获取选定的代码,但它没有在列表视图上显示选定的联系人。请帮助我了解我做错了什么以及在哪里做错了

public class Contacts extends Activity implements View.OnClickListener 
    private Button AddNewContact;
private Button AddFrmContacts;
private ListView EmergencyContactList;
private final int PICK = 1001;
private final int NEW = 1002;
ArrayList<ContactDetails> ContactList = new ArrayList<ContactDetails>();
ContactDetails CD = new ContactDetails(null, null);
ContactsAdapter contactsAdapter = null;
String[] ContactsArray = null;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.add_contacts);
    EmergencyContactList = (ListView) findViewById(R.id.emergency_contact_list);
    ContactsArray = new String[ContactList.size()]; 
    contactsAdapter = new ContactsAdapter(Contacts.this, R.layout.contacts_listitem,ContactsArray);
    EmergencyContactList.setAdapter(contactsAdapter);
    AddNewContact = (Button) findViewById(R.id.add_new);
    AddFrmContacts = (Button) findViewById(R.id.from_contacts);

    EmergencyContactList.setOnItemClickListener(new OnItemClickListener() 

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) 
            // TODO Auto-generated method stub
            Log.v("Item position :",
                    EmergencyContactList.getSelectedItemPosition() + "");
        
    );
    AddFrmContacts.setOnClickListener(this);
    AddNewContact.setOnClickListener(this);


@Override
public void onResume() 
    super.onResume();
    Log.v("contactlist on resume :", ContactList.isEmpty() + " "
            + ContactList.size());
    if (!ContactList.isEmpty()) 
        Log.v("name on resume :", ContactList.get(0).Name);
        Log.v("name on resume :", ContactList.get(0).Number);
        ContactsArray = getContactsArray(ContactList);
        contactsAdapter = new ContactsAdapter(Contacts.this, R.layout.contacts_listitem,ContactsArray);
        contactsAdapter.notifyDataSetChanged();
        EmergencyContactList.setAdapter(contactsAdapter);
    


@Override
public void onClick(View v) 
    // TODO Auto-generated method stub
    switch (v.getId()) 
    case R.id.add_new:
        Intent NewContactIntent = new Intent(Contacts.this,
                SOSAddNewContact.class);
        startActivityForResult(NewContactIntent, NEW);
        break;
    case R.id.from_contacts:
        Intent intent = new Intent(Intent.ACTION_PICK,
                ContactsContract.Contacts.CONTENT_URI);
        // calling OnActivityResult with intenet And Some conatct for
        // Identifie
        startActivityForResult(intent, PICK);
        break;
    


@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) 
    super.onActivityResult(reqCode, resultCode, data);
    String name = null;
    String PhoneNumber = "";
    switch (reqCode) 
    case (PICK):
        Uri contactData = data.getData();
        Cursor c = managedQuery(contactData, null, null, null, null);
        if (c.moveToFirst()) 
            name = c.getString(c
                    .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            Log.v("_ID", name);
            int HasNumber = c
                    .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
            if (HasNumber > 0) 
                Uri result = data.getData();
                Log.v("TAG", "Got a contact result: " + result.toString());
                String id = result.getLastPathSegment();
                try 
                    c = getContentResolver().query(Phone.CONTENT_URI, null,
                            Phone.CONTACT_ID + "=?", new String[]  id ,
                            null);
                    int contactnumberidx = c.getColumnIndex(Phone.DATA);
                    if (c.moveToFirst()) 
                        PhoneNumber = c.getString(contactnumberidx);
                        Log.v("TAG", "Got number: " + PhoneNumber);
                        CD = new ContactDetails(name, PhoneNumber);
                        ContactList.add(CD);
                     else 
                        Log.w("TAG", "No results");
                    
                 catch (Exception e) 
                    Log.e("TAG", "Failed to get phone data", e);
                 finally 
                    if (c != null) 
                        c.close();
                    
                
            
        
        break;
    case NEW :
        if(resultCode == Activity.RESULT_OK)
            Log.v("on activity result", "OK");
        else
            Log.v("result", "not OK");
        Bundle extras = data.getExtras();
        if(extras != null)
        name = extras.getString("Name");
        PhoneNumber = extras.getString("Number");
        CD = new ContactDetails(name, PhoneNumber);
        ContactList.add(CD);
        for(int i = 0;i<ContactList.size();i++)
            Log.v("ContactList", i+" "+ContactList.get(i).Name);
        else
            Log.v("extras ", "NULL");
        
        break;
    


public String[] getContactsArray(ArrayList<ContactDetails> List)
    if(!List.isEmpty())
        for(int i=0;i<=List.size()-1;i++)
            ContactsArray = new String[List.size()];
            ContactsArray[i] = List.get(i).Name +"\n"+ List.get(i).Number;
        
    
    return ContactsArray;


LOGCAT

01-16 17:23:50.954: I/InputReader(61): Device reconfigured: id=0x0, name=qwerty2, display size is now 320x480
01-16 17:23:50.954: I/InputManager-Callbacks(61): No virtual keys found for device qwerty2.
01-16 17:23:51.379: I/ARMAssembler(61): generated scanline__00000077:03515104_00001004_00000000 [ 65 ipp] (85 ins) at [0x4437d520:0x4437d674] in 908313 ns
01-16 17:23:51.399: I/ARMAssembler(61): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x4437d678:0x4437d840] in 707349 ns
01-16 17:23:52.950: I/ActivityManager(61): Starting: Intent  cmp=com.sos.emergency/.SOSAddContacts  from pid 386
01-16 17:23:53.080: V/contactlist on resume :(386): true 0
01-16 17:23:53.389: I/ActivityManager(61): Displayed com.sos.emergency/.Contacts: +415ms
01-16 17:23:54.040: I/ActivityManager(61): Starting: Intent  cmp=com.sos.emergency/.SOSAddNewContact  from pid 386
01-16 17:23:54.429: I/ActivityManager(61): Displayed com.sos.emergency/.SOSAddNewContact: +374ms
01-16 17:24:05.449: W/KeyCharacterMap(386): No keyboard for id 0
01-16 17:24:05.449: W/KeyCharacterMap(386): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
01-16 17:24:13.729: D/dalvikvm(61): GREF has increased to 401
01-16 17:24:24.400: V/intent data(386): abc 5555555555
01-16 17:24:24.450: V/on activity result(386): OK
01-16 17:24:24.450: V/ContactList(386): 0 abc
01-16 17:24:24.450: V/contactlist on resume :(386): false 1
01-16 17:24:24.459: V/name on resume :(386): abc
01-16 17:24:24.459: V/name on resume :(386): 5555555555
01-16 17:24:26.850: I/ActivityManager(61): Starting: Intent  act=android.intent.action.PICK dat=content://com.android.contacts/contacts cmp=com.android.contacts/.ContactsListActivity  from pid 386
01-16 17:24:27.230: D/dalvikvm(180): GC_CONCURRENT freed 482K, 49% free 3050K/5959K, external 716K/1038K, paused 4ms+5ms
01-16 17:24:27.400: I/ContactsListActivity(180): Called with action: android.intent.action.PICK
01-16 17:24:28.299: I/ActivityManager(61): Displayed com.android.contacts/.ContactsListActivity: +1s431ms
01-16 17:24:30.419: V/_ID(386): Jordan
01-16 17:24:30.419: V/TAG(386): Got a contact result: content://com.android.contacts/contacts/lookup/0r4-3F494F332D47/4
01-16 17:24:30.480: V/TAG(386): Got number: 845-435-3555
01-16 17:24:30.489: V/contactlist on resume :(386): false 2
01-16 17:24:30.489: V/name on resume :(386): abc
01-16 17:24:30.489: V/name on resume :(386): 5555555555
01-16 17:24:30.550: W/InputManagerService(61): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@4050be88 (uid=10000 pid=180)
01-16 17:24:39.319: I/ActivityManager(61): Starting: Intent  act=android.intent.action.PICK dat=content://com.android.contacts/contacts cmp=com.android.contacts/.ContactsListActivity  from pid 386
01-16 17:24:39.360: I/ContactsListActivity(180): Called with action: android.intent.action.PICK
01-16 17:24:39.689: D/dalvikvm(180): GC_CONCURRENT freed 333K, 47% free 3238K/6023K, external 914K/1038K, paused 5ms+6ms
01-16 17:24:39.979: I/ActivityManager(61): Displayed com.android.contacts/.ContactsListActivity: +643ms
01-16 17:24:41.269: V/_ID(386): Akriti
01-16 17:24:41.269: V/TAG(386): Got a contact result: content://com.android.contacts/contacts/lookup/0r3-2D414F3D533D/3
01-16 17:24:41.309: V/TAG(386): Got number: 854-741-1111
01-16 17:24:41.319: V/contactlist on resume :(386): false 3
01-16 17:24:41.330: V/name on resume :(386): abc
01-16 17:24:41.330: V/name on resume :(386): 5555555555
01-16 17:24:41.389: W/InputManagerService(61): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@4050be88 (uid=10000 pid=180)
01-16 17:25:00.189: D/dalvikvm(130): GC_CONCURRENT freed 246K, 48% free 2970K/5703K, external 956K/1038K, paused 5ms+6ms

【问题讨论】:

你能看到 onActivityResult() 中记录的文本吗?您的 ContactsList() 是否包含您在活动恢复时选择的联系人? @Hiral : 查看我的编辑我也添加了日志 您可以展示您的 ContactsAdapter 吗?是的,只需将 ContactAdapter 声明为 ContactsAdapter contactsAdapter;而不是在初始化时将 null 放在那里。 @hiral : 我添加了代码,现在看 为什么不尝试使用自定义 ArrayAdapter 类而不是 BaseAdapter? 【参考方案1】:

尝试对您当前的适配器类进行以下更改:

public class ContactsAdapter extends BaseAdapter 

    ArrayList<ContactDetails> contactDetails = new ArrayList<ContactDetails>();
    Context c;    
    LayoutInflater mInflater;

    public ContactsAdapter(Context context,ArrayList<ContactDetails> ContactDetails) 

        contactDetails = ContactDetails;        
        c=context;
        mInflater = LayoutInflater.from(context);  
        Log.v("constructor", contactDetails.size()+"");
    

    @Override
    public int getCount() 

        Log.v("getCount", "");
        return contactDetails.size();
    
    @Override
    public Object getItem(int position) 

        Log.v("getItem", position+" ");
        return contactDetails.get(position);
    
    @Override
    public long getItemId(int position) 

        Log.v("getItemId", position+"");
        return position;
    
    @Override
    public View getView(int position, View convertView,ViewGroup parent) 

        final ViewHolder holder;
        Log.v("in :","get View");        

        if (convertView == null)
                    
            convertView = mInflater.inflate(R.layout.contacts_listitem, null);
            holder = new ViewHolder();

            holder.text=(TextView)convertView.findViewById(R.id.text);
            convertView.setTag(holder);

            Log.v("TAG", "convert view not null");
         
        else       
            holder=(ViewHolder)convertView.getTag();

        textview.setText(contactDetails.get(position).Name);

        return convertView;
    
    static class ViewHolder
    
        TextView text;            
    

还包括名为 contacts_listitem.xml 的布局文件,如下所示。

现在您也需要在主要活动中更改这些行:

...
contactsAdapter = new ContactsAdapter(Contacts.this,ContactList);
EmergencyContactList.setAdapter(contactsAdapter);
...

在这里,您还没有为您的列表视图设置适配器,因此它没有向您显示任何内容。您错过了 EmergencyContactList.setAdapter(contactsAdapter); 行。 请按照上面的方法做,然后告诉我结果。

编辑

您也可以尝试使用自定义 ArrayAdapter 类,例如:

ContactsAdapter.class:

public class ContactsAdapter extends ArrayAdapter<String> 

    String[] array;
    LayoutInflater mInflater;

    public ContactsAdapter(Context context, int textViewResourceId,
            String[] objects)
    
        super(context, textViewResourceId, objects);
        array=objects;
        mInflater = LayoutInflater.from(context);               
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
           
        final ViewHolder holder;

        if(convertView==null)
        
                 convertView = mInflater.inflate(R.layout.contacts_listitem, null);
                 holder = new ViewHolder();

                 holder.text=(TextView)convertView.findViewById(R.id.text);
                 convertView.setTag(holder);
        
        else
                holder=(ViewHolder)convertView.getTag();

        holder.text.setText(array[position]);

        return convertView;
    

    static class ViewHolder
    
        TextView text;            
    

创建布局文件contacts_listitem.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_
    android:layout_>

    <TextView
        android:layout_
        android:layout_
        android:id="@+id/text"
        android:textSize="18dip"
        android:padding="5dip"      
        android:textColor="#90000000"
        android:layout_weight="0.9"
        />
</LinearLayout>

现在您需要在主要活动中使用 ContactsAdapter 的对象,例如:

...
ContactsAdapter aa=new ContactsAdapter(context,R.layout.contacts_listitem, new String[]"contact1","contact2","contact3","contacts4");
listView.setAdapter(aa);
...

在这里,您可以相应地在 onActivityResult() 中构建您的字符串数组。(我没有得到您在适配器类中所做的工作来显示联系人详细信息,所以我只是将字符串数组中的字符串放入适配器中。您必须编写代码根据您的需要。)

编辑:

在您的应用中更改这些代码行:

public String[] getContactsArray(ArrayList<ContactDetails> List)
    
    ContactsArray = new String[List.size()];
    for(int i=0;i<=List.size()-1;i++)
               
        ContactsArray[i] = List.get(i).Name +"\n"+ List.get(i).Number;
       
    return ContactsArray;

这里,你不需要检查列表是否为空,因为你在调用这个函数之前已经这样做了。

【讨论】:

您是否尝试将适配器设置为列表视图?您必须设置它..在您的代码中,我没有找到它。 感谢 Hiral 的快速回复,解决了我的问题 :) @DroidShruti:很高兴为您提供帮助.. :)

以上是关于列表视图上的 Android 联系人的主要内容,如果未能解决你的问题,请参考以下文章

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

联系人没有加载到我的列表视图android中

列表视图中的Android联系人图像占位符

在 Android 中高效处理动态列表视图项

如何使用复选框将Android联系人添加到列表视图中[重复]

如何在 Android for Android api 11+ 的列表视图中显示联系人