Android-数据存储(Content Provider 跨应用调用数据范例)
1.回顾
上篇 数据存储篇 已经学习完了,Android的数据存储 包括 SharedPrefence , SQLite , 文件存储 ,Content Provider ; 而还有一种 是存储在网络上 就不说了;
之前 写了一个 调用 通信录 ,获得 用户联系人的 例子 ,使用 Content Provider 实现;
2. 重点
(1)复习 Content Provider
(2)Content Provider 实现 权限 解释
(3)调用演示实例
3. 复习
(1)ContentProvider 实现 通过 Uri 实现 对 数据的增删改查;
(2)可以跨应用 调用数据;
(3)ContentProvider 通过 ContentResolver 实现 增删改查,两个类对应的 方法包括参数一模一样;
(4)ContentProvider 在 生成数据App端封装,后在 Androidmianfest.xml 中注册(包括权限设置);
(5)ContentResolver 在 请求数据的App中封装,后通过 生成数据App端提供的Uri地址 实现 增删改查数据操作;
4. ContentProvider 权限解释
声明:AppProvider:代表 生成数据App端 (数据提供端);AppResovler :代表 请求数据 App端
4.1 权限解释
<provider android:name="com.example.sqlite.TContentProvider" android:authorities="com.example.sqlite" android:exported="true" />
(1)在 Androidmianfest.xml 文件下的 的 Application 标签中添加 provider 标签
<Application ....> .... <provider ...... /> </Application>(2)一般情况下,包含必须的三个属性
name : 为 自定义 ContentProvider 类 的包名(在 AppProvider 应用中 ,继承 ContentProvider)
authorities :为 这个 ContentProvider 的 uri 地址 ;
exported : 为 是否可以其他应用所访问,默认不写为 false , true 是可以访问;
有这三个 就已经可以实现 数据共享了 ;
4.2 权限提升
前三个属性 和上面一样,下面是 又多的三个属性
<provider android:name="com.example.sqlite.TContentProvider" android:authorities="com.example.sqlite" android:exported="true" android:permission="com.example.sqlitedemo" android:readPermission="com.example.sqlite.read" android:writePermission="com.example.sqlite.write" />
4.2.1 permission
给应用 注册 和 提供访问的读写权限 ;
(1) AppProvider 应用 声明权限 在与 Application 的同级标签下声明:
这里的 name值 和 上面 permission 值一样!!
<permission android:name="com.example.sqlitedemo" android:label="content provider read" android:protectionLevel="normal" ></permission>
( 2) AppResovler 应用 实现数据请求 ,必须在 自己的 Androidmianfest.xml文件中,声明:
这里的 name 也和 permission 值一样 !!!和 Application 标签同级 ;
<uses-permission android:name="com.example.sqlitedemo"/>
4.2.2 readPermission 和 writePermission
(1)Permission可以同时实现 读写权限 ;
(2)readPermission 只实现 读 权限 ,没有写入权限;
(3)writePermission 只实现 写入权限 ,没有实现 读取权限;
(4)当同时出现的时候,readPermission 和 writePermission的权限 优先级 比 Permission优先级高;
(5)readPermission和writePermission的 权限注册方法 和 Permission一样;
(6)例子 (readPermission 和 permission 的权限优先级):
AppProvider 应用配置实现:
<provider android:name="com.example.sqlite.TContentProvider" android:authorities="com.example.sqlite" android:exported="true" android:permission="com.example.sqlitedemo" android:readPermission="com.example.sqlite.read" />
permission 和 readPermission 注册权限 如下:
<permission android:name="com.example.sqlite.read" android:label="content provider read" android:protectionLevel="normal" ></permission> <permission android:name="com.example.sqlitedemo" android:label="content provider read write" android:protectionLevel="normal" ></permission>
AppResovler 请求端 添加下面权限 ,会报错 ,因为permission 优先级低:
<uses-permission android:name="com.example.sqlitedemo"/>
但是 使用 readPermission的权限 就行了;
<uses-permission android:name="com.example.sqlite.read"/>
(7)当 同时出现 writePermission和 readPermission的时候,permission 属性 就会失效了,没有用了;
5.实例- 实现 SQLite数据共享
当然和上面一样 一个 数据提供者 AppProvider ,一个数据请求者 AppResovler ;
5.1 AppProvider 实现
(1)实现 SQLiteOpenHelper 创建 数据库和表 ,并初始化 数据 ;
package com.example.sqlite; import android.content.ContentValues; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DB extends SQLiteOpenHelper { public DB(Context context, String name) { super(context, name, null, 1); } /** * 首次创建 数据库的时候调用 * 一般 把建库 和 键表操作 放在这里 */ @Override public void onCreate(SQLiteDatabase db) { // 一般 把建库 和 键表操作 放在这里 db.execSQL("create table if not exists labelnet(_id integer primary key autoincrement,name text not null,pass text not null)"); //初始化 20 个值 ContentValues values=new ContentValues(); for(int i=0;i<20;i++){ values.put("name","yuanmingzhuo"+i); values.put("pass","hpu"+i); db.insert("labelnet",null, values); values.clear(); } } /** * 当数据库版本发送改名的时候,自动调用 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //当数据库版本发送改名的时候,自动调用 } }
(2)实现 ContentProvider ,实现 查询方法 ;
package com.example.sqlite; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class TContentProvider extends ContentProvider { private SQLiteDatabase db; @Override public boolean onCreate() { //在 ContentProvider 被创建 后 调用 /** * 通过SQLiteOpenHelper 调用创建SQLiteDatabase对象 */ DB d=new DB(this.getContext(),"yuan.db"); db=d.getWritableDatabase(); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 根据 uri 查询 指定的 selection 条件的数据,并 可以指定 那些列和排序 //执行查询操作 /** * 数据库表 : labelnet ,全部数据 */ Cursor cursor=db.query("labelnet",null,null,null,null,null,null); /** * 返回出游标对象 */ return cursor; } @Override public String getType(Uri uri) { // 返回 但却 uri的 MIME 类型 , 如果 URI对应得 数据 可能包括 多条记录 ,那么MIME类型 字符串 以vnd.android.dir/开头 //如果只有一条 那么该 MIME 类型数据 以 vnd.android.cursor.item/ 开头 return null; } @Override public Uri insert(Uri uri, ContentValues values) { // 根据 uri 插入 values 数据 return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // 根据 uri 删除 selection 对象的 数据 return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // 根据 uri 修改 数据 return 0; } }
(3)注册 ContentProvider ,添加 读权限,提供 uri地址;
<!-- 注册 Provider --> <provider android:name="com.example.sqlite.TContentProvider" android:authorities="com.example.sqlite" android:exported="true" android:permission="com.example.sqlitedemo" android:readPermission="com.example.sqlite.read" />
(4)MainActivity 测试 读取数据 作为对比
5.2 AppResovler 实现
(1)通过 ContentResolver 和 uri地址 ,调用 刚刚 的查询 方法;
// 通过 ContentResolver 实现 操作 另一个应用 ContentProvider ContentResolver resolver = MainActivity.this.getContentResolver(); Uri uri = Uri.parse("content://com.example.sqlite"); // 调用查询方法(刚刚 已经在 SqliteDemo应用中) Cursor cursor = resolver.query(uri, null, null, null, null);
(2)显示在Listview 中, 作为 对比数据
6.demo 下载
http://download.****.net/detail/lablenet/9055853
谢谢阅读!给个建议吧!
版权声明:本文为博主原创文章,未经博主允许不得转载。