首页 > 代码库 > 内容观察者

内容观察者

需要提供读取短信权限





package com.example.contentobserver;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         Uri uri=Uri.parse("content://sms");
         ContentResolver resolver= getContentResolver();
         resolver.registerContentObserver(uri, truenew Mycontentobeserver(new Handler()));
    }
    
//    当内容观察者观察到数据库的内容发生变化了调用该方法。
//    实际上是观察到消息邮箱(一个公共内存区域)里有一条数据库内容变化的通知
private class Mycontentobeserver extends ContentObserver{
    public Mycontentobeserver(Handler handler) {
        super(handler);
        // TODO Auto-generated constructor stub
    }
    public void onChange(boolean selfChange){
        super.onChange(selfChange);
        Toast.makeText(MainActivity.this"数据库内容变化了", 1).show();
        Uri uri=Uri.parse("content://sms");
        ContentResolver resolver= getContentResolver();
        Cursor cursor=resolver.query(uri, new String[]{"address","date","type","body"}, nullnullnull);
//        得到最后一条短信
        cursor.moveToFirst();
        String address=cursor.getString(0);
        String body=cursor.getString(3);
        System.out.println("address:"+address+"::"+"body:"+body);
        cursor.close();
    }
}
}

-------------------------------------------------
内容观察者观察自定义的数据库时:

数据库变化时要主动发送通知到公共内存区域




package com.example.simpledatabase.dao;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import com.example.simpledatabase.PersonSQLiteOpenHelper;
import com.example.simpledatabase.domain.Person;
public class PersonDao {
    // 在构造方法里完成helper初始化
    public PersonSQLiteOpenHelper helper;
    private Context context;
    public static Uri message = Uri.parse("content://person");
    public PersonDao(Context context) {
        helper = new PersonSQLiteOpenHelper(context);
    }
    /**
     * 添加记录
     * 
     * @param name
     * @param number
     */
    public void add(String name, String number) {
        SQLiteDatabase db = helper.getWritableDatabase();
        db.execSQL("insert into person (name,number) values (?,?)",
                new Object[] { name, number });
        db.close();
        context.getContentResolver().notifyChange(messagenull);
    }
    /**
     * 查询
     * 
     * @param name
     * @return
     */
    public boolean find(String name) {
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select * from person where name=?",
                new String[] { name });
        boolean result = cursor.moveToNext();
        cursor.close();
        db.close();
        return result;
    }
    /**
     * 修改
     * 
     * @param name
     * @param newnumber
     */
    public void update(String name, String newnumber) {
        SQLiteDatabase db = helper.getWritableDatabase();
        db.execSQL("update person set number=? where name=?"new Object[] {
                newnumber, name });
        db.close();
        context.getContentResolver().notifyChange(messagenull);
    }
    /**
     * 删除
     * 
     * @param name
     */
    public void delete(String name) {
        SQLiteDatabase db = helper.getWritableDatabase();
        db.execSQL("delete from person where name=?"new Object[] { name });
        db.close();
        context.getContentResolver().notifyChange(messagenull);
    }
    // 查询数据库全部信息
    public List<Person> findAll() {
        SQLiteDatabase db = helper.getReadableDatabase();
        List<Person> persons = new ArrayList<Person>();
        Cursor cursor = db.rawQuery("select * from person"null);
        while (cursor.moveToNext()) {
            int id = cursor.getInt(cursor.getColumnIndex("id"));
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String number = cursor.getString(cursor.getColumnIndex("number"));
            Person p = new Person(id, name, number);
            persons.add(p);
        }
        db.close();
        return persons;
    }
}


package com.example.simpledatabase;
import com.example.simpledatabase.dao.PersonDao;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class PersonDBProvider extends ContentProvider {
    // 用于规定addURI的返回值
    private static final int INSERT = 1;
    private static final int DELETE = 2;
    private static final int UPDATE = 3;
    private static final int QUERY = 4;
    private static final int QUERYONE = 5;
    private PersonSQLiteOpenHelper helper;
    private String tag = "PersonDBProvider";
    
    // 定义一个URI匹配器用于匹配uri,如果路径不满足条件则
    private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    // 指定匹配器的规则
    static {
        // 添加一组匹配规则
        matcher.addURI("com.example.simpledatabase.personprovider""insert",
                INSERT);
        matcher.addURI("com.example.simpledatabase.personprovider""delete",
                DELETE);
        matcher.addURI("com.example.simpledatabase.personprovider""update",
                UPDATE);
        matcher.addURI("com.example.simpledatabase.personprovider""query",
                QUERY);
        matcher.addURI("com.example.simpledatabase.personprovider""query/#",
                QUERYONE);
    }
    // 在安卓中内容提供者路径名格式为
    // content://com.example.simpledatabase.personprovider/insert 添加操作
    // content://com.example.simpledatabase.personprovider/update
    // content://com.example.simpledatabase.personprovider/query
    // content://com.example.simpledatabase.personprovider/delete
    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        helper = new PersonSQLiteOpenHelper(getContext());
        return false;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        if (matcher.match(uri) == QUERY) {
            // Log.i(tag, "看效果");
            SQLiteDatabase db = helper.getReadableDatabase();
            Cursor cursor = db.query("person", projection, selection,
                    selectionArgs, nullnull, sortOrder);
            return cursor;// 不能关闭数据库否则无法获取结果集,返回的是多条结果集
        }
        else if (matcher.match(uri) == QUERYONE) {
            long id = ContentUris.parseId(uri);
            SQLiteDatabase db = helper.getReadableDatabase();
            Cursor cursor = db.query("person", projection, "id=?",
                    new String[] { id + "" }, nullnull, sortOrder);
            return cursor;// 返回的是一条记录
        }
        else {
            throw new IllegalArgumentException("查询失败,路径名不合法");
        }
    }
    @Override
    public String getType(Uri uri) {
        if (matcher.match(uri) == QUERY) {
            return "vnd.android.cursor.dir/person";// 返回的是多条记录
        }
        else if (matcher.match(uri) == QUERYONE) {
            return "vnd.android.cursor.item/person";// 返回的是具体记录
        }
        return null;
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (matcher.match(uri) == INSERT) {
            // Log.i(tag, "看效果");
            SQLiteDatabase db = helper.getWritableDatabase();
            db.insert("person"null, values);
            getContext().getContentResolver().notifyChange(PersonDao.messagenull);
        } else {
            throw new IllegalArgumentException("查询失败,路径名不合法");
        }
        return null;
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (matcher.match(uri) == DELETE) {
            SQLiteDatabase db = helper.getWritableDatabase();
            db.delete("person", selection, selectionArgs);
            getContext().getContentResolver().notifyChange(PersonDao.messagenull);
        } else {
            throw new IllegalArgumentException("查询失败,路径名不合法");
        }
        return 0;
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        if (matcher.match(uri) == UPDATE) {
            SQLiteDatabase db = helper.getWritableDatabase();
            db.update("person", values, selection, selectionArgs);
            getContext().getContentResolver().notifyChange(PersonDao.messagenull);
        } else {
            throw new IllegalArgumentException("查询失败,路径名不合法");
        }
        return 0;
    }
}


第三个应用观察数据库变化情况:


package com.example.persondbobserver;
import android.app.Activity;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Uri uri=Uri.parse("content://person");
        getContentResolver().registerContentObserver(uri, truenew Myobserver(new Handler()));
    }
    private class Myobserver extends ContentObserver{
        public Myobserver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }
        @Override
        public void onChange(boolean selfChange) {
            // TODO Auto-generated method stub
            super.onChange(selfChange);
            System.out.println("第三方应用,数据库变化了");
        }
        
    }
}


当测试程序执行添加 删除 修改时,第三方观察者应用可观察到数据库变化



来自为知笔记(Wiz)