本文章是對android 6.0許可權機制的簡單封裝,如果對許可權機制不太瞭解可以移步android 6.0許可權申請機制(簡單案例),有助於你對許可權機制的整體瞭解。
在封裝的過程中出現了一個問題,給大家分享下: 在官方文件中許可權的回撥是這樣的:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
複製程式碼
在本方法中,官方使用的是switch..case...的方法去實現的,然而在封裝過程中無法將MY_PERMISSIONS_REQUEST常量資訊傳遞給PermissionUtils的callback(...)方法,傳遞後就會變成int型別,無法使用switch...case...方法,在查閱相關資料後,將回撥的方法改成這樣:
public void callback(int requestCode, String permissions[], int[] grantResults){
if(requestCode == key){
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(context, "申請失敗", Toast.LENGTH_SHORT).show();
}
return;
}
}
複製程式碼
去判斷requestCode和key的值是否相等代替掉switch...case...,這個時switch...case...的基本原理,原諒我一時忘記!
接下來直接上全部整體原始碼: ####1.AndroidManifest的許可權新增
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.SEND_SMS" />
複製程式碼
####2.PermissionUtils的封裝
package com.example.mypremission;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by 納蘭寒明 on 2017/7/31.
* 歡迎大家關注我的主頁
* 簡書--http://www.jianshu.com/u/d9b6614545ce
*/
class PermissionUtils {
private Context context;
private List<String> p = new ArrayList<>();
public static int key = 1;
//構造器
PermissionUtils(Context context,int key) {
this.context = context;
this.key = key;
}
//新增許可權資訊
public void add(String permission) {
p.add(permission);
}
//將list轉化為String
private String[] getPermissionString(){
String strings[] = new String[p.size()];
for (int k = 0, j = p.size(); k < j; k++) {
strings[k] = p.get(k);
}
return strings;
}
//實現許可權的申請
public void setPermission() {
Log.e("kang",p+toString());
for (int i = 0; i < p.size(); i++) {
requestPermission(i);
String strings[] = getPermissionString();
ActivityCompat.requestPermissions((Activity) context, strings,key);
}
}
//回撥方法
public void callback(int requestCode, String permissions[], int[] grantResults){
if(requestCode == key){
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(context, "申請失敗", Toast.LENGTH_SHORT).show();
}
return;
}
}
//驗證許可權的資訊
private void requestPermission(int i) {
if (ContextCompat.checkSelfPermission(context,
p.get(i))
!= PackageManager.PERMISSION_GRANTED) {
//檢查到該許可權未被授權
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context,
p.get(i))) {
//上一次使用者拒絕了開啟此許可權
// p.remove(i);
Toast.makeText(context, "上次使用者拒絕開啟了"+p.get(i).toString()+"許可權!", Toast.LENGTH_SHORT).show();
}
} else {
p.remove(i);
}
}
}
複製程式碼
####3.Activity中的配置
package com.example.mypremission;
import android.Manifest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private PermissionUtils p;
private static final int MY_PERMISSIONS_EXTERNAL= 1;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//宣告PermissionUtils的物件
p = new PermissionUtils(this,MY_PERMISSIONS_EXTERNAL);
//新增許可權資訊
p.add(Manifest.permission.CAMERA);
p.add(Manifest.permission.SEND_SMS);
p.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
//啟動許可權申請
p.setPermission();
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
//許可權回撥處理
p.callback(requestCode,permissions,grantResults);
}
}
複製程式碼
目前在程式中,不太理解MY_PERMISSIONS_EXTERNAL的功能,他的必要性是什麼,檢視文件與回撥方法onRequesrPermissionResult(...)方法有關,但具體不太理解,希望大神可以幫我指出來它的功能。接下來我會檢視資料,解決問題!
修改版本:感謝@pianoboyfans 對本章的支援!通過交流,確實發現程式碼中存在的一些問題,現在問題已經解決。如果還有什麼bug還請反饋,及時修改,完善這個封裝類。
更新程式碼中修改PermissionUtils封裝類,其他未動,所以只更新PermissionUtils類:
/**
* Created by 納蘭寒明 on 2017/7/31.
* 歡迎大家關注我的主頁
* 掘金--https://juejin.im/user/57e79759d20309006940dab7
*/
class PermissionUtils {
private Context context;
private List<String> p = new ArrayList<>();
public static int key = 1;
public int temp = 0;
//構造器
PermissionUtils(Context context,int key) {
this.context = context;
this.key = key;
}
//新增許可權資訊
public void add(String permission) {
p.add(permission);
}
//將list轉化為String
private String[] getPermissionString(){
String strings[] = new String[p.size()];
for (int k = 0, j = p.size(); k < j; k++) {
strings[k] = p.get(k);
}
return strings;
}
//實現許可權的申請
public void setPermission() {
while(p.size()>temp){
requestPermission(temp);
temp++;
}
String strings[] = getPermissionString();
if(strings.length != 0)
ActivityCompat.requestPermissions((Activity) context, strings,key);
}
//回撥方法
public void callback(int requestCode, String permissions[], int[] grantResults){
if(requestCode == key){
if (grantResults.length > 0){
//每個許可權的返回資訊都可以判斷其是否授權成功
for(int i = 0;i<grantResults.length;i++){
if(grantResults[i] == PackageManager.PERMISSION_GRANTED){
//成功授權
Toast.makeText(context, "授權成功", Toast.LENGTH_SHORT).show();
}else{
//授權失敗
Toast.makeText(context, "授權失敗", Toast.LENGTH_SHORT).show();
}
}
}
return;
}
}
//驗證許可權的資訊
private void requestPermission(int i) {
//檢查到該許可權未被授權
if (ContextCompat.checkSelfPermission(context,
p.get(i))
!= PackageManager.PERMISSION_GRANTED) {
//判斷上一次使用者是否開啟了此許可權(原生系統)
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context,
p.get(i))) {
//上一次使用者拒絕了開啟此許可權
Toast.makeText(context, "上次使用者拒絕開啟了"+p.get(i).toString()+"許可權!", Toast.LENGTH_SHORT).show();
}
} else {
//檢查許可權被授權就移除許可權
p.remove(i);
temp--;
}
}
}
複製程式碼
原生系統在使用者拒絕後第二次開啟程式還是會讓使用者選擇的,而本人親測小米5手機上shouldShowRequestPermissionRationale()這個方法返回的是false(),那麼就不會在第二次開啟程式後彈出被拒絕的許可權了,直接就會拒絕授權。
該封裝類許可權控制較為重要,避免多次使用,只允許擁有一個例項,所以可以使用單例模式進行封裝!