這里寫目錄標題
- 權限
- 普通權限和危險權限
- 在程式運行時申請權限
- 訪問其他程式中的資料
- ContentResolver
- Uri
- 查詢
- 增加
- 改變
- 洗掉
- 創建內容提供器
- onCreate()
- query()
- insert
- update
- delete
- getType()
- 跨程式訪問資料
- Git進階版
- 忽略檔案
- 查看修改內容
- 撤銷未提交修改
- 查看提交記錄
權限
- 內容提供器作用:
不同與檔案與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基本使用,可查看
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里的權限機制,學習了如何申請權限,如何訪問其他程式的資料,如何建內容提供器共享資料~~小小淺談,如果對你有用,感謝您百忙中點個贊~?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/292758.html
標籤:其他
