ContentProvider和ContentResolver的混用

/*
* 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的 哎 下次再说吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值