轉載請註明出處:http://blog.csdn.net/li0978/article/details/52168827
運行時權限申請
Android 6.0在我們原有的AndroidManifest.xml聲明權限的基礎上,又新增了運行時權限動態檢測,以下權限都需要在運行時判斷(不判斷則會報錯):
身體傳感器 |
首先觸發權限申請:
public void onCameraClick(View view) {
//判斷權限是否已經同意
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//1.還未同意
requestCameraPermission();
} else {
//2.已同意
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
}
}
開始請求權限:
private void requestCameraPermission() {
//判斷“不在提醒”複選框是否展示
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
//3.複選框顯示時的請求
ActivityCompat.requestPermissions(GooglePermissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
} else {
//4.複選框不顯示時的請求
ActivityCompat.requestPermissions(GooglePermissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
}
//如果需要針對“不在提醒”複選框顯示時做一些處理用上邊的方式,否者乾脆直接請求權限(個人推薦後者)
// ActivityCompat.requestPermissions(GooglePermissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
}
這一步可以不僅僅可以請求一個權限也可以請求一組權限,另外也將會根據權限申請的過程展示不同的權限說明界面(都是系統給的),第一次請求是沒有複選框的,第一次拒絕後第二次請求會多出一個複選框出來。
權限請求結果:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA) {
if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//5.回調權限申請成功
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
} else {
//6.回調權限申請拒絕
Toast.makeText(this, "相機開啓被拒絕,請到系統設置中開啓相機權限。", Toast.LENGTH_LONG).show();
}
}
}
這一步和Activity中執行startActivityForResult方法進行回調的onActivityResult()方法類似,這裏可以根據當前請求某個權限的申請結果進行不同的處理。
根據上邊三段代碼中註釋部分的編號,整個請求過程如下圖所示:
在fragment中權限處理:
1.在Fragment中申請權限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否則會回調到Activity的onRequestPermissionsResult。
2.如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方法,onRequestPermissionsResult不會回調回來,建議使用getParentFragment().requestPermissions方法,這個方法會回調到父Fragment中的onRequestPermissionsResult,加入以下代碼可以把回調後傳到子Fragment:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
List<Fragment> fragments = getChildFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment != null) {
fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}
}
}
自定義權限
在android系統的安全模型中,應用程序在默認的情況下不可以執行任何對其他應用程序,系統或者用戶帶來負面影響的操作。如果應用需要執行某些操作,就需要聲明使用這個操作對應的權限。
一般情況下我們都是註冊系統權限來滿足對系統相關組件的操作,我們還可以自定義屬於我們自己app的權限來滿足來自其他程序安全的交互通信。
1.聲明自定義權限:
<permission
android:name="com.bigrun.permissionforandroidm.customerpermission1"
android:description="@string/hello_world"
android:label="@string/app_name"
android:protectionLevel="normal" />
自定義權限中標示說明:
android:name :權限的唯一標識,一般都是使用 包名加權限名 。(必寫)
android:label: 對權限的一個簡短描述。
android:description :對權限的描述,一般是兩句話,第一句話描述這個權限所針對的操作,第二句話告訴用戶授予app這個權限會帶來的後果 。
android:permissionGroup: 權限所屬權限組的名稱 。
android:protectionLevel: 權限的等級。(必寫)
權限的等級分爲如下四個:
normal 是最低的等級,聲明此權限的app,系統會默認授予次權限,不會提示用戶 。dangerous 權限對應的操作有安全風險,系統在安裝聲明此類權限的app時會提示用戶 ,在android6.0以上會出現運行時提示權限申請對話框。signature 此權限的申請若想正常使用必須保證兩個應用的簽名一致。signatureOrSystem 與signature類似,只是增加了rom中自帶的app的聲明 。
2.指定某個組件啓動時使用此權限:
這裏我們指定程序的主程序擁有此權限。
<activity android:name=".TestActivity" android:permission="com.bigrun.permissionforandroidm.customerpermission1">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
一定要有一個過濾器設置其啓動方式爲主界面啓動。3.在另一個應用中去啓動此界面。
註冊上一個應用程序的自定義權限:
<uses-permission android:name="com.example.customerpermission1"/>
啓動上一個應用程序:
Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.bigrun.permissionforandroidm","com.bigrun.permissionforandroidm.TestActivity");
intent.setComponent(componentName);
startActivity(intent);
上邊也可以設定一個權限組:
<permission-group
android:name="com.bigrun.permissionforandroidm.customerpermissiongroup"
android:description="@string/hello_world"
android:label="@string/app_name" />
<permission
android:name="com.bigrun.permissionforandroidm.customerpermission1"
android:description="@string/hello_world"
android:label="@string/app_name"
android:permissionGroup="com.bigrun.permissionforandroidm.customerpermissiongroup"
android:protectionLevel="normal" />
在另外一個app中同樣要註冊這個權限組:
<uses-permission android:name="com.bigrun.permissionforandroidm.customerpermission1"/>
<permission-tree android:name="com.kifile.test.permission"/>