四大组件之内容提供器(ContentProvider)
1.内容提供器简介
内容提供器其实就是不同应用程序进行数据交流的一个中间站,工具,我们利用内容提供器就只有两个方面,第一就是将我们本地程序的某些数据暴露出去,第二就是读取其他程序暴露出来的数据。
2.运行时权限
2.1简介
一般我们设置权限直接在androidmamifest.xml文件中去静态设置,但是随着时代的变化,人们越来越追求隐私了,所以危险权限在6.0系统之后只能通过动态去设置,也就是说当你要设置该权限的时候,系统会自动跳转出询问我们是否要开通该权限的对话框,我们进行选择是否开通,以下是危险权限目录,不用死记,其是作为参照表用的,除了以下这些,其他都是普通权限,也就是可以直接静态注册的权限。
注意:
表格中的每个危险权限都属于一个权限组,我们在进行运行时权限处理使用的是权限名,但是用户一旦同意授权了,那么该权限所对应的权限组中所有的其他权限也会同时被授权。
(完整的权限列表:http://developer.android.com/reference/android/Manifest.permission.html)
2.2.实现动态申请权限
步骤:
1)判断用户是否已经给我们授权了
2)如果有授权直接调用授权之后的操作,如果没有授权,进行动态授权处理
代码:
总结:
1)今天判断的语句,第一个参数是context,第二个参数是权限,不等如果返回true的话,进行注册处理
2)动态注册处理使用参数有三个,第一个是context,第二个是权限,第三个是请求码,该返回码用于在onRequestPermissionsResult()中进行对应的授权完成处理逻辑,也就是说这个方法中,是所有权限询问对话框逻辑处理的总集合。
2.3 撤销申请
方案:很简单,当你已经给其授权之后又反悔了,你可以在我们手机设置按钮中的权限设置找到对应程序,进行权限的取消。
3.访问其他程序中的数据
3.1 整体框架
3.2 ContentResolver的基本用法
a.有啥用?其用来访问内容提供器中共享的数据。
b.步骤:
1)通过Context的getContentResolver()方法获取该实例
2)然后根据CRUD的特色化处理代码进行访问
c.uri
1)组成:其由协议,authority和path组成,authority一般是包名来命名,而path是表名。
2)实例:
d.查询操作
1)将uri解析成uri对象
2)使用查询语句,返回cursor
3)遍历cursor,获取值
e.其余操作
添加:
更新:
删除:
3.3 读取系统联系人
需求分析:
1)进行动态权限注册
2)再写一个读取系统联系人的方法,注意最后的cursor要进行关闭
3)最后动态权限也要在androidManifest.xml中进行申请(这一步指的去验证)
代码:
4. 创建自己的内容提供器
4.1作用:通过内容提供器,将数据暴露出去
4.2 实现思路:
说明:
总结:可以看到,几乎每一个方法都会带有uri这个参数,这个参数也正是调用ContentResolver的增删该查方法是传递过来的。
注意:
1)
2)
实例:
在开始之前我们先要创建一个数据库创建类(数据库内容后面会讲~):
DBOpenHelper.java
public class DBOpenHelper extends SQLiteOpenHelper {
final String CREATE_SQL = "CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT,name)";
public DBOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_SQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
Step 1:自定义ContentProvider类,实现onCreate(),getType(),根据需求重写对应的增删改查方法:
NameContentProvider.java
public class NameContentProvider extends ContentProvider {
//初始化一些常量
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private DBOpenHelper dbOpenHelper;
//为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
static{
matcher.addURI("com.jay.example.providers.myprovider", "test", 1);
}
@Override
public boolean onCreate() {
dbOpenHelper = new DBOpenHelper(this.getContext(), "test.db", null, 1);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
switch(matcher.match(uri))
{
//把数据库打开放到里面是想证明uri匹配完成
case 1:
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
long rowId = db.insert("test", null, values);
if(rowId > 0)
{
//在前面已有的Uri后面追加ID
Uri nameUri = ContentUris.withAppendedId(uri, rowId);
//通知数据已经发生改变
getContext().getContentResolver().notifyChange(nameUri, null