1. 实现原理图
2. 示例代码
(暂时有个问题,短信观察者 收到一条短信时 onchange方法会执行两次, 解决方法为:每次监听到变化的时候就去取最新短信的id,跟上次取的比较,如果一样的就不做处理,如果不一样,就该干嘛干嘛)
MainActivity.java
public class MainActivity extends Activity { public static final String TAG = "MainActivity"; @Override protected 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方法. @Override public 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); }