Android中获取联系人信息(一)


        在上一篇学习ListView的时候,看到在API中获取联系人的例子已经不被官方推荐了。于是,手痒又查了查,看看使用Android如何获取联系人信息。这篇可以说着对ListView继续深入学习,也是对android中访问联系人信息的学习。

        在学习的过程中参考了很多资料,其中写得比较好的是这一篇http://xys289187120.blog.51cto.com/3361352/656766

我的例子也基本上是模仿他写的。

       

下面看代码

          
package com.example.contactlist;

import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MainActivity extends ListActivity {

	Context myContext = null;
	MyListAdapter myListAdapter = null;
	TextView name = null;
	TextView number = null;
	
	//这两个List用于暂时存储联系人的名字和号码
	List<String> myContactName = new ArrayList<String>();
	List<String> myContactNumber = new ArrayList<String>();	

	public void onCreate(Bundle savedInstanceState) {
		
		myContext = this;
		
		//使用getContentResolver方法来读取联系人的表
		Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null); 
				  
		while(cursor.moveToNext()){ 
				//联系人的ID
				String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 
				//联系人的名称
				String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
				//联系人的电话
				String number = "";
				
				//联系人是否有电话号码
				int isHas = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts. HAS_PHONE_NUMBER))); 
				  
				if(isHas>0){ 
					Cursor c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = " + id,null,null); 
					while(c.moveToNext()){ 
						number += c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))+"  "; 
						
					} 
					c.close(); 
				} 
				myContactName.add(name);
				myContactNumber.add(number);
		} 
		cursor.close();
			
		myListAdapter = new MyListAdapter(this);
		setListAdapter(myListAdapter);
		super.onCreate(savedInstanceState);
	}
	
	
	//定义一个BaseAdpter的子类,并重写getView方法
	class MyListAdapter extends BaseAdapter {		
		public MyListAdapter(Context context){
			myContext = context;
		}
	
		public int getCount() {
			// TODO Auto-generated method stub
			return myContactName.size();
		}
	
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return position;
		}
	
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}
	
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			

			if(convertView == null){
				//将List布局文件实例化为一个View
				convertView = LayoutInflater.from(myContext).inflate(R.layout.list, null);
				name = (TextView) convertView.findViewById(R.id.name);
				number = (TextView) convertView.findViewById(R.id.number);				
			}
		
			name.setText(myContactName.get(position));
			number.setText(myContactNumber.get(position));
			
			return convertView;
		}
	}
}


      相对于前一篇的区别是,这次的代码中定义了一个BaseAdpter的子类,并重写了getView方法。

      还有一点就是

  Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
        这一句代码中,我们通过getContentResolver()方法来读取联系人数据库中的内容。getContentResolver可以读取通过ContentProvider提供的数据。这里先不细说了。

        这个程序运行起来,刚开始是没问题的,所有的联系人都读取出来了。但是,当我向下拖动ListView的时候,发现,有的联系人的信息刷新变成了别的联系人,有的联系人顺序也变了,总之一拖动ListView就会出现一些比较奇怪的现象。

        我把这个问题放到一些论坛上和大家讨论了一下。目前个人认为比较靠谱的解释是我在getView中的写法会导致Item中的View重新初始化。。所以会导致一些联系人变了。。(谁有更好的解释留言告诉我一下)

 

我试了一种比较好的解决方法就是加上一个静态类ViewHolder,修改后代码如下

 

package com.example.contactlist;

import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MainActivity extends ListActivity {

	Context myContext = null;
	MyListAdapter myListAdapter = null;
	ViewHolder viewHolder = null;
	
	List<String> myContactName = new ArrayList<String>();
	List<String> myContactNumber = new ArrayList<String>();

	public void onCreate(Bundle savedInstanceState) {
		
		myContext = this;
		
		//使用getContentResolver方法来读取联系人的表
		Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null); 
				  
		while(cursor.moveToNext()){ 
				//联系人的ID
				String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 
				//联系人的名称
				String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
				//联系人的电话
				String number = "";
				
				//联系人是否有电话号码
				int isHas = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts. HAS_PHONE_NUMBER))); 
				  
				if(isHas>0){ 
					Cursor c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = " + id,null,null); 
					while(c.moveToNext()){ 
						number += c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))+"  "; 
						
					} 
					c.close(); 
				} 
				myContactName.add(name);
				myContactNumber.add(number);
		} 
		cursor.close();
		
		
		myListAdapter = new MyListAdapter(this);
		setListAdapter(myListAdapter);
		super.onCreate(savedInstanceState);
	}
	
	class MyListAdapter extends BaseAdapter {
		
		public MyListAdapter(Context context){
			myContext = context;
		}
	

		public int getCount() {
			// TODO Auto-generated method stub
			return myContactName.size();
		}
	
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return position;
		}
	
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}
	
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			

			if(convertView == null){
				viewHolder = new ViewHolder();

				convertView = LayoutInflater.from(myContext).inflate(R.layout.list, null);
				viewHolder.name = (TextView) convertView.findViewById(R.id.name);
				viewHolder.number = (TextView) convertView.findViewById(R.id.number);
				
				convertView.setTag(viewHolder);
			}else
	        {
	            viewHolder = (ViewHolder) convertView.getTag();
	        }

			viewHolder.name.setText(myContactName.get(position));
			viewHolder.number.setText(myContactNumber.get(position));
			
			return convertView;
		}
	}

    private static class ViewHolder
    {
        TextView name;
        TextView number;
     
    }

}


加上了这个类之后,我再试了试发现ListView拖动的时候比较平滑,也没有出现过联系人位置改变的情况了。

由于这个涉及到联系人信息所以就不截图了,但是代码保证是可用的。

 

附上布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
        android:id="@+id/name"
        android:layout_width="80dp" 
        android:layout_height="40dp"
        />
    
    <TextView 
        android:id="@+id/number"
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        />
</LinearLayout>


 

Android中获取联系人信息(一),布布扣,bubuko.com

Android中获取联系人信息(一)

上一篇:Unity3D发布打包系列之(四)——IOS真机调试打包ipa(补充)


下一篇:Django 设置admin后台表和App(应用)为中文名