Android開發之運行時權限申請和自定義權限

轉載請註明出處: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"/>














發佈了36 篇原創文章 · 獲贊 37 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章