1. 实现原理图
2. 示例代码
(暂时有个问题,短信观察者 收到一条短信时 onchange方法会执行两次, 解决方法为:每次监听到变化的时候就去取最新短信的id,跟上次取的比较,如果一样的就不做处理,如果不一样,就该干嘛干嘛)
MainActivity.java
public class MainActivity extends Activity {public static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 监听系统的短信数据库的变化ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://sms/");//true表示只要uri的前缀相同(content://sms/) 的数据有变化就会被发现resolver.registerContentObserver(uri, true, new SmsObserver(new Handler()));}private class SmsObserver extends ContentObserver {public SmsObserver(Handler handler) {super(handler);}//当观察到数据发生变化的时候 会执行onchange方法.@Overridepublic void onChange(boolean selfChange) {Log.i(TAG,"发现有新的短信产生了...");//1.利用内容提供者 中间人 获取用户的短信数据.ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://sms/"); //根据分析 代表的是所有的短信的路径Cursor cursor = resolver.query(uri, new String[]{"address","date","body","type"}, null, null, null);if(cursor.moveToFirst()){String address =cursor.getString(0);String date = cursor.getString(1);String body = cursor.getString(2);String type = cursor.getString(3);System.out.println(address+"--"+date+"---"+body+"---"+type);}cursor.close();super.onChange(selfChange);}}
}
3. 怎么实现 ContentObserver
由原理图可知, 在dao层操作时 发信息到消息邮箱即可。
例如在数据库 插入操作时 发一条消息到邮箱,notifyChange的uri可以自己随意定,
third app使用的时候要保持uri一致。
public void add(String name, float money){SQLiteDatabase db = helper.getWritableDatabase();db.execSQL("insert into account (name,money) values (?,?)", new Object[]{name, money}); db.close();context.getContentResolver().notifyChange(uri, null); }