ContentProvider和ContentResolver的混用

来源:互联网 发布:matlab数组倒序 编辑:程序博客网 时间:2024/05/18 15:06

/*
* ContentProvider是Android的四大组件之一,可见它在Android中的作用非同小可。
* 它主要的作用是:实现各个应用程序之间的(跨应用)数据共享,比如联系人应用中就使用了ContentProvider,
* 你在自己的应用中可以读取和修改联系人的数据,不过需要获得相应的权限。
* 其实它也只是一个中间人,真正的数据源是文件或者SQLite等。
* 一个应用实现ContentProvider来提供内容给别的应用来操作,
* 通过ContentResolver来操作别的应用数据,当然在自己的应用中也可以。
* ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,
* 继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),
* 当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,
* 相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,
* 当然这是与它所监听的Uri MIME Type有关的。
*/
通过上篇博文我们知道 我们可以通过ContentResolver借助Uri来访问系统的数据库像通话记录,联系人,短信的数据库,,相应的我们也可以自己构建一个数据库通过某种方式(Uri)把自己的数据端口暴露给其他用用程序使用 借助ContentProvider我们可以实现这样的功能.
//让我们通过一个例子来看
既然要暴露端口当然首先要构建数据库

public class DBHelper extends SQLiteOpenHelper {    private static final String DBNAME = "persons.db";    private static final int DBVERSION = 1;    // 创建数据库    public DBHelper(Context context) {        super(context, DBNAME, null, DBVERSION);    }    // 创建表    @Override    public void onCreate(SQLiteDatabase db) {        String sql = "CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20),nickname VARCHAR(20))";        db.execSQL(sql);    }    //数据库更新的时候调用    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}

//自定义ContentProvider实现增删改查操作

public class MyCustomProvider extends ContentProvider {    private SQLiteDatabase db;    // 用来在程序一启动的时候初始化内容提供者.只会执行一次.    // 这个方法是在主线程中运行的,不能进行特别耗时的操作,否则程序的启动就会延迟.    // true:表示内容提供者被成功的加载.false:反之.    @Override    public boolean onCreate() {        DBHelper helper = new DBHelper(getContext());        db = helper.getWritableDatabase();        return true;    }    // 必须构建URI:---->创建"口令"的过程    private final static String AUTHORITY = "www.xxx.cn";    private final static int PERSON_CODE = 1;    private final static int PERSON_ID = 2;    private final static int PERSON_TEXT = 3;    // UriMatcher.NO_MATCH:默认的验证码.如果URI没有验证通过,就返回该值,-1.    private static UriMatcher mMatcher = new UriMatcher(UriMatcher.NO_MATCH);    static {        // 用来创建URI对象.        // content://www.xxx.cn/person        mMatcher.addURI(AUTHORITY, "person", PERSON_CODE);        // content://www.xxx.cn/person/1        mMatcher.addURI(AUTHORITY, "person/#", PERSON_ID);        // content://www.xxx.cn/person/filter/sss        mMatcher.addURI(AUTHORITY, "person/filter/*", PERSON_TEXT);    }    // Uri:统一资源标示符:content://www.syc.com/mydb    // URL:统一资源定位符--->http://www.baidu.com/index.html    @Override    public Uri insert(Uri uri, ContentValues values) {        // content://www.xxx.cn/person        // insert into person (name,nickname) values("zhs","ss");        // 验证URI        int match = mMatcher.match(uri);        switch (match) {            case PERSON_CODE:                // id:最近添加的一行的行号.                long id = db.insert("person", null, values);                if (id > 0) {                    // 当数据源发生了改变,发出通知--->通过uri,把信息告诉--->MyObserver:                    getContext().getContentResolver().notifyChange(uri, null);                }                // content://www.xxx.cn/person/1                // 将id追加到原有的uri后面,形成一个新的uri                return ContentUris.withAppendedId(uri, id);            default:                throw new IllegalArgumentException("口令不对,滚一边去!");        }    }    @Override    public int delete(Uri uri, String selection, String[] selectionArgs) {        int match = mMatcher.match(uri);        // delete from person        // delete from person where _id=1        // delete from person where name=李逵        switch (match) {            case PERSON_CODE:                break;            case PERSON_ID:// content://www.xxx.cn/person/1                long parseId = ContentUris.parseId(uri);                int delete = db.delete("person", "_id=?",                        new String[]{String.valueOf(parseId)});                if (delete > 0) {                    getContext().getContentResolver().notifyChange(uri, null);                }                return delete;            case PERSON_TEXT:// content://www.xxx.cn/person/filter/李逵                String lastPathSegment = uri.getLastPathSegment();                int delete2 = db.delete("person", "name=?",                        new String[]{lastPathSegment});                if (delete2 > 0) {                    getContext().getContentResolver().notifyChange(uri, null);                }                return delete2;            default:                throw new IllegalArgumentException("路径错误");        }        return 0;    }    @Override    public int update(Uri uri, ContentValues values, String selection,                      String[] selectionArgs) {        // update person set name="ss" where _id=1;        // update person set name="ss" where name=ss;        int match = mMatcher.match(uri);        switch (match) {            case PERSON_CODE:                return db.update("person", values, selection, selectionArgs);            case PERSON_ID:// content://www.xxx.cn/person/1                long parseId = ContentUris.parseId(uri);                return db.update("person", values, "_id=?",                        new String[]{String.valueOf(parseId)});            case PERSON_TEXT:// content://www.xxx.cn/person/filter/黑鬼                // 截取最后的部分                String lastPathSegment = uri.getLastPathSegment();                return db.update("person", values, "nickname=?",                        new String[]{lastPathSegment});            default:                throw new IllegalArgumentException("路径错了");        }    }    @Override    public Cursor query(Uri uri, String[] projection, String selection,                        String[] selectionArgs, String sortOrder) {        int match = mMatcher.match(uri);        switch (match) {            case PERSON_CODE:                return db.query("person", projection, selection, selectionArgs,                        null, null, sortOrder);            case PERSON_ID:                long parseId = ContentUris.parseId(uri);                return db.query("person", projection, "_id=?",                        new String[]{String.valueOf(parseId)}, null, null,                        sortOrder);            case PERSON_TEXT:                String lastPathSegment = uri.getLastPathSegment();                return db.query("person", projection, "name=?",                        new String[]{lastPathSegment}, null, null, sortOrder);            default:                break;        }        return null;    }    // 根据传递进来的uri参数类型,判定要请求的数据类型.    // vnd.android.cursor.item:代表单条数据;    // vnd.android.cursor.dir:代表多条数据.    @Override    public String getType(Uri uri) {        int match = mMatcher.match(uri);        switch (match) {            case PERSON_CODE:                return "vnd.android.cursor.dir";            case PERSON_ID:                return "vnd.android.cursor.item";        }        return null;    }}

注册

 <provider            android:name=".MyCustomProvider"            android:authorities="www.xxx.cn"            android:exported="true">        </provider>

//在另外一个app借助ContentResolver对该数据库进行增删改查操作

/**** * ContentProvider内容提供者 ContentResolver内容解析者 ContentObserver内容观察者 * ContentResolver就是来取ContentProvider提供的数据的。 * ContentProvider使你数据库中数据能够被其他程序访问,但能访问不能任意方式都能访问, * 只能通过规定的方式,这中方式就是通过ContentResolver来实现 *内容观察者,观察内容提供者数据的变化。如果内容提供者数据变化了,那么发送信息给观察者。 *原理:在resolver身上注册一个观察者observer,当数据改变时,调用观察者的onChange方法 *在provider的数据会发生改变的方法中调用resolver的notifyChange方法。 */public class MainActivity extends AppCompatActivity {    private ContentResolver resolver;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        resolver = getContentResolver();    }    public void insert(View v) {        String str = "content://www.xxx.cn/person";        ContentValues values = new ContentValues();        values.put("name", "宋江");        values.put("nickname", "黑三郎");        Uri result = resolver.insert(Uri.parse(str), values);        // 将一个uri最后的id给截取返回.        long parseId = ContentUris.parseId(result);        if (parseId > 0) {            Toast.makeText(this, "添加成功", Toast.LENGTH_LONG).show();        }    }    public void update(View v) {        //根据id更新         String str = "content://www.xxx.cn/person/1";         ContentValues values=new ContentValues();         values.put("name", "李逵");         values.put("nickname", "黑鬼");         int result = resolver.update(Uri.parse(str), values,"_id=?", new String[]{String.valueOf("1")});        //匹配字符更新        //String str = "content://www.xxx.cn/person/filter/黑三郎";        //ContentValues values = new ContentValues();        //values.put("nickname", "黑旋风");        //values.put("name", "大傻逼");        //int result = resolver.update(Uri.parse(str), values, null, null);        if (result > 0) {            Toast.makeText(this, "修改成功", Toast.LENGTH_LONG).show();        }    }    // 删除    public void delete(View v) {        //根据id删除         String str = "content://www.xxx.cn/person/1";         int result = resolver.delete(Uri.parse(str),"_id=?", new String[]{String.valueOf("1")});        //匹配字符删除        //String str = "content://www.xxx.cn/person/filter/宋江";        //int result = resolver.delete(Uri.parse(str), null, null);        //全部删除        //String str = "content://www.xxx.cn/person";        //int result = resolver.delete(Uri.parse(str), null, null);        if (result > 0) {            Toast.makeText(this, "删除成功", Toast.LENGTH_LONG).show();        }    }    public void query(View v) {        //根据id查询 在6.0的手机上居然禁止关联启动了  shit        String str = "content://www.xxx.cn/person/3";        Cursor cursor = resolver.query(Uri.parse(str), new String[] {"_id","name","nickname"},"_id=?", new String[]{"3"}, null);        //全部查询        //String str = "content://www.xxx.cn/person";        //Cursor cursor = resolver.query(Uri.parse(str), new String[] {"_id","name","nickname"},null, null, null);        while (cursor.moveToNext()) {            Long _id = cursor.getLong(cursor.getColumnIndex("_id"));            String name = cursor.getString(cursor.getColumnIndex("name"));            String nickname = cursor.getString(cursor.getColumnIndex("nickname"));            Log.i("TAG", "_id="+_id+"name=" + name+"--nickname="+nickname);        }    }}

本来应该加上 ContentObserver的 哎 下次再说吧

0 0
原创粉丝点击