[Android四大组件] ContentProvider 内容提供器

来源:互联网 发布:淘宝店怎么看分 编辑:程序博客网 时间:2024/03/29 05:06

ContentProvider 内容提供器

  • 什么是内容提供器

    官方解释:

    A content provider manages access to a central repository of data. A provider is part of an Android application, which often provides its own UI for working with the data. However, content providers are primarily intended to be used by other applications, which access the provider using a provider client object. Together, providers and provider clients offer a consistent, standard interface to data that also handles inter-process communication and secure data access.

    通俗易懂:

    主要是用于不同的应用程序之间实现数据共享的功能.

    内容提供器以一个或多个表(跟数据库的表类似)的形式呈献给外部应用.

    分两类:

    • 使用现有的内容提供器来读取和操作应用程序的数据

    • 创建自己的内容提供器提供外部访问接口


  • ContentProvider的基本用法

    • 访问其他程序的数据

      • ContentResolver类

        如果想要访问内容提供器中共享的数据, 就需要借助ContentResolver类, 可以通过Context.getContentResolver()方法来获取该类的实例.

        这个ContentResolver提供了一些对数据进行CRUD的操作, 也就是常说的”增删查改”

        但是, 与SQLiteDatabase不同的是, ContentResolver的增删查改方法是不接受表名参数的,而是 Uri,

        Uri: 由 权限 和 路径 组成的. (用于在提供程序中标识数据的URI)。

        Uri的标准写法如下:

        content://com.example.app.provider/table1

        table1为数据库的名字;

        再使用Uri.parse(uri) 就可以将字符串转发为Uri类型啦.

        说了那么多,我们还没开始访问数据, 代码如下:

        Cursor cursor=getContentResolver().query(    uri,    projection,    selection,    selectionArgs,    sortOrder);

        上面传入参数很多, 下面表格将这些参数和SQLiteDatabase中的query()进行了对比:

        query() 对应SQL部分 描述 uri from table_name 指定查询应用程序的某一个表 projection select column1,column2 指定查询的列名 selection where column=value 为where中的占位符提供具体的值 selectionArgs - 为where的占位符提供具体的值 sortOrder order by column1, column2 指定查询结果的排序方式

        很明显上面返回的是Cursor类, 读取数据的思路就是通过移动游标的位置来遍历Cursor的所有行, 然后取出每一行相应列的数据, 代码如下:

        if(cursor!=null){    while(cursor.moveToNext()){        String column1 = cursor.getString(cursor.getColumnIndex("column1"));        int column2 = cursor.getInt(cursor.getColumnIndex("column2"));    }    cursor.close();}

        以下是各种操作的简单介绍:

        ContentValues values=new ContentValues();//插入数据getContentResolver().insert(uri, values);//更新数据getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[]{"text","1"});//删除数据getContentResolver().delete(uri, "column2 = ?", new String[]{"1"});

  • 创建自己的ContentProvider

    • 创建前的准备

      1. 决定你是否需要ContentProvider

        • 你想为其他应用提供复杂的数据或文件

        • 你想允许用户将复杂的数据从你的应用复制到其他应用中

        • 你想使用搜索框架提供自定义搜索建议

      2. 创建步骤

        • 设计原始存储, 文件数据(照片\音频…)或者结构化数据(数据库或数组…)

        • 继承ContentProvider类, 并实现具体方法

        • 定义提供程序的授权字符串\ URI \ 列名称

        • 添加其他可选的部分

    • 实例操作

      • 创建数据库, 这里不详细介绍了.

      • 继承ContentProvider类

        public class DemoContentProvider extends ContentProvider {    @Override    public boolean onCreate() {        return false;    }    @Nullable    @Override    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {        return null;    }    @Nullable    @Override    public String getType(@NonNull Uri uri) {        return null;    }    @Nullable    @Override    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {        return null;    }    @Override    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {        return 0;    }    @Override    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {        return 0;    }}
      • 设计内容URI

        • 设计授权

          如果Android包名为com.example., 则为提供程序提供com.example..provider 授权

        • 设计路径结构

          合并上一段的权限来生成内容URI : com.example..provider/table1 或者table2

        • 处理内容URI ID

          末尾有_ID值就是来对表的单个行的访问.

        • URI模式

          由于有实用类UriMatcher, 所以可以使用以下通配符来匹配内容:

          • ” * ” : 匹配任意长度的任意字符

          • ” # ” : 匹配任意长度的数字

          标准的URI:
          content://com.example.app.provider/….

      • 综合代码如下:

        public class DemoContentProvider extends ContentProvider {    private static final int TABLE1_DIR = 0;    private static final int TABLE1_ITEM = 1;    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);    static {        sUriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);        sUriMatcher.addURI("com.example.app.provider", "table1/#", TABLE1_ITEM);    }    @Override    public boolean onCreate() {        return false;    }    @Nullable    @Override    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {        SQLiteDatabase db = dbHelper.getReadableDatabase();        Cursor cursor = null;        switch (sUriMatcher.match(uri)) {            case TABLE1_DIR:                //查询table1表中的所有数据                break;            case TABLE1_ITEM:                //查询table1表中的单条数据                break;            default:                break;        }        return cursor;    }    @Nullable    @Override    public String getType(@NonNull Uri uri) {        switch (sUriMatcher.match(uri)) {            case TABLE1_DIR:                return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";            case TABLE1_ITEM:                return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";            default:                break;        }        return null;    }    @Nullable    @Override    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {        return null;    }    @Override    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {        return 0;    }    @Override    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {        return 0;    }}

      不知道大家有没有看到getType这个方法,返回了一些莫名其妙的字符串

      其实这些都是MIME类型的数据

      格式如下:

      • 必须vnd开头
      • 路径结尾的话就后接android.cursor.dir/ , 若是id结尾就接android.cursor.item/
      • 最后接上 vnd. < authority > . < path >
  • 总结

    这个内容提供器有很多demo , 需要结合数据库来讲, 我想等讲完数据库再上传这个DEMO吧.谢谢大家看我的学习笔记!

0 0
原创粉丝点击