上次我们说了内容观察者的使用,细心的朋友会发现,我们需要主动进行查询才可以知道数据库是否有了变化。如果我们想在数据库变化的第一时间就知道怎么办?这里我们以读取短信数据为例,说明内容观察者的使用方法。
首先我们需要加入一个权限
<uses-permission android:name="android.permission.READ_SMS"/>
有了这个权限我们才可以获取短信的内容
接着我们要在需要读取短息的界面加入观察的代码,示例代码如下
public class GcdxnrActivity extends WaterPermissionActivity<GcdxnrModel> implements GcdxnrCallback {
private Handler mHandler = new Handler();//声明一个处理器对象
private SmsGerObserver mObserver;//声明一个短信获取的观察器对象
private static Uri mSmsUri;//声明一个系统短信提供器的Uri对象
private static String[] mSmsColumn;//声明一个短信记录的字段数组
private TextView tv_chect_flow;
@Override
protected GcdxnrModel getModelImp() {
return new GcdxnrModel(this,this);
}
@Override
protected int getContentLayoutId() {
return R.layout.activity_gcdxnr;
}
@Override
protected void initWidget() {
tv_chect_flow = findViewById(R.id.tv_chect_flow);
requestPermission(READ_SMS);
}
@Override
protected void doSMS() {
initSmsObserver();
}
/**
* 初始化短信观察器
*/
private void initSmsObserver(){
mSmsUri = Uri.parse("content://sms");
mSmsColumn = new String[]{"address","body","date"};
//创建一个短信观察器对象
mObserver = new SmsGerObserver(this,mHandler);
//给指定Uri注册内容观察器,一旦Uri内部发生数据变化,就出发观察器的onChange方法
getContentResolver().registerContentObserver(mSmsUri,true,mObserver);
}
/**
* 在页面销毁时触发
*/
@Override
protected void onDestroy() {
//注销内容观察器
getContentResolver().unregisterContentObserver(mObserver);
super.onDestroy();
}
/**
* 定义一个短信获取的观察器
*/
private static class SmsGerObserver extends ContentObserver {
private Activity mActivity;//声明一个上下文对象
private GcdxnrActivity mainActivity;
public SmsGerObserver(Activity activity, Handler handler){
super(handler);
mActivity = activity;
mainActivity = (GcdxnrActivity) activity;
}
public void onChange(boolean selfChange){
String sender = "";
String content = "";
//构建一个查询短信的条件语句,这里使用移动号码测试,故而查找10086发来的短信
String selection = String.format("address='1008611' and date>%d",System.currentTimeMillis() - 1000*60);
//通过内容解析器获取符合条件的结果集游标
Cursor cursor = mActivity.getContentResolver().query(mSmsUri,mSmsColumn,selection,null,"date desc");
//循环取出游标所指向的所有短信记录
while (cursor.moveToNext()){
sender = cursor.getString(0);
content = cursor.getString(1);
break;
}
cursor.close();//关闭数据库游标
mainActivity.setText("发送者:"+sender+"\n"+"内容:"+content);
super.onChange(selfChange);
}
}
public void setText(String text){
if (tv_chect_flow!=null) {
tv_chect_flow.setText(text);
}
}
}
首先我们可以看到
requestPermission(READ_SMS);
这里是请求了一个Manifest.permission.READ_SMS动态权限,doSMS()是用户同意权限后执行的方法。我们在这里执行了initSmsObserver()方法,即初始化观察器的方法。大家可以使用自己的动态权限请求的方法。
如果数据库发生了改变,则会调用onChange方法。sender是短信发送者,content是短信的内容。
String selection = String.format("address='1008611' and date>%d",System.currentTimeMillis() - 1000*60);
这个代码中指定了要查询的短信是哪个号码发送的,以及要查询多久以前的短信。
大家有什么疑问都可以在评论区给我留言。