使用ContentObserver实现短信提醒功能
2015-11-07 15:58
519 查看
通过查询语句:Cursor cursor = mContext.getContentResolver().query(Uri.parse("content://sms"), null, "type = 1 and read = 0", null, null);打印可以看到数据库中所有的列字段
String names[] = cursor.getColumnNames();
name = _id i = 0 //短消息序号自动递增 如100
name = thread_id i = 1 //序号,同一发信人的id相同
name = address i = 2 //发件人地址,手机号.如:10086
name = person i = 3 //发件人,返回一个数字就是联系人列表里的序号,陌生人为null
name = date i = 4 //日期,long型
name = date_sent i = 5
name = protocol i = 6 //协议 0 SMS_RPOTO, 1 MMS_PROTO
name = read i = 7 //是否阅读 0未读, 1已读
name = status i = 8 //状态 -1接收,0 complete, 64 pending, 128 failed
name = type i = 9
//ALL = 0;
//INBOX = 1; 接收
//SENT = 2; 发送
//DRAFT = 3;
//OUTBOX = 4;
//FAILED = 5;
//QUEUED = 6;
name = reply_path_present i = 10
name = subject i = 11 //短信的主题,一般为null
name = body i = 12 //短信内容
name = service_center i = 13 //短信服务中心号码编号,如+8613800752011
name = locked i = 14
name = error_code i = 15
name = seen i = 16
name = timed i = 17
name = deleted i = 18
name = sync_state i = 19
name = marker i = 20
name = source i = 21
name = bind_id i = 22
name = mx_status i = 23
name = mx_id i = 24
name = out_time i = 25
name = account i = 26
name = block_type i = 27
name = sim_id i = 28
name = advanced_seen i = 29以上作了注释的是较为常用的,我们可以只查询出常用的列,查询函数原型:query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
第二个参数:projection,可以写上我们需要的列,第三个:selection是查询的条件。
private static final String[] PROJECTION = new String[] { SMS._ID,// 0
SMS.TYPE,// 1
SMS.ADDRESS,// 2
SMS.SUBJECT,// 3
SMS.BODY,// 4
SMS.DATE,// 5
SMS.THREAD_ID,// 6
SMS.READ,// 7
SMS.PROTOCOL // 8
};
Cursor cursor = mContext.getContentResolver().query(
SMS.CONTENT_URI, PROJECTION, "type = 1 and read = 0", null,
null);关于每个字符的类型可以看下packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java文件是如何创建表的:
下面就来看下短信提醒功能如何实现的。
程序结构
先定义一个常量类SMS.java
package com.deng.datawidget.sms;
import android.net.Uri;
import android.provider.BaseColumns;
public class SMS implements BaseColumns {
public static final Uri CONTENT_URI = Uri.parse("content://sms");
public static final String FILTER = "!imichat";
public static final String TYPE = "type";
public static final String THREAD_ID = "thread_id";
public static final String ADDRESS = "address";
public static final String PERSON_ID = "person";
public static final String DATE = "date";
public static final String READ = "read";
public static final String SUBJECT = "subject";
public static final String BODY = "body";
public static final String PROTOCOL = "protocol";
public static final int MESSAGE_TYPE_ALL = 0;
public static final int MESSAGE_TYPE_INBOX = 1;
public static final int MESSAGE_TYPE_SENT = 2;
public static final int MESSAGE_TYPE_DRAFT = 3;
public static final int MESSAGE_TYPE_OUTBOX = 4;
public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing
// messages
public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send
// later
public static final int PROTOCOL_SMS = 0;// SMS_PROTO
public static final int PROTOCOL_MMS = 1;// MMS_PROTO
}定义SmsObserver继承ContentObserver监听数据库的变化
以上方式只是ContentObserver的一种使用方法,可以用来监听你需要监听的数据库是否有变化,如有变化作出相应的回应。
String names[] = cursor.getColumnNames();
name = _id i = 0 //短消息序号自动递增 如100
name = thread_id i = 1 //序号,同一发信人的id相同
name = address i = 2 //发件人地址,手机号.如:10086
name = person i = 3 //发件人,返回一个数字就是联系人列表里的序号,陌生人为null
name = date i = 4 //日期,long型
name = date_sent i = 5
name = protocol i = 6 //协议 0 SMS_RPOTO, 1 MMS_PROTO
name = read i = 7 //是否阅读 0未读, 1已读
name = status i = 8 //状态 -1接收,0 complete, 64 pending, 128 failed
name = type i = 9
//ALL = 0;
//INBOX = 1; 接收
//SENT = 2; 发送
//DRAFT = 3;
//OUTBOX = 4;
//FAILED = 5;
//QUEUED = 6;
name = reply_path_present i = 10
name = subject i = 11 //短信的主题,一般为null
name = body i = 12 //短信内容
name = service_center i = 13 //短信服务中心号码编号,如+8613800752011
name = locked i = 14
name = error_code i = 15
name = seen i = 16
name = timed i = 17
name = deleted i = 18
name = sync_state i = 19
name = marker i = 20
name = source i = 21
name = bind_id i = 22
name = mx_status i = 23
name = mx_id i = 24
name = out_time i = 25
name = account i = 26
name = block_type i = 27
name = sim_id i = 28
name = advanced_seen i = 29以上作了注释的是较为常用的,我们可以只查询出常用的列,查询函数原型:query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
第二个参数:projection,可以写上我们需要的列,第三个:selection是查询的条件。
private static final String[] PROJECTION = new String[] { SMS._ID,// 0
SMS.TYPE,// 1
SMS.ADDRESS,// 2
SMS.SUBJECT,// 3
SMS.BODY,// 4
SMS.DATE,// 5
SMS.THREAD_ID,// 6
SMS.READ,// 7
SMS.PROTOCOL // 8
};
Cursor cursor = mContext.getContentResolver().query(
SMS.CONTENT_URI, PROJECTION, "type = 1 and read = 0", null,
null);关于每个字符的类型可以看下packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java文件是如何创建表的:
db.execSQL("CREATE TABLE pdu_temp (" + Mms._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + Mms.THREAD_ID + " INTEGER," + Mms.DATE + " INTEGER," + Mms.DATE_SENT + " INTEGER DEFAULT 0," + Mms.MESSAGE_BOX + " INTEGER," + Mms.READ + " INTEGER DEFAULT 0," + Mms.MESSAGE_ID + " TEXT," + Mms.SUBJECT + " TEXT," + Mms.SUBJECT_CHARSET + " INTEGER," + Mms.CONTENT_TYPE + " TEXT," + Mms.CONTENT_LOCATION + " TEXT," + Mms.EXPIRY + " INTEGER," + Mms.MESSAGE_CLASS + " TEXT," + Mms.MESSAGE_TYPE + " INTEGER," + Mms.MMS_VERSION + " INTEGER," + Mms.MESSAGE_SIZE + " INTEGER," + Mms.PRIORITY + " INTEGER," + Mms.READ_REPORT + " INTEGER," + Mms.REPORT_ALLOWED + " INTEGER," + Mms.RESPONSE_STATUS + " INTEGER," + Mms.STATUS + " INTEGER," + Mms.TRANSACTION_ID + " TEXT," + Mms.RETRIEVE_STATUS + " INTEGER," + Mms.RETRIEVE_TEXT + " TEXT," + Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," + Mms.READ_STATUS + " INTEGER," + Mms.CONTENT_CLASS + " INTEGER," + Mms.RESPONSE_TEXT + " TEXT," + Mms.DELIVERY_TIME + " INTEGER," + Mms.DELIVERY_REPORT + " INTEGER," + Mms.LOCKED + " INTEGER DEFAULT 0," + Mms.SEEN + " INTEGER DEFAULT 0," + Mms.TEXT_ONLY + " INTEGER DEFAULT 0" + ");");只查询出我们关心的字段就可以了。
下面就来看下短信提醒功能如何实现的。
程序结构
先定义一个常量类SMS.java
package com.deng.datawidget.sms;
import android.net.Uri;
import android.provider.BaseColumns;
public class SMS implements BaseColumns {
public static final Uri CONTENT_URI = Uri.parse("content://sms");
public static final String FILTER = "!imichat";
public static final String TYPE = "type";
public static final String THREAD_ID = "thread_id";
public static final String ADDRESS = "address";
public static final String PERSON_ID = "person";
public static final String DATE = "date";
public static final String READ = "read";
public static final String SUBJECT = "subject";
public static final String BODY = "body";
public static final String PROTOCOL = "protocol";
public static final int MESSAGE_TYPE_ALL = 0;
public static final int MESSAGE_TYPE_INBOX = 1;
public static final int MESSAGE_TYPE_SENT = 2;
public static final int MESSAGE_TYPE_DRAFT = 3;
public static final int MESSAGE_TYPE_OUTBOX = 4;
public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing
// messages
public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send
// later
public static final int PROTOCOL_SMS = 0;// SMS_PROTO
public static final int PROTOCOL_MMS = 1;// MMS_PROTO
}定义SmsObserver继承ContentObserver监听数据库的变化
package com.deng.datawidget.sms; import java.sql.Date; import java.text.SimpleDateFormat; import java.util.Locale; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.os.Handler; import android.os.Message; import android.util.Log; /** * 短信监听器,根据数据库的变化去查询未读短信,可以做到短信提醒功能 * * */ public class SmsObserver extends ContentObserver { private static final String TAG = "SmsObserver"; private Context mContext; private Handler mHandler; private static final String[] PROJECTION = new String[] { SMS._ID,// 0 SMS.TYPE,// 1 SMS.ADDRESS,// 2 SMS.SUBJECT,// 3 SMS.BODY,// 4 SMS.DATE,// 5 SMS.THREAD_ID,// 6 SMS.READ,// 7 SMS.PROTOCOL // 8 }; public SmsObserver(Context context, Handler handler) { super(handler); mHandler = handler; mContext = context; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); // 每当有新短信到来时,使用我们获取短消息的方法 int newMsgNum = getNewSmsCount(); Message msg = mHandler.obtainMessage(); msg.what = 2; msg.obj = newMsgNum; mHandler.sendMessage(msg); Log.i(TAG, "onChange newMsgNum = " + newMsgNum); } private int getNewSmsCount() { int result = 0; try { Cursor cursor = mContext.getContentResolver().query( SMS.CONTENT_URI, PROJECTION, "type = 1 and read = 0", null, null); if (cursor != null) { MessageItem msg; result = cursor.getCount(); while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex(SMS._ID)); int type = cursor.getInt(cursor.getColumnIndex(SMS.TYPE)); int protocol = cursor.getInt(cursor .getColumnIndex(SMS.PROTOCOL)); String address = cursor.getString(cursor .getColumnIndex(SMS.ADDRESS)); String body = cursor.getString(cursor .getColumnIndex(SMS.BODY)); String subject = cursor.getString(cursor .getColumnIndex(SMS.SUBJECT)); SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss", Locale.getDefault()); Date d = new Date(cursor.getLong(cursor .getColumnIndex(SMS.DATE))); String date = dateFormat.format(d); msg = new MessageItem(); msg.setId(id); msg.setType(type); msg.setProtocol(protocol); msg.setDate(date); msg.setAddress(address); msg.setSubject(subject); msg.setBody(body); Log.i(TAG, msg.toString()); } String names[] = cursor.getColumnNames(); int i = 0; for (String name : names) { Log.i(TAG, "name = " + name + " i = " + i); i++; } cursor.close(); } } catch (Exception e) { Log.e(TAG, e.toString()); } return result; } }在activity中注册内容观察者
package com.deng.datawidget; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.Toast; import com.deng.datawidget.sms.SMS; import com.deng.datawidget.sms.SmsObserver; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private SmsObserver content = null; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub final int what = msg.what; switch (what) { case 2: int num = (int) msg.obj; Toast.makeText(MainActivity.this, "你有:" + num + " 条未读短信", Toast.LENGTH_LONG).show(); break; default: break; } super.handleMessage(msg); } }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); content = new SmsObserver(this, mHandler); // 注册短信变化监听 getContentResolver().registerContentObserver(SMS.CONTENT_URI, true, content); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); getContentResolver().unregisterContentObserver(content); } }相应代码下载:http://download.csdn.net/detail/deng0zhaotai/9250353
以上方式只是ContentObserver的一种使用方法,可以用来监听你需要监听的数据库是否有变化,如有变化作出相应的回应。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories