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.youkuaiyun.com/detail/lablenet/9055853
谢谢阅读!给个建议吧!