1. 程式人生 > 實用技巧 >Android搞定許可權申請

Android搞定許可權申請

0x00 前言

使用EasyPermissions庫進行申請許可權

開啟App時就申請許可權,如果使用者拒絕許可權後,會迴圈申請

如果永久拒絕後,會跳轉到設定裡繼續申請

效果圖:

注:不講原理,先教你怎麼實現


0x01 引入依賴

appbuild.gradle裡面,新增EasyPermissions的依賴

implementation 'pub.devrel:easypermissions:2.0.0'

新增後點擊 File -> Sync Project with Gradle Files 重新構建一些專案


0x02 建立PermissionActivity

建立一個PermissionActivity用於獲取許可權,佈局隨意

可以把它設為啟動Activity,也可以由SplashActivity轉至PermissionActivity


建立完成後,讓PermissionActivity實現EasyPermissions.PermissionCallbacks,並重新下面三個方法

PermissionActivity複製下面的內容即可

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import java.util.List;

import pub.devrel.easypermissions.EasyPermissions;

public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

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

    // 重新下面三個方法
    
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {

    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {

    }
}

0x03 三個方法

其中onRequestPermissionsResult是許可權申請後執行的方法,預設就寫成上面那樣就行

onPermissionsGranted是許可權授權時的回撥

onPermissionsDenied是許可權被拒絕時的回撥


0x04 申請許可權

假如要申請儲存許可權

首先在AndroidManifest.xml裡面加上這兩行

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然後,在PermissionActivity裡定義兩個常量

// 指定申請儲存許可權時,一個識別符號,用於在成功或失敗回撥中判斷申請成功的或失敗的是哪幾個許可權
static final int STORAGE_CALL_BACK_CODE = 0;
// 儲存許可權
static final String[] perms_storage = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};

onCreate裡面加上申請許可權的程式碼

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

    if (EasyPermissions.hasPermissions(this, perms_storage)) {
        Toast.makeText(this, "已經有儲存許可權", Toast.LENGTH_SHORT).show();
    } else {
        EasyPermissions.requestPermissions(this, "請給我許可權", STORAGE_CALL_BACK_CODE, perms_storage);
    }
}

0x05 處理授權成功

onPermissionsGranted方法

@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
    //noinspection SwitchStatementWithTooFewBranches
    switch (requestCode) {
        // 如果儲存許可權申請通過
        case STORAGE_CALL_BACK_CODE:
            Toast.makeText(this, "已同意儲存許可權", Toast.LENGTH_SHORT).show();
            // pass為通過後執行的方法,注意下面有個finish(),pass()中就不要再加finish()了
            pass();
            finish();
            break;
    }
}

0x06 處理授權失敗

onPermissionsDenied方法

@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
    //noinspection SwitchStatementWithTooFewBranches
    switch (requestCode) {
        case STORAGE_CALL_BACK_CODE:
            Toast.makeText(this, "已拒絕儲存許可權", Toast.LENGTH_SHORT).show();
            ActivityCompat.requestPermissions(this, perms_storage, STORAGE_CALL_BACK_CODE);
            break;
    }
    // 如果許可權被永久拒絕,就提示到設定頁面中開啟
    if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
        Toast.makeText(this, "許可權已被永久拒絕", Toast.LENGTH_SHORT).show();
        new AppSettingsDialog
            .Builder(this)
            .setTitle("許可權已被永久拒絕")
            .setRationale("該應用需要此許可權,否則無法正常使用,是否開啟設定")
            .setPositiveButton("確定")
            .setNegativeButton("取消")
            .build()
            .show();
    }
}

0x07 完整程式碼

PermissionActivity

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import java.util.List;

import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

    static final int STORAGE_CALL_BACK_CODE = 0;
    static final String[] perms_storage = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};


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

        if (EasyPermissions.hasPermissions(this, perms_storage)) {
            Toast.makeText(this, "已經有儲存許可權", Toast.LENGTH_SHORT).show();
        } else {
            EasyPermissions.requestPermissions(this, "請給我許可權", STORAGE_CALL_BACK_CODE, perms_storage);
        }
    }

    void pass() {
        startActivity(new Intent(this, MainActivity.class));
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        //noinspection SwitchStatementWithTooFewBranches
        switch (requestCode) {
            // 如果儲存許可權申請通過
            case STORAGE_CALL_BACK_CODE:
                Toast.makeText(this, "已同意儲存許可權", Toast.LENGTH_SHORT).show();
                // pass為通過後執行的方法,注意下面有個finish(),pass()中就不要再加finish()了
                pass();
                finish();
                break;
        }
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        //noinspection SwitchStatementWithTooFewBranches
        switch (requestCode) {
            case STORAGE_CALL_BACK_CODE:
                Toast.makeText(this, "已拒絕儲存許可權", Toast.LENGTH_SHORT).show();
                ActivityCompat.requestPermissions(this, perms_storage, STORAGE_CALL_BACK_CODE);
                break;
        }
        // 如果許可權被永久拒絕,就提示到設定頁面中開啟
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            Toast.makeText(this, "許可權已被永久拒絕", Toast.LENGTH_SHORT).show();
            new AppSettingsDialog
                    .Builder(this)
                    .setTitle("許可權已被永久拒絕")
                    .setRationale("該應用需要此許可權,否則無法正常使用,是否開啟設定")
                    .setPositiveButton("確定")
                    .setNegativeButton("取消")
                    .build()
                    .show();
        }
    }
}

0x08 專案程式碼

專案在github上面,有用的話,可以給一個star

https://github.com/tanyiqu/android-permission-demo