1. 程式人生 > >Android 6.0在執行時申請許可權解釋與例項

Android 6.0在執行時申請許可權解釋與例項

Android 6.0在執行時申請許可權

從android 6.0(API23)開始,當app執行時使用者授予使用者的許可權,而不是在安裝程式的時候。

系統許可權分為2種,分別為normal和dangerous.

  • Normal permission:對於使用者隱私沒有危險的,在清單檔案中申請就可以直接授權。

  • Dangerous permission:app需要訪問使用者的隱私資訊等,即使在清單檔案註冊,也需要在執行是通過使用者授權。

檢查許可權(check permission)

在android6.0及以上的sdk提供了一個檢查許可權的方法:ContextCompat.checkSelfPermission()。

eg:

int permission = ContextCompat.checkSelfPermission(MainActivity.this,
        Manifest.permission.RECORD_AUDIO);

if (permission == PackageManager.PERMISSION_GRANTED) {
    //表示已經授權
}
//PackageManager.PERMISSION_DENIED--->表示許可權被否認了

如果在Activity中申請許可權可以的呼叫:
if (Build.VERSION.SDK_INT >= Build.VERSION
_CODES.M) { int permission = checkSelfPermission(Manifest.permission.RECORD_AUDIO); }

請求許可權

在Android 6.0及以上,如果檢查沒有許可權,需要主動請求許可權。在請求許可權是會彈出一個對話方塊提示使用者,是否授權。
請求許可權的方法:requestPermissions()。在請求許可權後會有一個回撥方法onRequestPermissionsResult()。

ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, 1
); //或者 在Activity的方法呼叫 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},1); } /** * 引數1:requestCode-->是requestPermissions()方法傳遞過來的請求碼。 * 引數2:permissions-->是requestPermissions()方法傳遞過來的需要申請許可權 * 引數3:grantResults-->是申請許可權後,系統返回的結果,PackageManager.PERMISSION_GRANTED表示授權成功,PackageManager.PERMISSION_DENIED表示授權失敗。 * grantResults和permissions是一一對應的 */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); }

解釋為什麼應用程式需要許可權

在某些情況下,你希望使用者能理解你的app為什麼需要這樣一個許可權。例如:使用者開啟一個攝影的app,使用者不會驚訝於camera許可權,但不理解location許可權或聯絡人許可權。所以在使用者授權之前,需要向用戶提供一個解釋。

另一種方法是,如果一個使用者試圖使用需要一個許可權的功能,但拒絕了許可權請求,當下一次使用到此功能時,給使用者一個解釋。

對應此場景,android6.0(API23)及以上,提供了一個方法:shouldshowrequestpermissionrationale(),如果應用程式請求此許可權,並且使用者拒絕了請求,則此方法返回true。

注意:如果使用者在過去拒絕了許可權請求,對話方塊中選擇了“不再詢問”選項,該方法返回false。如果設定中禁止應用程式具有該許可權,該方法還將返回false。

boolean flag = ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.RECORD_AUDIO);

//或者 在Activity的方法呼叫
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    boolean flag = shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO);
}

案例:

public class MainActivity extends AppCompatActivity {

    private boolean granted;
    private Button record;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initPermission();

        initView();

        initListener();
    }

    private void initView() {
        record = (Button) findViewById(R.id.btn_record);
    }

    private void initListener() {
        record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (granted) {
                    record();
                } else {
                    Toast.makeText(MainActivity.this, "你還沒有獲取錄音許可權", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void record() {
        //錄音程式碼
        MediaRecorder recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setOutputFile(getCacheDir().getPath() + "1.mp3");
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        try {
            recorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        recorder.start();
    }

    private void initPermission() {
        int permission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            //需不需要解釋的dialog
            if (shouldRequest()) return;
            //請求許可權
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
        }
    }

    private boolean shouldRequest() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
            //顯示一個對話方塊,給使用者解釋
            explainDialog();
            return true;
        }
        return false;
    }

    private void explainDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("應用需要獲取您的錄音許可權,是否授權?")
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //請求許可權
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
                    }
                }).setNegativeButton("取消", null)
                .create().show();
    }

    /**
     * 請求許可權的回撥
     *
     * 引數1:requestCode-->是requestPermissions()方法傳遞過來的請求碼。
     * 引數2:permissions-->是requestPermissions()方法傳遞過來的需要申請許可權
     * 引數3:grantResults-->是申請許可權後,系統返回的結果,PackageManager.PERMISSION_GRANTED表示授權成功,PackageManager.PERMISSION_DENIED表示授權失敗。
     * grantResults和permissions是一一對應的
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1 && grantResults.length > 0) {
            granted = grantResults[0] == PackageManager.PERMISSION_GRANTED;//是否授權,可以根據permission作為標記
        }
    }
}

操作流程:app開啟->點選否認->點選錄音->返回退出->再次開啟app->點選確定->點選允許->點選錄音

image

操作流程:app開啟->點選否認->點選錄音->返回退出->再次開啟app->點選確定->點選否認->點選錄音
[注:]當不在詢問勾選是,點選否認許可權,shouldShowRequestPermissionRationale()返回值為false.
image