Android通讯录管理(获取联系人、通话记录、短信消息)(二)
前言:上一篇博客介绍的是获取联系人的实现,本篇博客将介绍通话记录的实现。
同样的,你可以到这里下载源码:http://download.csdn.net/detail/wwj_748/6962865
界面布局:
/Contact_Demo/res/layout/contact_record_list_view.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/contact_record_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000"> <ListView android:id="@+id/call_log_list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentTop="true" android:cacheColorHint="#000000" android:fadingEdge="none" android:scrollingCache="false" android:visibility="visible" /> </RelativeLayout>
/Contact_Demo/res/layout/contact_record_list_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:id="@+id/call_type" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="5dip" android:layout_marginRight="5dip" android:background="@drawable/ic_calllog_outgoing_nomal" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/call_type" android:orientation="vertical" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="0dip" android:layout_weight="1" android:textAppearance="?android:textAppearanceMedium" android:textColor="#ffffff" /> <TextView android:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:textAppearanceSmall" android:textColor="#cccccc" /> </LinearLayout> <TextView android:id="@+id/call_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" android:background="@drawable/ic_calllog_call_btn" /> <ImageView android:id="@+id/fg" android:layout_width="wrap_content" android:layout_height="75dip" android:layout_toLeftOf="@+id/call_btn" android:background="@drawable/black_bg" /> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@+id/fg" android:textColor="#ffffff" /> </RelativeLayout>
定义实体类:
/Contact_Demo/src/com/suntek/contact/model/CallLogBean.java
package com.suntek.contact.model; /** * 通话记录实体类 * * @author Administrator * */ public class CallLogBean { private int id; private String name; // 名称 private String number; // 号码 private String date; // 日期 private int type; // 来电:1,拨出:2,未接:3 private int count; // 通话次数 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public int getType() { return type; } public void setType(int type) { this.type = type; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
/Contact_Demo/src/com/suntek/contact/adapter/DialAdapter.java
package com.suntek.contact.adapter; import java.util.List; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.suntek.contact.R; import com.suntek.contact.model.CallLogBean; /** * 电话记录适配器 * * @author Administrator * */ public class DialAdapter extends BaseAdapter { private Context ctx; private List<CallLogBean> callLogs; private LayoutInflater inflater; public DialAdapter(Context context, List<CallLogBean> callLogs) { this.ctx = context; this.callLogs = callLogs; this.inflater = LayoutInflater.from(context); } @Override public int getCount() { return callLogs.size(); } @Override public Object getItem(int position) { return callLogs.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.contact_record_list_item, null); holder = new ViewHolder(); holder.call_type = (ImageView) convertView .findViewById(R.id.call_type); holder.name = (TextView) convertView.findViewById(R.id.name); holder.number = (TextView) convertView.findViewById(R.id.number); holder.time = (TextView) convertView.findViewById(R.id.time); holder.call_btn = (TextView) convertView .findViewById(R.id.call_btn); convertView.setTag(holder); // 缓存 } else { holder = (ViewHolder) convertView.getTag(); } CallLogBean callLog = callLogs.get(position); switch (callLog.getType()) { case 1: holder.call_type .setBackgroundResource(R.drawable.ic_calllog_outgoing_nomal); break; case 2: holder.call_type .setBackgroundResource(R.drawable.ic_calllog_incomming_normal); break; case 3: holder.call_type .setBackgroundResource(R.drawable.ic_calllog_missed_normal); break; } holder.name.setText(callLog.getName()); holder.number.setText(callLog.getNumber()); holder.time.setText(callLog.getDate()); addViewListener(holder.call_btn, callLog, position); return convertView; } private static class ViewHolder { ImageView call_type; TextView name; TextView number; TextView time; TextView call_btn; } private void addViewListener(View view, final CallLogBean callLog, final int position) { view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Uri uri = Uri.parse("tel:" + callLog.getNumber()); Intent intent = new Intent(Intent.ACTION_CALL, uri); ctx.startActivity(intent); } }); } }
/Contact_Demo/src/com/suntek/contact/ContactRecordListActivity.java
package com.suntek.contact; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import android.app.Activity; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.CallLog; import android.widget.ListView; import com.suntek.contact.adapter.DialAdapter; import com.suntek.contact.model.CallLogBean; /** * 通话记录列表 * * @author wwj * */ public class ContactRecordListActivity extends Activity { private ListView callLogListView; private AsyncQueryHandler asyncQuery; private DialAdapter adapter; private List<CallLogBean> callLogs; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contact_record_list_view); callLogListView = (ListView) findViewById(R.id.call_log_list); asyncQuery = new MyAsyncQueryHandler(getContentResolver()); init(); } private void init() { Uri uri = android.provider.CallLog.Calls.CONTENT_URI; // 查询的列 String[] projection = { CallLog.Calls.DATE, // 日期 CallLog.Calls.NUMBER, // 号码 CallLog.Calls.TYPE, // 类型 CallLog.Calls.CACHED_NAME, // 名字 CallLog.Calls._ID, // id }; asyncQuery.startQuery(0, null, uri, projection, null, null, CallLog.Calls.DEFAULT_SORT_ORDER); } private class MyAsyncQueryHandler extends AsyncQueryHandler { public MyAsyncQueryHandler(ContentResolver cr) { super(cr); } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { if (cursor != null && cursor.getCount() > 0) { callLogs = new ArrayList<CallLogBean>(); SimpleDateFormat sfd = new SimpleDateFormat("MM-dd hh:mm"); Date date; cursor.moveToFirst(); // 游标移动到第一项 for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); date = new Date(cursor.getLong(cursor .getColumnIndex(CallLog.Calls.DATE))); String number = cursor.getString(cursor .getColumnIndex(CallLog.Calls.NUMBER)); int type = cursor.getInt(cursor .getColumnIndex(CallLog.Calls.TYPE)); String cachedName = cursor.getString(cursor .getColumnIndex(CallLog.Calls.CACHED_NAME));// 缓存的名称与电话号码,如果它的存在 int id = cursor.getInt(cursor .getColumnIndex(CallLog.Calls._ID)); CallLogBean callLogBean = new CallLogBean(); callLogBean.setId(id); callLogBean.setNumber(number); callLogBean.setName(cachedName); if (null == cachedName || "".equals(cachedName)) { callLogBean.setName(number); } callLogBean.setType(type); callLogBean.setDate(sfd.format(date)); callLogs.add(callLogBean); } if (callLogs.size() > 0) { setAdapter(callLogs); } } super.onQueryComplete(token, cookie, cursor); } } private void setAdapter(List<CallLogBean> callLogs) { adapter = new DialAdapter(this, callLogs); callLogListView.setAdapter(adapter); } }
代码是最好的解释了,这里使用的几个重要的类,一个是Uri(进行查询的通用资源标志符),一个是AsyncQueryHandler(Android提供的异步操作数据库的类),这里我们调用它的startQuery方法来查询数据库,在它onQueryComplete方法中得到数据库返回的游标cousor,通过curor来取得数据库对应表中的字段值。