内容提供器主要是为了程序之间共享数据,同时还保证安全性。
运行时权限
权限机制:用户在安装程序时会得到程序获得的权限的提醒,同时用户能够查看任意一个程序获得的权限。运行时权限是为了用户能够在程序运行过程中为软件授权而不需要在安装时一次性授权。权限分为危险权限和普通权限,普通权限系统自动授权,危险权限需要用户手动授权。
由于打电话是危险权限,需要在运行时授权。
首先用ContextCompat查询当前是否有权限,那么就向ActivityCompat的requestPermissions方法传入一个权限数组,申请权限。如果有权限直接拨打电话。
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new
String[]{Manifest.permission.CALL_PHONE},1);
}else{
call();
}
}
需要对用户的授权结果进行处理,重写onRequestPermissionsResult方法,如图:
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
call();
}else{
Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
访问其他程序中的数据
ContentResolver
通过getContentResolver获取该类的实例,提供了一系列方法insert(),update(),delete(),query(),与Sqlite不同,表明变成了内容URI,格式如下:
content://com.example.app.provider/table1
,com.example.app是包名,com.example.app.provider是authority,table1是path。
然后需要将内容URI通过Uri.parse转化为URI对象。
Uri uri = Uri.parse(content://com.example.app.provider/table1;
就可以通过uri来查询记录了
Cursor cursor = getContentResolver.query(
uri,
projection,
selection,
selectionArgs,
sortOrder();
)
uri指定表,projection指定列,selection指定where后面的条件,selectionArgs指定条件上的占位符,sortOrder()指定排序方式。返回的是一个Cursor,需要对每一行进行遍历,然后取出一行中的值。
读取系统联系人
首先去获取运行时权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)!=
PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{
Manifest.permission.READ_CONTACTS},1);
}else{
readContacts();
}
使用getContentResolver().query()去获取系统联系人的数据,这里的ContactsContract.CommonDataKinds.Phone.CONTENT_URI是android封装好的URI对象
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.
CONTENT_URI,null,null,null,null);
遍历游标,取出对象,封装成数组,通过adapter适配给ListView,最后完成系统联系人的显示。
自定义内容提供器
自定义MyProvider继承ContentProvider,重写6个方法。
使用通配符*,#
content://com.example.app.provider/*
匹配所有表
content://com.example.app.provider/table1/#
匹配一张表中的所有列
然后使用uriMatch这个方法来实现URI和功能之间的对应。所有的Provider必须提供getType方法,需要返回一个MIME类型,比如:content://com.example.app/table1
是以路径结尾的,那么对应的MIME就是vnd.android.cursor.dir/vnd.com.example.app.provider.table1
;而content://com.example.app/table1/1
是以item结尾的,那么对应的MIME类型就是vnd.andorid.cursor.item/vnd.com.example.app.provide.table1