contentprovider实例

创建一个contentProvider

  1. 首先我们需要准备好一个数据库,创建一张表,作为操作的基本表
public class DbHelper extends SQLiteOpenHelper {
    public DbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    public DbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version, @Nullable DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    @RequiresApi(api = Build.VERSION_CODES.P)
    public DbHelper(@Nullable Context context, @Nullable String name, int version, @NonNull SQLiteDatabase.OpenParams openParams) {
        super(context, name, version, openParams);
    }

    private String sql="create table person (id integer primary key autoincrement, name text, age integer)";

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(sql);
        Log.d("sqlite","数据库创建成功");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

  1. 创建一个MyProvider类,让它继承自ContentProvider, 它有几个重要的成员,UriMatcher对象,它里面存放正确的uri,以及后面调用它的match方法匹配URI,数据库对象db,对数据表操作 。
    private final int PERSON=1;
    private final int PERSONOITEM=2;
    
    // 数据库
    private DbHelper helper;
    // matcher
    private UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
    private final String authority="com.example.demo4.myprovider";
    @Override
    public boolean onCreate() {
        helper=new DbHelper(getContext(),"person.db",null,1);
        matcher.addURI(authority,"person",PERSON);
        matcher.addURI(authority,"person/#",PERSONOITEM);
        return true;
    }

上面我声明了两个常量PERSON, PERSONITEM, 可以把它看做是两个URI的type, 所加入的两条uri分为为
com.example.demo4.myprovider/person
com.example.demo4.myprovider.person/#

这里的#代表任意数字,如果是* 则代表匹配任意长度的任意字符。
想必你猜到了,这里的PERSON, PERSONITEM两个常量就是代表两个uri的编号。
接下来看一下查询方法

    public Cursor query(@NonNull Uri uri,String[] projection,String selection, String[] selectionArgs, String sortOrder) {
        // 获取数据库对象
        SQLiteDatabase db=helper.getWritableDatabase();
        // 匹配uri
        int code = matcher.match(uri);
        // 不根据id查询
        if (code==PERSON){
            return db.query("person",projection,selection,selectionArgs,null,null,null);
        }
        // 根据id查询
        else if (code==PERSONOITEM){
            // 解析id
            long id = ContentUris.parseId(uri);
            return db.query("person",projection,"id=?",new String[]{id+""},null,null,null);
        }
        // 错误
        else {
            return null;
        }
    }

这里通过mather对象的match方法得到查询的uri的类型,如果是查询整张表,那么code应该是PERSON, 如果是根据id查询,那么code应该是PERSONITEM,根据id查询时,调用ContentUris的parseId()方法来解析出查询的id。

  1. 在AndroidManifest.xml文件中声明我们的provider。
        <provider
            android:authorities="com.example.demo4.myprovider"
            android:name=".MyProvider"
            android:enabled="true"
            android:exported="true"/>

authorities属性是其他应用查找该provider的依据,一般这里用provider的全类名小写即可。

Uri对象所对应的MIME类型

**getType()**方法用于获取URI对象所对应MIME类型,一个内容URI的MIME 类型由3个部分组成。

  • 以vnd开头
  • 如果内容URL以路径结尾,那么后接android.cursor.dir/; 如果内容URL以id结尾,那么后接android.cursor.item/;
  • 最后还要接上vnd..
    比如上文中,我们的URI是com.example.demo4.myprovider/person,它所对应的MIME类型是
    vnd.android.cursor.dir/vnd.com.example.demo4.myprovider.person

其他应用中使用

        Uri uri=Uri.parse("content://com.example.demo4.myprovider/person/1");
        Cursor cursor = getContentResolver().query(uri,null,null,null,null);

        if (cursor.moveToFirst()){
            do{
                String name = cursor.getString(cursor.getColumnIndex("name"));

                int age = cursor.getInt(cursor.getColumnIndex("age"));

                Log.d("query","name: "+name+"  age: "+age);
            }while (cursor.moveToNext());
        }

在API 30之后,android又对ContentProvider做出了限制,也就是查询的一方必须在AndroidManifest.xml 中声明要查询的provider,否则查询不到。

    <queries>
        <provider android:authorities="com.ts.schedule.myprovider"/>
    </queries>

总结

  • ContentProvider必须在AndroidManifest.xml文件中声明,并且指定export为true,authorities一般指定为全类名小写即可。
  • UriMatcher类负责存储和匹配uri。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值