1. 程式人生 > >Android 6.0 許可權的申請 與 封裝

Android 6.0 許可權的申請 與 封裝

Android 6.0 以後最大的改變就是對於許可權的管理這一塊了,以前某個App 想使用什麼許可權 只要在 manifest 檔案裡面新增申請就可以了。
Android 6.0 以後不但要在manifest 裡面新增執行的時候還會彈出一個對話方塊讓使用者選擇是否賦予該許可權。

新的許可權機制更好的保護了使用者的隱私,Google將許可權分為兩類,一類是Normal Permissions,這類許可權一般不涉及使用者隱私,是不需要使用者進行授權的,比如手機震動、訪問網路等;另一類是Dangerous Permission,一般是涉及到使用者隱私的,需要使用者進行授權,比如讀取sdcard、訪問通訊錄等。

Normal Permissions:
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
…….
Dangerous Permissions:
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
……

可以通過adb shell pm list permissions -d -g進行檢視。

申請步驟:
1. 在AndroidManifest檔案中新增需要的許可權
2. 使用前檢查
3. 申請許可權
4. 處理申請回調

(一) 在AndroidManifest檔案中新增需要的許可權
這個和在6.0 以前是一樣的。

(二)檢查許可權
這裡寫圖片描述
6.0 以後 在 Activity 裡面 有
checkSelfPermission(String permission)這個方法。
(其實是在ContextWrapper ,Activity 實現了 ContextWrapper )
也可以使用 ContextCompat.checkSelfPermission()這個方法。
ContextCompat 是在 support.v4 裡面的。為了相容6.0以前 版本,儘量使用 ContextCompat 檢查許可權。

(三)申請許可權
這裡寫圖片描述
6.0 以後 在Activity 也有
requestPermissions(String[] permissions, int requestCode);
(也是 ContextWrapper 裡面的)
也可以通過
ActivityCompat.requestPermissions(final @NonNull Activity activity,final @NonNull String[] permissions, final int requestCode)
申請。
ActivityCompat 在 v4 裡面,建議申請許可權 都統一使用 v4 裡面的元件申請管理。以免出現異常。

(四) 許可權回撥處理
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
申請許可權時候 會彈出一個對話方塊,使用者可以選擇 同意或者不同意。
使用者操作之後會回撥到這個方法。

    if (grantResults.length > 0&& grantResults[0] ==PackageManager.PERMISSION_GRANTED)

public static final int PERMISSION_DENIED = -1; //拒絕
public static final int PERMISSION_GRANTED = 0;//同意

我們可以根據不同的邏輯進行不同的處理。

(五) 簡單封裝

/**
 * @Author linyong
 * @Date 2016/10/5
 * @Time 22:22
 */
public class BaseActivity extends Activity {

    /**
     * @param permissions
     * @return
     */
    protected boolean hasPermissions(String... permissions) {
        boolean flag = true;
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return flag;
    }

    /**
     *
     * @param requestCode
     * @param permissions
     */
    protected void doRequestPermissions(int requestCode, String... permissions) {
        ActivityCompat.requestPermissions( this,permissions,  requestCode);
    }

}

Fragment 也可以進行類似的封裝。

(六) 高階封裝
使用 PermissionGen(https://github.com/lovedise/PermissionGen),一個韓國人寫的,通過反射簡單的封裝了許可權的處理。
具體用法可以 看他的 sample。使用起來比較簡單。

public class MainActivity extends AppCompatActivity {
    @Bind(R.id.btn_contact)
    Button btnContact;
    @Bind(R.id.btn_camera)
    Button btnCamera;


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

    @OnClick({R.id.btn_contact, R.id.btn_camera})
    public void open(View view) {
        switch (view.getId()) {
            case R.id.btn_contact:
                PermissionGen.with(MainActivity.this)
                        .addRequestCode(100)
                        .permissions(
                                Manifest.permission.READ_CONTACTS,
                                Manifest.permission.RECEIVE_SMS,
                                Manifest.permission.WRITE_CONTACTS)
                        .request();
                break;
            case R.id.btn_camera:
                PermissionGen.needPermission(this, 200, Manifest.permission.CAMERA);
                break;
        }
    }

    @PermissionSuccess(requestCode = 100)
    public void test() {
        startActivity(new Intent(this, ContactActivity.class));
    }

    @PermissionFail(requestCode = 100)
    private void test2() {
        Dlog.debug("contact fail");
    }

    @PermissionSuccess(requestCode = 200)
    public void openCamera() {
        Dlog.debug("open camera success");
    }

    @PermissionFail(requestCode = 200)
    public void failOpenCamera() {
        Toast.makeText(this, "Camera permission is not granted", Toast.LENGTH_SHORT).show();
    }

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