【Android学习系列】android Content Provider 应用步骤

这里举例是A应用要访问B应用
1、在B应用里创建数据库
只需要创建一个类继承DBOpenHelper
public class DBOpenHelper extends SQLiteOpenHelper {
    private static int DATABASE_VERSION = 1;//版本号
    public DBOpenHelper(Context context) {
        super(context, "表名", null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE <表名> ( _id INTEGER primary key autoincrement, <字段> varchar(20))");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 更新表
    }

}


*这个数据库是创建好了,可是要想自己操作该数据库就需要这样了
    DBOpenHelper helper = new DBOpenHelper(context);
    SQLiteDatabase db = helper.getWritableDatabase();
    db.execSQL("insert into......");//仅代表执行sql语句
    db.close(); 



2、在B应用里创建ContentProvider

只需要创建一个类继承ContentProvider
public class PicturesProvider extends ContentProvider {
    private static final int PICTURES = 1;// 代表访问/picture
    private static final int PICTURE = 2;// 代表访问/picture/#
    private static final UriMatcher MATCHER = new UriMatcher(
            UriMatcher.NO_MATCH);// 初始化UriMatcher的不匹配码,如果不匹配就会返回UriMatcher.NO_MATCH也就是-1
    private DBOpenHelper helper;//之前创建的操作数据库的类
    //在静态代码块里添加匹配的uri
    static {
        MATCHER.addURI("com.xy.picturesprovider", "picture_table", PICTURES);// 代表访问/picture
        MATCHER.addURI("com.xy.picturesprovider", "picture_table/#", PICTURE);// 代表访问/picture/#
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int num = 0;
        SQLiteDatabase db = helper.getWritableDatabase();
        switch (MATCHER.match(uri)) {
        case PICTURES:// 代表访问/picture
            num = db.delete("picture_table", selection, selectionArgs);
            break;
        case PICTURE:// 代表访问/picture/#
            long id = ContentUris.parseId(uri);//截取id
            String where = "_id=" + id;
            if (selection != null && !"".equals(selection.trim())) {
                where += " and" + selection;
            }
            num = db.delete("", where, selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unkonwn Uri:" + uri);//没有匹配的就抛出异常
        }
        return num;//返回删掉的数量
    }

    @Override
    public String getType(Uri uri) {
        String type = null;
        //返回数据类型
        switch (MATCHER.match(uri)) {
        case PICTURES:// 代表访问/picture
            type = "vnd.android.cursor.dir/xxx";//xxx是自己随便写的  主要是前面  这个代表要操作的数据数据集合类型
            break;
        case PICTURE:// 代表访问/picture/#
            type = "vnd.android.cursor.item/xxx";//代表要操作的数据属于非集合类型
            break;
        default:
            throw new IllegalArgumentException("Unkonwn Uri:" + uri);//没有匹配的就抛出异常
        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        Log.e("xxxxxxxxxxxxxxxxxxxxx", "insert");
        SQLiteDatabase db = helper.getWritableDatabase();
        switch (MATCHER.match(uri)) {
        case PICTURES:
            long rawid = db.insert("picture_table", "_path", values);// 返回该记录的行号
            db.close();
             Uri noteUri = ContentUris.withAppendedId(uri, rowId);
                    getContext().getContentResolver().notifyChange(noteUri, null);
                    return noteUri;
        default:
            throw new IllegalArgumentException("Unkonwn Uri:" + uri);
        }
    }

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        helper = new DBOpenHelper(getContext());//初始化
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

}



3、在B应用的manifest文件的application节点里添加provider节点
    <provider  android:name=".刚写的Provider类名" android:authorities="com.xy.picturesprovider"></provider>
    authorities里的属性自己写  主要是为了区别用的   待会就是根据这个路径找到该应用的

4、现在可以着手完成A应用了
    如果要测试A访问B的话,就看第5点
    下面代码是增加和删除的测试代码
        public void testInsert(){
             ContentResolver resolver = getContext().getContentResolver();
             Uri uri = Uri.parse("content://com.xy.picturesprovider/picture_table");//#1
             ContentValues values = new ContentValues();
             values.put("_path", "www.sina.com");
             resolver.insert(uri, values);
        }
        public void testDelete(){
            ContentResolver resolver = getContext().getContentResolver();
             Uri uri = Uri.parse("content://com.xy.picturesprovider/picture_table/5");//#2
             ContentValues values = new ContentValues();
             resolver.delete(uri, null, null);
        }


    这里解释下 #1:content://是固定写法,紧接着的就是之前在manifest里设置的一串东西,虽然可以任意写,
可是这里却需要和那里写的一致否则访问不到B应用,然后接着后面的就是要访问的表名了
    #2的话只多了一个参数,代表访问的时表中的第5条记录
至此 , 您已经操作了其他应用
5、如果需要测试的话需要在manifest文件里的两处添加代码
    一是在application节点里activity节点外添加<uses-library android:name="android.test.runner" />
    二是在application外面添加
    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.xy.b" />后面这个属性必须写成要测试应用的package属性

    
监听数据库的数据发生变化:
    因为之前在insert的时候有了getContext().getContentResolver().notifyChange(noteUri, null);这段代码所以通知已经发出去 了,我们现在要做的就是设置一个观察者去观察数据的变化,如下
    //监听对应数据库数据的变化
    registerObserver(Uri.parse("content://com.android.userinfo.appprovider/userPicture"));//方法实现在下面

    /**
     * 为了监听对应数据库数据发生变化后发出的通知
     * @date   2012-3-9下午02:12:10
     */
    private void registerObserver(Uri uri) {
        ContentResolver resolver = getContext().getContentResolver();
        resolver.registerContentObserver(uri, true,
        new ContentObserver(new Handler()){
            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);
                Log.i("zhidaole", "            zhidao la  a");
                //在这里写数据变化后的代码
            }
        });

    }



    http://blog.csdn.net/chunlongyuan/article/details/7751031

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值