Android版本升到6.0后最坑的就是权限问题,以下是我参考大神一个权限管理工具类,希望对大家有用
PermissionUtils.java
1 import android.Manifest; 2 import android.app.Activity; 3 import android.content.DialogInterface; 4 import android.content.Intent; 5 import android.content.pm.PackageManager; 6 import android.net.Uri; 7 import android.provider.Settings; 8 import android.support.annotation.NonNull; 9 import android.support.v4.app.ActivityCompat; 10 import android.support.v7.app.AlertDialog; 11 import android.util.Log; 12 import android.widget.Toast; 13 14 import com.qicloud.fathercook.R; 15 16 import java.util.ArrayList; 17 import java.util.HashMap; 18 import java.util.List; 19 import java.util.Map; 20 21 /** 22 * 类说明:权限工具 23 * copy from https://github.com/qianxiaoai/RuntimePermissionsDemo/tree/dev 24 * Author: Kuzan 25 * Date: 2016/12/15 16:44. 26 */ 27 public class PermissionUtils { 28 private static final String TAG = PermissionUtils.class.getSimpleName(); 29 public static final int CODE_RECORD_AUDIO = 0; 30 public static final int CODE_GET_ACCOUNTS = 1; 31 public static final int CODE_READ_PHONE_STATE = 2; 32 public static final int CODE_CALL_PHONE = 3; 33 public static final int CODE_CAMERA = 4; 34 public static final int CODE_ACCESS_FINE_LOCATION = 5; 35 public static final int CODE_ACCESS_COARSE_LOCATION = 6; 36 public static final int CODE_READ_EXTERNAL_STORAGE = 7; 37 public static final int CODE_WRITE_EXTERNAL_STORAGE = 8; 38 public static final int CODE_CHANGE_CONFIGURATION = 9; 39 public static final int CODE_MULTI_PERMISSION = 100; 40 41 public static final String PERMISSION_RECORD_AUDIO = Manifest.permission.RECORD_AUDIO; 42 public static final String PERMISSION_GET_ACCOUNTS = Manifest.permission.GET_ACCOUNTS; 43 public static final String PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE; 44 public static final String PERMISSION_CALL_PHONE = Manifest.permission.CALL_PHONE; 45 public static final String PERMISSION_CAMERA = Manifest.permission.CAMERA; 46 public static final String PERMISSION_ACCESS_FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION; 47 public static final String PERMISSION_ACCESS_COARSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION; 48 public static final String PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE; 49 public static final String PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE; 50 public static final String PERMISSION_CHANGE_CONFIGURATION = Manifest.permission.CHANGE_CONFIGURATION; 51 52 private static final String[] requestPermissions = { 53 PERMISSION_RECORD_AUDIO, // 直接使用麦克风录制音频 54 PERMISSION_READ_PHONE_STATE, // 读取设备状态信息 55 PERMISSION_CALL_PHONE, // 拨打电话和管理电话 56 PERMISSION_CAMERA, // 直接使用相机以拍摄图片或视频 57 PERMISSION_READ_EXTERNAL_STORAGE, // 访问SD卡 58 PERMISSION_WRITE_EXTERNAL_STORAGE, // 操作SD卡 59 PERMISSION_ACCESS_FINE_LOCATION 60 }; 61 62 public interface PermissionGrant { 63 void onPermissionGranted(int requestCode); 64 } 65 66 /** 67 * Requests permission. 68 * 69 * @param activity 70 * @param requestCode request code, e.g. if you need request CAMERA permission,parameters is PermissionUtils.CODE_CAMERA 71 */ 72 public static void requestPermission(final Activity activity, final int requestCode, PermissionGrant permissionGrant) { 73 if (activity == null) { 74 return; 75 } 76 77 Log.i(TAG, "requestPermission requestCode:" + requestCode); 78 if (requestCode < 0 || requestCode >= requestPermissions.length) { 79 Log.w(TAG, "requestPermission illegal requestCode:" + requestCode); 80 return; 81 } 82 83 final String requestPermission = requestPermissions[requestCode]; 84 85 //如果是6.0以下的手机,ActivityCompat.checkSelfPermission()会始终等于PERMISSION_GRANTED, 86 // 但是,如果用户关闭了你申请的权限,ActivityCompat.checkSelfPermission(),会导致程序崩溃(java.lang.RuntimeException: Unknown exception code: 1 msg null), 87 // 你可以使用try{}catch(){},处理异常,也可以判断系统版本,低于23就不申请权限,直接做你想做的。permissionGrant.onPermissionGranted(requestCode); 88 // if (Build.VERSION.SDK_INT < 23) { 89 // permissionGrant.onPermissionGranted(requestCode); 90 // return; 91 // } 92 93 int checkSelfPermission; 94 try { 95 checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission); 96 } catch (RuntimeException e) { 97 Toast.makeText(activity, "please open this permission", Toast.LENGTH_SHORT) 98 .show(); 99 Log.e(TAG, "RuntimeException:" + e.getMessage()); 100 return; 101 } 102 103 if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { 104 Log.i(TAG, "ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED"); 105 106 107 if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) { 108 Log.i(TAG, "requestPermission shouldShowRequestPermissionRationale"); 109 shouldShowRationale(activity, requestCode, requestPermission); 110 111 } else { 112 Log.d(TAG, "requestCameraPermission else"); 113 ActivityCompat.requestPermissions(activity, new String[]{requestPermission}, requestCode); 114 } 115 116 } else { 117 Log.d(TAG, "ActivityCompat.checkSelfPermission ==== PackageManager.PERMISSION_GRANTED"); 118 Toast.makeText(activity, "opened:" + requestPermissions[requestCode], Toast.LENGTH_SHORT).show(); 119 permissionGrant.onPermissionGranted(requestCode); 120 } 121 } 122 123 private static void requestMultiResult(Activity activity, String[] permissions, int[] grantResults, PermissionGrant permissionGrant) { 124 if (activity == null) { 125 return; 126 } 127 128 //TODO 129 Log.d(TAG, "onRequestPermissionsResult permissions length:" + permissions.length); 130 Map<String, Integer> perms = new HashMap<>(); 131 132 ArrayList<String> notGranted = new ArrayList<>(); 133 for (int i = 0; i < permissions.length; i++) { 134 Log.d(TAG, "permissions: [i]:" + i + ", permissions[i]" + permissions[i] + ",grantResults[i]:" + grantResults[i]); 135 perms.put(permissions[i], grantResults[i]); 136 if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { 137 notGranted.add(permissions[i]); 138 } 139 } 140 141 if (notGranted.size() == 0) { 142 // Toast.makeText(activity, "all permission success" + notGranted, Toast.LENGTH_SHORT) 143 // .show(); 144 Log.e(TAG, "all permission success" + notGranted); 145 permissionGrant.onPermissionGranted(CODE_MULTI_PERMISSION); 146 } else { 147 openSettingActivity(activity, "those permission need granted!"); 148 } 149 150 } 151 152 153 /** 154 * 一次申请多个权限 155 */ 156 public static void requestMultiPermissions(final Activity activity, PermissionGrant grant) { 157 158 final List<String> permissionsList = getNoGrantedPermission(activity, false); 159 final List<String> shouldRationalePermissionsList = getNoGrantedPermission(activity, true); 160 161 //TODO checkSelfPermission 162 if (permissionsList == null || shouldRationalePermissionsList == null) { 163 return; 164 } 165 Log.d(TAG, "requestMultiPermissions permissionsList:" + permissionsList.size() + ",shouldRationalePermissionsList:" + shouldRationalePermissionsList.size()); 166 167 if (permissionsList.size() > 0) { 168 ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String[permissionsList.size()]), 169 CODE_MULTI_PERMISSION); 170 Log.d(TAG, "showMessageOKCancel requestPermissions"); 171 172 } else if (shouldRationalePermissionsList.size() > 0) { 173 showMessageOKCancel(activity, "should open those permission", 174 new DialogInterface.OnClickListener() { 175 @Override 176 public void onClick(DialogInterface dialog, int which) { 177 ActivityCompat.requestPermissions(activity, shouldRationalePermissionsList.toArray(new String[shouldRationalePermissionsList.size()]), 178 CODE_MULTI_PERMISSION); 179 Log.d(TAG, "showMessageOKCancel requestPermissions"); 180 } 181 }); 182 } else { 183 grant.onPermissionGranted(CODE_MULTI_PERMISSION); 184 } 185 } 186 187 private static void shouldShowRationale(final Activity activity, final int requestCode, final String requestPermission) { 188 //TODO 189 String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions); 190 showMessageOKCancel(activity, "Rationale: " + permissionsHint[requestCode], new DialogInterface.OnClickListener() { 191 @Override 192 public void onClick(DialogInterface dialog, int which) { 193 ActivityCompat.requestPermissions(activity, 194 new String[]{requestPermission}, 195 requestCode); 196 Log.d(TAG, "showMessageOKCancel requestPermissions:" + requestPermission); 197 } 198 }); 199 } 200 201 private static void showMessageOKCancel(final Activity context, String message, DialogInterface.OnClickListener okListener) { 202 new AlertDialog.Builder(context) 203 .setMessage(message) 204 .setPositiveButton("OK", okListener) 205 .setNegativeButton("Cancel", null) 206 .create() 207 .show(); 208 209 } 210 211 /** 212 * @param activity 213 * @param requestCode Need consistent with requestPermission 214 * @param permissions 215 * @param grantResults 216 */ 217 public static void requestPermissionsResult(final Activity activity, final int requestCode, @NonNull String[] permissions, 218 @NonNull int[] grantResults, PermissionGrant permissionGrant) { 219 220 if (activity == null) { 221 return; 222 } 223 Log.d(TAG, "requestPermissionsResult requestCode:" + requestCode); 224 225 if (requestCode == CODE_MULTI_PERMISSION) { 226 requestMultiResult(activity, permissions, grantResults, permissionGrant); 227 return; 228 } 229 230 if (requestCode < 0 || requestCode >= requestPermissions.length) { 231 Log.w(TAG, "requestPermissionsResult illegal requestCode:" + requestCode); 232 Toast.makeText(activity, "illegal requestCode:" + requestCode, Toast.LENGTH_SHORT).show(); 233 return; 234 } 235 236 Log.i(TAG, "onRequestPermissionsResult requestCode:" + requestCode + ",permissions:" + permissions.toString() 237 + ",grantResults:" + grantResults.toString() + ",length:" + grantResults.length); 238 239 if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 240 Log.i(TAG, "onRequestPermissionsResult PERMISSION_GRANTED"); 241 //TODO success, do something, can use callback 242 permissionGrant.onPermissionGranted(requestCode); 243 244 } else { 245 //TODO hint user this permission function 246 Log.i(TAG, "onRequestPermissionsResult PERMISSION NOT GRANTED"); 247 //TODO 248 String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions); 249 openSettingActivity(activity, "Result" + permissionsHint[requestCode]); 250 } 251 252 } 253 254 private static void openSettingActivity(final Activity activity, String message) { 255 256 showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() { 257 @Override 258 public void onClick(DialogInterface dialog, int which) { 259 Intent intent = new Intent(); 260 intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 261 Log.d(TAG, "getPackageName(): " + activity.getPackageName()); 262 Uri uri = Uri.fromParts("package", activity.getPackageName(), null); 263 intent.setData(uri); 264 activity.startActivity(intent); 265 } 266 }); 267 } 268 269 /** 270 * @param activity 271 * @param isShouldRationale true: return no granted and shouldShowRequestPermissionRationale permissions, false:return no granted and !shouldShowRequestPermissionRationale 272 * @return 273 */ 274 public static ArrayList<String> getNoGrantedPermission(Activity activity, boolean isShouldRationale) { 275 276 ArrayList<String> permissions = new ArrayList<>(); 277 278 for (int i = 0; i < requestPermissions.length; i++) { 279 String requestPermission = requestPermissions[i]; 280 281 282 //TODO checkSelfPermission 283 int checkSelfPermission = -1; 284 try { 285 checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission); 286 } catch (RuntimeException e) { 287 Toast.makeText(activity, "please open those permission", Toast.LENGTH_SHORT) 288 .show(); 289 Log.e(TAG, "RuntimeException:" + e.getMessage()); 290 return null; 291 } 292 293 if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { 294 Log.i(TAG, "getNoGrantedPermission ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED:" + requestPermission); 295 296 if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) { 297 Log.d(TAG, "shouldShowRequestPermissionRationale if"); 298 if (isShouldRationale) { 299 permissions.add(requestPermission); 300 } 301 302 } else { 303 304 if (!isShouldRationale) { 305 permissions.add(requestPermission); 306 } 307 Log.d(TAG, "shouldShowRequestPermissionRationale else"); 308 } 309 310 } 311 } 312 313 return permissions; 314 } 315 }
在Activity中调用如下
1 /** 2 * 判断是否有获取手机信息权限 3 */ 4 private boolean readPhoneStatePermission() { 5 int hasReadPhoneStatePermission = ContextCompat.checkSelfPermission(this, 6 Manifest.permission.READ_PHONE_STATE); 7 if (hasReadPhoneStatePermission == PackageManager.PERMISSION_GRANTED) { 8 return true; 9 } else { 10 return false; 11 } 12 } 13 14 @Override 15 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 16 for (int i=0; i<permissions.length; i++) { 17 if (permissions[i].equals(Manifest.permission.READ_PHONE_STATE) 18 && grantResults[i] == PackageManager.PERMISSION_GRANTED) { 19 // 用户同意获取手机信息权限 20 21 break; 22 } 23 } 24 PermissionUtils.requestPermissionsResult(this, requestCode, permissions, grantResults, mPermissionGrant); 25 }
1 private PermissionUtils.PermissionGrant mPermissionGrant = new PermissionUtils.PermissionGrant() { 2 @Override 3 public void onPermissionGranted(int requestCode) { 4 switch (requestCode) { 5 case PermissionUtils.CODE_RECORD_AUDIO: 6 Log.w("Permission", "Result Permission Grant CODE_RECORD_AUDIO"); 7 break; 8 case PermissionUtils.CODE_READ_PHONE_STATE: 9 Log.w("Permission", "Result Permission Grant CODE_READ_PHONE_STATE"); 10 break; 11 case PermissionUtils.CODE_CALL_PHONE: 12 Log.w("Permission", "Result Permission Grant CODE_CALL_PHONE"); 13 break; 14 case PermissionUtils.CODE_CAMERA: 15 Log.w("Permission", "Result Permission Grant CODE_CAMERA"); 16 break; 17 case PermissionUtils.CODE_READ_EXTERNAL_STORAGE: 18 Log.w("Permission", "Result Permission Grant CODE_READ_EXTERNAL_STORAGE"); 19 break; 20 case PermissionUtils.CODE_WRITE_EXTERNAL_STORAGE: 21 Log.w("Permission", "Result Permission Grant CODE_WRITE_EXTERNAL_STORAGE"); 22 break; 23 case PermissionUtils.CODE_MULTI_PERMISSION: 24 Log.w("Permission", "Result All Permission Grant"); 25 break; 26 default: 27 break; 28 } 29 } 30 };
在onCreate中调用
PermissionUtils.requestMultiPermissions(this, mPermissionGrant);
判断是否有权限
if (readPhoneStatePermission()) { // ToDo }