下面通过一个联系人ContentProvider的操作,先看程序效果图:
实现功能:
1、 获得手机当前所有联系人
2、 获得当前通话记录
下面开始正式程序,首先是界面清单
main.xml 程序主界面 包括俩个按钮和一个ListView
contacts.xml 联系人listview单项样式
calllog.xml 通话记录中listview单项样式
根据ContentProvider的操作规律,关键点是获得要操作数据的URI地址,下面是联系人的操作地址:
联系人的Uri: ContactsContract.Contacts.CONTENT_URI
通话记录的URI:android.provider.CallLog.Calls.CONTENT_URI
下面是源文件清单:
ContentProviderExActivity.java 程序入口 及获取联系人列表
package com.freshstu;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import android.net.*;
import android.content.*;
public class ContentProviderExActivity extends Activity {
/** Called when the activity is first created. */
private Button queryBut = null;
private Button logBut = null;
private ListView listView = null;
// 存放返会结果
private Cursor result = null;
// 存放显示数据
private List
CallLog.java 通话记录列表
package com.freshstu;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.provider.*;
public class CallLog extends Activity {
private Button queryBut = null;
private Button logBut = null;
private ListView listView = null;
private SimpleAdapter simple = null;
private List> list = null;
private Cursor result = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.contacts);
queryBut = (Button) findViewById(R.id.query);
logBut = (Button) findViewById(R.id.log);
queryBut.setVisibility(View.GONE);
logBut.setVisibility(View.VISIBLE);
logBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// 这里是查询函数
result = queryCallLog();
System.out.println("通话记录条数:" + result.getCount());
list = new ArrayList>();
while (result.moveToNext()) {
// 显示五个部分:姓名、通话起始时间、通话时间、通话类型、来电号码
Map map = new HashMap();
String tempName = result.getString(result
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
if (tempName == null || "".equals(tempName)) {
tempName = "号码不详";
}
map.put("name", tempName);
map.put("time",
result.getString(result
.getColumnIndex(android.provider.CallLog.Calls.DATE)));
map.put("phone",
result.getString(result
.getColumnIndex(android.provider.CallLog.Calls.NUMBER)));
map.put("duration",
result.getString(result
.getColumnIndex(android.provider.CallLog.Calls.DURATION)));
int tid = result.getInt(result
.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String tempType =null;
switch (tid) {
case 1:
tempType = "来电";
break;
case 2:
tempType = "去电";
break;
case 3:
tempType = "未接";
break;
}
map.put("type",tempType);
list.add(map);
}
System.out.println("list size:" + list.size());
simple = new SimpleAdapter(CallLog.this, list,
R.layout.calllog, new String[] { "name", "phone",
"time", "duration", "type" }, new int[] {
R.id.log_name, R.id.log_phone, R.id.log_time,
R.id.log_duration, R.id.log_type });
listView.setAdapter(simple);
}
});
}
private Cursor queryCallLog() {
// 获得客户端对象ContentResolver并进行查询操作
return super.getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DEFAULT_SORT_ORDER);
}
}
其中有一点,需要说明的query操作会返回一个Cursor,获取Cursor后需要将数据遍历到listView中去,除了传统的遍历方法以外还有一个专用的适配器SimpleCursorAdapter,通过该适配器可以一次性的将数据呈现出来,而不用手动写代码遍历将数据放到List集合中,不过这样操作有一个缺点就是无法截获数据对数据加工,比如上面通话记录中返回的通话类型是int值,分别代表3个不同状态,想要将这3个状态变得更友好,就必须对查询返回的数据进行加工,而SimpleCursorAdapter就无法进行这样的操作,其直接将数据转化为显示状态。所以如果你希望查询得到的数据能够符合你自己的要求,希望再加功就最好使用前者,相反使用后者可以生省不少力
package com.freshstu;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.*;
import android.widget.SimpleAdapter;
public class CopyOfCallLog extends Activity {
private Button queryBut = null;
private Button logBut = null;
private ListView listView = null;
private ListAdapter listAdapter = null;
private Cursor result = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.contacts);
queryBut = (Button) findViewById(R.id.query);
logBut = (Button) findViewById(R.id.log);
queryBut.setVisibility(View.GONE);
logBut.setVisibility(View.VISIBLE);
logBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// 这里是查询函数
result = queryCallLog();
System.out.println("通话记录条数:" + result.getCount());
listAdapter = new SimpleCursorAdapter(
CopyOfCallLog.this,
R.layout.calllog,
result,
new String[] {
android.provider.CallLog.Calls.CACHED_NAME,
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.DATE,
android.provider.CallLog.Calls.DURATION,
android.provider.CallLog.Calls.TYPE },
new int[] { R.id.log_name, R.id.log_phone,
R.id.log_time, R.id.log_duration, R.id.log_type });
listView.setAdapter(listAdapter);
}
});
}
private Cursor queryCallLog() {
// 获得客户端对象ContentResolver并进行查询操作
return super.getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DEFAULT_SORT_ORDER);
}
}
这里是使用后的效果图(注意红圈标注通话类型的显示)
结束语:
Contentprovider的开发比较复杂,但是其使用却相对简单的多,只要能找到正确的数据位置(uri), 其它操作与操作SQLIte数据库基本一致。
代码下载:
http://115.com/file/c283izeb