这里写目录标题
权限
- 内容提供器作用:
不同与文件与SharedPreferences的全局可读写,内容提供器可选择只对哪一部分进行共享 - 现有提供器读取和操作数据,创建提供器给数据提供外部接口
普通权限和危险权限
- 普通:不威胁用户安全和隐私,系统自动授权;
- 危险:用户手动授权,运行时权限看起来用的是权限名,实际对应权限组的其他权限也会同时被授权
在程序运行时申请权限
- 以申请拨打电话权限为例
//MainActivity
public void onClick(View v){
//判断是否授过权了
//checkSelfPermission(context,具体权限名)
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifext.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},1);
}else{
call();
}
}
private void call(){
try{
//设定Intent的Action
Intent intent=new Intent(Intent.ACTION_CALL);
//指定协议tel,号码是10086
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}catch{
e.printSatckTrace();
}
}
public void onRequestPermissionResult(int requestCode,String[] permissions,int[] grantResults){
switch(requestCode){
case 1:
if(grandeResults.length>0&&grandsResults[0]==PackageManager.PERMISSION_GRANTED){
call();
}else{
Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default;
}
}
}
//AndroidManifest.xml
<uses-permission android:name="android.permission.CALL_PHONE"/>
访问其他程序中的数据
ContentResolver
Uri
- Uri标准写法
//authority区分程序,path区分表
content://com.example.app.provider/table1
content://com.example.app.provider/table2
- Uri是提供器唯一的标识符,ContentResolver 以Uri 作为唯一参数,传入时要解析成Uri对象
Uri uri=Uri.parse("content://com.example.app.provider/table");
查询
//Uri对象
//写上Uri uri=Uri.parse("content://com.example.app.provider/table");
Cursor cursor=getContentResolver().query( //结果放在cursor对象中返回
uri, //指定查询哪张表
projection, //指定查询哪些列
selection,
selectionArgs, //指定查询哪些行
sortOrder);//对结果进行排序
if(cursor!=null){
while(cursor.moveText()){ //移动游标查询,逐个读取
String column1=cursor.getString(cursor.getColumnIndex("column1"));
int colunm2=cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}
增加
ContentValues values=new ContentValues();
values.put("column1","text");
values.put("column2",1);
getContentResolver().insert(uri,values);
改变
ContentValues values=new ContentValues();
values.put("column1","");
getContentResolver().update(uri,values,"column1=? and column2=?",new String[]{"text","1"});
删除
getContentResolver().detele(uri,"column2=?",new String[]{"1"});
创建内容提供器
- 通配符
*:表示匹配 任意长度 的 任意字符
#:表示匹配 任意长度数字
//一个匹配任意表的内容URI格式 provider/*
//一个匹配table表中任一行数据 provider/table1/#
- URI 的 MIME类型
//content://com.example.app.provider/table1 这个内容URI
vnd.android.cursor.dir/vnd.com.example.app.provider.table1 //内容URI以路径结尾
vnd.android.cursor.item/vnd.com.example.app.provider.table1//内容URI以id结尾
onCreate()
//当ContentResolver尝试访问数据时,内容提供器被初始化,完成对数据库的创建升级,初始化成功返回true,失败返回false
//public class MyProvider extends ContentProvider
public boolean onCreate(){
return false;
}
query()
- 5个参数:uri,projection,selection,selectionArgs,sortOrder
//参数意思在前边已经讲过啦~就不再多加追述啦
public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder){
return null;
}
insert
- 2个参数: uri,values
public Uri insert(Uri uri,ContentValues values){
return null;
}
update
- 4个参数:uri,values,selection,selectionArgs
public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs){
return 0;
}
delete
- 3个参数:uri,selection,selectionArgs
public int delete(Uri uri,String selection,String[] selectioArgs){
return 0;
}
getType()
- 获取URI对象的MIME类型
//MyProvider
public class MyProvider extends ContentProvider{
...
public String getType(Uri uri){
switch(uriMatcher.match(uri)){
case TABLE1_DIR:
return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
case TABLE1_ITEM:
return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
case TABLE2_DIR:
return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2"
case TABLE2_ITEM:
"vnd.android.cursor.item/vnd.com.example.app.provider.table2"
default:
break
}
return null;
}
}
跨程序访问数据
- 相当于以上知识的一次总结运用,虽然代码很长,但是内容简单,有很多相似的部分~
//沿用上一章databaseProvider代码
public class DatbaseProvider extends ContentProvider{
public static final int BOOK_DIR=0;
public static final int BOOK_ITEM=1;
public static final int CATEGORY_DIR=2;
public static final int CATEGORY_ITEM=3;
public static final String AUTHORITY="com.example.databasetest.provider";
private static UriMatcher uriMatcher;
private MyDatabaseHelper dbHelper;
static {
uriMatcher =new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR);
uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR);
uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM);
}
//初始化内容提供器
public boolean onCreate(){
dbHelper =new MyDatabaseHelper(getContext(),"BookStore.db",null,2);
return true;
}
//query:
//先获取SQL实例,传入uri判断用想访问的表,调用SQL.query查询,返回cursor对象
//getPathSegments():将内容URI权限之后的部分以"/"分割,并把结果放到字符列表中
//列表中第一个位置是路径,第二个是id
//得到id通过两个selc参数对查询进行约束
//下面有方法相通~~就不再多加赘述啦
public Cursor query(Uri uri,String[] projection,String selection,String selectionArgs,String sortOrder){
SQLiteDatabase sb=dbHelper.getReadableDatabase();
Cursor cursor=null;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
cursor=db.query("Book",projection,selection,selectionArgs,null,null,sortOrder);
break;
case BOOK_ITEM:
String bookId=uri.getPathSegments().get(1);
cursor=db.query("Book",projection,"id=?",new String[]{bookId},null,null,sortOrder);
break;
case CATEGORY_DIR:
cursor=db.query("Category",projection,selection,selectionArgs,null,null,sortOrder);
break;
case CATEGORY_ITEM:
cursor=db.query("Category",projection,"id=?".new String[]{categotyId},null,null,sortOrder);
break;
default:
break;
}
return cursor;
}
//insert:
//要求返回的是新增数据的URI,因此还要解析成Uri对象
public Uri insert(Uri uri,ContentValues values){
SQLiteDatabase db=dbHelper.getWritableDatabase();
Uri uriReturn=null;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
case BOOK_ITEM:
long newBookId=db.insert("Book",null,values);
uriReturn =Uri.parse("content://"+AUTHORITY+"/book/"+newBookId);
break;
case CATEGORY_DIR:
case CATEGORY_ITEM:
long newCategoryId=db.insert("Category",null,values);
uriReturn=Uri.parse("content://"+AUTHORITY+"/category/"+newCategoryId);
break;
default:
break
}
return uriReturn;
}
public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs){
SQLiteDatabase db=dbHelper.getWritableDatabase();
int updatedRows;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
updateRows=db.update("Book",values,selection,selctionArgs);
break;
case BOOK_ITEM:
String bookId=uri.getPathSegments().get(1);
updateRows=db.update("Book",values,"id=?",new String[]{bookId});
case CATEGORY_DIR:
updateRows=db.update("Category",values,selection,selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId=uri.getPathSegments().get(1);
updateRows=db.update("Category",values,"id=?",new String[]{categoryId});
break;
default:
break;
}
return updateRows;
}
public int delete(Uri uri,String selection,String[] selectionArgs){
//delte与update很类似,除了参数中没有values
//被删除的行数以返回值形式返回
SQLiteDatabase db=dbHelper.getWritableDatabase();
int updatedRows;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
updateRows=db.delete("Book",selection,selctionArgs);
break;
case BOOK_ITEM:
String bookId=uri.getPathSegments().get(1);
updateRows=db.delete("Book","id=?",new String[]{bookId});
break;
case CATEGORY_DIR:
updateRows=db.delete("Category",selection,selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId=uri.getPathSegments().get(1);
updateRows=db.delete("Category","id=?",new String[]{categoryId});
break;
default:
break;
}
return updateRows;
}
public String getType(Uri uri){
//将app变为了databasetest
switch(uriMatcher.match(uri)){
case TABLE1_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.table1";
case TABLE1_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.table1";
case TABLE2_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.table2"
case TABLE2_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.table2"
default:
break
}
return null;
}
}
Git进阶版
-
想要复习git基本使用,可查看
忽略文件
//在app/.gitgnore添加
// /build
/src/test
/src/androidTest
查看修改内容
git status
//查看文件所有更改内容
git diff
//指定查看某个文件更改内容(内容中 -表示删除 +表示增加)
git diff app/src/main/java/com/example/providertest/ManiActivity.java
撤销未提交修改
//reset取消添加 checkout撤销提交
git reset HEAD app/src/main/java/com/example/providertest/MainActivity.java
查看提交记录
git log
//指定看某一条可在该记录后 加上-1
git log 1fa380b..... -1
//想看该记录具体修改了什么内容,可在命令后加上-p参数
git log 1fa380b..... -1 -p
这篇博客分享了Android里的权限机制,学习了如何申请权限,如何访问其他程序的数据,如何建内容提供器共享数据~~小小浅谈,如果对你有用,感谢您百忙中点个赞~♥