Android——内容提供者
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。
内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内容提供器给我们程序的数据提供外部访问接口。
访问其他程序中的数据
Android 系统中自带的电话簿、短信、媒体库等程序都提供了外部访问接口 。
-
ContentResolver 的基本用法
要访问内容提供器中共享的数据,就一定要借助ContentResolve 类,可以通过 Context 中的 getContentResolver()方法获取到该类的实例。
ContentResolver 中提供了一系列的方法用于对数据进行 CRUD 操作。ContentResolver 中的增删改查方法是使用了一个Uri参数代替,这个参数被称为内容Uri,Uri是给内容提供器中的数据建立了唯一标识符。
- insert()方法用于添加数据
- update()方法用于更新数据
- delete()方法用于删除数据
- query()方法用于查询数据。
Uri主要由两部分组成,权限(authority)和路径(path)。权限是对不同的应用程序做区分,一般为了避免冲突都会采用程序包名的方式来进行命名,路径这是对于同一应用程序的不同表做区分的,通常会添加到权限的后面。权限与路径组合就组成了Uri 例如:(com.example.app.provider/table1)目前还很难认出这个字符串就是Uri,还需要在字符串头部加上协议声明,内容Uri的标准的格式如下:content://com.example.app.provider/table1 。
- 在得到了内容 URI 字符串之后,我们还需要将它解析成 Uri 对象才可以作为参数传入。
Uri uri = Uri.parse("content://com.example.app.provider/table1"); //将Uri字符串解析为Uri对象
- 使用Uri对象来查询
table1
表格中的数据
Cursor cursor = getContentResolver().query( uri, projection, selection, selectionArgs, sortOrder);
query方法参数 对应SQL部分 描述 Uri from table_name 指定查询某个应用程序下的某一张表 projection select column1, column2 指定查询的列名 selection where column = value 指定 where 的约束条件 selectionArgs 为 where 中的占位符提供具体的值 sortOrder order by column1, column2 指定查询结果的排序方式 查询完成后返回的仍然是一个 Cursor 对象,这时我们就可以将数据从 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(); values.put("column1", "text"); values.put("column2", 1); getContentResolver().insert(uri, values);
将添加的数据组装到 ContentValues 中,然后调用 ContentResolver的 insert()方法,将 Uri 和 ContentValues 作为参数传入即可。
- 更新数据
ContentValues values = new ContentValues(); values.put("column1", ""); getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[] {"text", "1"});
注意上述代码使用了 selection 和 selectionArgs 参数来对想要更新的数据进行约束,以防止所有的行都会受影响
- 删除数据
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });
-
创建自己的内容提供器
通过新建一个类去继承 ContentProvider 的方式来创建一个自己的内容提供器。ContentProvider 类中有六个抽象方法
public class MyProvider extends ContentProvider { @Override public boolean onCreate() { // 初始化内容提供器的时候调用 return false; } @Override // 内容提供器中查询数据 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override // 向内容提供器中插入数据 public Uri insert(Uri uri, ContentValues values) { return null; } @Override // 更新内容提供器中的数据 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } @Override // 从内容提供器中删除数据 public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override // 根据传入的内容Uri来返回相应的MIME类型 public String getType(Uri uri) { return null; } }