標籤:android 簡訊 通訊錄
前兩篇部落格並分別講了擷取連絡人和通話記錄的知識,這篇主要介紹簡訊擷取知識,簡訊在通訊管理中應該說是一個痛點,因為簡訊涉及到短息會話和簡訊詳情兩個部分,並且簡訊的資料量比較大,可以採用AsyncQueryHandler架構來查詢,同時採用CursorAdapter來綁定資料
其中簡訊中可以來擷取連絡人的頭像和姓名。這個在代碼工具類中有實現,如果連絡人存在,則顯示姓名,否則顯示號碼,如果連絡人頭像存在則顯示頭像,否則顯示預設頭像,片所示。這兩部分功能在連絡人和通話記錄中均可以實現,有興趣的童鞋可以修改。
查詢方塊架
package cn.zxw.contact.utils;import android.content.AsyncQueryHandler;import android.content.ContentResolver;import android.database.Cursor;import android.support.v4.widget.CursorAdapter;import android.util.Log;/** * QueryHandler架構 * @author zhan * */public class QueryHandler extends AsyncQueryHandler {private static final String TAG = "QueryHandler";public QueryHandler(ContentResolver cr) {super(cr);}@Overrideprotected void onQueryComplete(int token, Object cookie, Cursor cursor) {super.onQueryComplete(token, cookie, cursor);String names[] = cursor.getColumnNames();for (String name : names) {Log.i(TAG, name);}// 查詢完成//if (cookie != null && cookie instanceof CursorAdapter) {// 把查詢出來的cursor結果設定給adapterCursorAdapter adapter = (CursorAdapter) cookie;adapter.changeCursor(cursor);}}}簡訊會話擷取
package cn.zxw.contact;import cn.zxw.contact.utils.ContactsUtils;import cn.zxw.contact.utils.QueryHandler;import cn.zxw.contact.utils.TimeUtils;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.net.Uri;import android.os.Bundle;import android.support.v4.widget.CursorAdapter;import android.text.TextUtils;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;/** * 簡訊列表 * 點擊短息列表中的條目會進入條目對應的簡訊詳情頁面 * @author zhan * */public class MsgActivity extends Activity implements OnItemClickListener {private ListView lv;public MyCursorAdapter adapter;// 查詢的結果集private String[] projection = new String[] { "snippet","sms.thread_id as _id", "msg_count", "sms.address as address","sms.date as date" };private final static int SINPPET_COLUMN_INDEX = 0;private final static int THREAD_ID_COLUMN_INDEX = 1;private final static int MSG_COUNT_COLUMN_INDEX = 2;private final static int ADDRESS_COLUMN_INDEX = 3;private final static int DATE_COLUMN_INDEX = 4;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_contacts_msg_calllog);lv = (ListView) findViewById(R.id.lv);adapter=new MyCursorAdapter(this, null);//初始化Adapterlv.setAdapter(adapter);startQuery();lv.setOnItemClickListener(this);}/** * 執行查詢 */private void startQuery() {QueryHandler mQueryHandler = new QueryHandler(getContentResolver());// 執行查詢/** * token唯一標識 cookie可以用來傳遞資料 上面的參數會傳遞給一個方法 onQueryComplete */Uri uri = Uri.parse("content://sms/conversations");// mQueryHandler.startQuery(0, null, uri, projection, null,// null,"date desc");mQueryHandler.startQuery(0, adapter, uri, projection, null, null,"date desc");}// 自訂CursorAdapterprivate class MyCursorAdapter extends CursorAdapter {private LayoutInflater mInflater;public MyCursorAdapter(Context context, Cursor c) {super(context, c);mInflater = LayoutInflater.from(context);}// 建立條目@Overridepublic View newView(Context context, Cursor cursor, ViewGroup parent) {View view = mInflater.inflate(R.layout.activity_msg_list_item,null);return view;}// 綁定條目@Overridepublic void bindView(View view, Context context, Cursor cursor) {// 1.擷取條目// 2.擷取資料// 3.綁定資料ImageView iv_header = (ImageView) view.findViewById(R.id.iv_header);TextView tv_number = (TextView) view.findViewById(R.id.tv_number);TextView tv_body = (TextView) view.findViewById(R.id.tv_body);TextView tv_date = (TextView) view.findViewById(R.id.tv_date);// 由於Listview的資料顯示是通過適配器來控制的,所以到bindView方法中來控制checkbox 的顯示// 擷取資料int id = cursor.getInt(THREAD_ID_COLUMN_INDEX);String address = cursor.getString(ADDRESS_COLUMN_INDEX);int msg_count = cursor.getInt(MSG_COUNT_COLUMN_INDEX);long date = cursor.getLong(DATE_COLUMN_INDEX);String body = cursor.getString(SINPPET_COLUMN_INDEX);System.out.println(address);// 綁定資料String displayName = ContactsUtils.getContactNameByAddress(getApplicationContext(), address);if (TextUtils.isEmpty(displayName)) {// 未知連絡人iv_header.setImageResource(R.drawable.ic_launcher);tv_number.setText(address + "(" + msg_count + ")");} else {// 已知連絡人tv_number.setText(displayName + "(" + msg_count + ")");Bitmap bitmap = ContactsUtils.getContactPhotoByAddress(getApplicationContext(), address);if (bitmap == null) {iv_header.setImageResource(R.drawable.ic_launcher);} else {iv_header.setImageBitmap(bitmap);}}tv_body.setText(body);String dataStr = TimeUtils.formatDate(getApplicationContext(), date);tv_date.setText(dataStr);}}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {//傳遞資料Cursor cursor = (Cursor) adapter.getItem(position);int _id = cursor.getInt(THREAD_ID_COLUMN_INDEX);String address=cursor.getString(ADDRESS_COLUMN_INDEX);String displayName=ContactsUtils.getContactNameByAddress(getApplicationContext(), address);//進入列表詳情頁面Intent intent=new Intent(this, MsgDetailActivity.class);intent.putExtra("_id", _id);intent.putExtra("address", address);intent.putExtra("displayName", displayName);startActivity(intent);}}簡訊詳情頁面,可以實現發送短息
package cn.zxw.contact;import cn.zxw.contact.utils.Constants;import cn.zxw.contact.utils.ContactsMsgUtils;import cn.zxw.contact.utils.QueryHandler;import cn.zxw.contact.utils.TimeUtils;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.os.Bundle;import android.support.v4.widget.CursorAdapter;import android.text.TextUtils;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;public class MsgDetailActivity extends Activity implements OnClickListener {private Button bt_back;private TextView tv_number;private ListView lv;private EditText et_msg_content;private Button bt_send;private int _id;private String address;private MyCursorAdapter adapter;private String[] projection=new String[]{"_id","type","body","date"};private final static int ID_COLUMN_INDEX=0;private final static int TYPE_COLUMN_INDEX=1;private final static int BODY_COLUMN_INDEX=2;private final static int DATE_COLUMN_INDEX=3;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_msg_list_detail);initView();startQuery();}public void initView() {bt_back = (Button) findViewById(R.id.bt_back);tv_number = (TextView) findViewById(R.id.tv_number);lv = (ListView) findViewById(R.id.lv);et_msg_content = (EditText) findViewById(R.id.et_msg_content);bt_send = (Button) findViewById(R.id.bt_send);bt_back.setOnClickListener(this);bt_send.setOnClickListener(this);Intent intent=getIntent();_id = intent.getIntExtra("_id", 0);address = intent.getStringExtra("address");String displayName=intent.getStringExtra("displayName");if (TextUtils.isEmpty(displayName)) {tv_number.setText(address);}else{tv_number.setText(displayName);}adapter = new MyCursorAdapter(this, null);lv.setAdapter(adapter);}public void startQuery() {//查詢QueryHandler mHandler=new QueryHandler(getContentResolver());//查詢指定會話id裡面的所有簡訊String selection="thread_id=?";String[] selectionArgs=new String[]{_id+""};mHandler.startQuery(0, adapter, Constants.SMS_URI, projection, selection, selectionArgs, "date asc");}private class MyCursorAdapter extends CursorAdapter{public MyCursorAdapter(Context context, Cursor c) {super(context, c);}@Overridepublic View newView(Context context, Cursor cursor, ViewGroup viewGroup) {View view=getLayoutInflater().inflate(R.layout.activity_msg_detial_item, null);return view;}@Overridepublic void bindView(View view, Context context, Cursor cursor) {TextView tv_date=(TextView) view.findViewById(R.id.tv_date);TextView tv_send=(TextView) view.findViewById(R.id.tv_send);TextView tv_receive=(TextView) view.findViewById(R.id.tv_receive);long date=cursor.getLong(DATE_COLUMN_INDEX);String body=cursor.getString(BODY_COLUMN_INDEX);int type=cursor.getInt(TYPE_COLUMN_INDEX);String str=TimeUtils.formatDate(getApplicationContext(), date);tv_date.setText(str);if (type==Constants.RECEIVE_TYPE) {//1表示接收tv_date.setVisibility(View.VISIBLE);tv_receive.setText(body);tv_send.setVisibility(View.GONE);}else if (type==Constants.SEND_TYPE) {//2表示發送tv_date.setVisibility(View.VISIBLE);tv_send.setVisibility(View.VISIBLE);tv_send.setText(body);tv_receive.setVisibility(View.GONE);}}/** * 該方法一定會被系統調用 */@Overridepublic void notifyDataSetChanged() {super.notifyDataSetChanged();//讓Listview滾動到最後面lv.setSelection(adapter.getCount()-1);}}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.bt_back:finish();//關閉當前activitybreak;case R.id.bt_send:// 擷取短息內容String content=et_msg_content.getText().toString().trim();if (TextUtils.isEmpty(content)) {//發送內容為空白Toast.makeText(getApplicationContext(), "簡訊為空白", 0).show();}else{ContactsMsgUtils.sendMsg(getApplicationContext(), address, content);//清空et_msg_content.setText("");//短息發送成功後自動滾動到最後}break;default:break;}}}簡訊發送方法:
/** * 傳送簡訊 * @param address * @param content */public static void sendMsg(Context context,String address,String content){SmsManager smsManager=SmsManager.getDefault();//如果簡訊太長,拆分簡訊ArrayList<String> parts=smsManager.divideMessage(content);smsManager.sendMultipartTextMessage(address, null, parts, null, null);//手動儲存簡訊ContentResolver resolver=context.getContentResolver();Uri uri=Constants.SMS_URI;ContentValues values=new ContentValues();values.put("address", address);values.put("body", content);values.put("type", Constants.SEND_TYPE);values.put("date", System.currentTimeMillis());resolver.insert(uri, values);}關於AsyncQueryHandler和CursorAdapter可以參考http://blog.csdn.net/yuzhiboyi/article/details/8093408和http://blog.csdn.net/yuzhiboyi/article/details/7654840來學習
Android通訊錄管理三之短息擷取和發送短息