使用CursorLoader读取手机通讯录
今天get到一个新技能,使用CursorLoader异步加载数据通讯录数据。
实现功能:通过读取手机通讯录所有联系人的名字及联系号码,将数据通过CursorLoader异步加载到ListView上。
这是效果图。因为模拟器上我只存了一个联系人,使用效果不明显,我将apk下载到手机上安装读取联系人完全没有问题,因为联系人关系到一些不可描述的小秘密,就不截图出来了。
工程目录结构图:
非常简单有木有,只有一个类和两个布局文件,一个是activity的布局文件,一个是自定义适配器的布局文件。好吧,又是自定义适配器。我的原则就是学习的时候多写多练,所以我都是怎么复杂怎么来的。
上代码———————————–
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity implements LoaderCallbacks<Cursor> {
private ListView listView;
private LoaderManager loaderManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
loaderManager = getLoaderManager();
loaderManager.initLoader(1111, null, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO Auto-generated method stub
Uri uri = ContactsContract.Contacts.CONTENT_URI;
CursorLoader cursorLoader = new CursorLoader(this, uri, null, null,
null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// TODO Auto-generated method stub
List<List<String>> list = new ArrayList<List<String>>();
//list存储整个联系人的数据
while (data.moveToNext()) {
String name = null;
List<String> list_data = new ArrayList<String>();
//list_data存储单个联系人的数据,我只读取了名字和电话号码。
name = data.getString(data
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
int id = data.getInt(data
//android 内部通讯录并不是将电话和联系人存储在同一张表格中,而是通过一个ID将联系人和电话关联
.getColumnIndex(ContactsContract.Contacts._ID));
Cursor cursor = getContentResolver().query( //通过ID获取对应的电话表格游标
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
+ id, null, null);
while (cursor.moveToNext()) {//遍历游标获取电话
list_data.add(name);
list_data.add(cursor
.getString(cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
//ContactsContract.CommonDataKinds下的常量可以去查找一下官方API太多了一两句解释不清,官网这一节有中文的的翻译
}
list.add(list_data);
}
myAdapter adapter = new myAdapter(list);
listView.setAdapter(adapter);
}
//自定义适配器
class myAdapter extends BaseAdapter {
List<List<String>> list = new ArrayList<List<String>>();
public myAdapter(List<List<String>> list) {
// TODO Auto-generated constructor stub
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = null;
if (convertView == null) {
view = LayoutInflater.from(MainActivity.this).inflate(
R.layout.list, null);
} else {
view = convertView;
}
TextView textView2 = (TextView) view
.findViewById(R.id.list_textView2);
TextView textView3 = (TextView) view
.findViewById(R.id.list_textView3);
List<String> list1 = new ArrayList<String>();
list1 = list.get(position);
textView2.setText(list1.get(0));
textView3.setText(list1.get(1));
return view;
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// TODO Auto-generated method stub
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#cccccc"
android:paddingBottom="10sp" >
<TextView
android:id="@+id/textView2"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:paddingTop="10dp"
android:text="姓名"
android:textColor="#2828ff"
android:textSize="20sp" />
<TextView
android:id="@+id/textView3"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center_horizontal"
android:paddingTop="10dp"
android:text="电话"
android:textColor="#2828ff"
android:textSize="20sp" />
</LinearLayout>
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<TextView
android:id="@+id/list_textView2"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="TextView"
android:textSize="20sp" />
<TextView
android:id="@+id/list_textView3"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center"
android:text="TextView"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>