getResults() {
236 | if (mResults == null) {
237 | synchronized (EasyPermissionHelper.class) {
238 | if (mResults == null) {
239 | mResults = new SparseArray<>(1);
240 | }
241 | }
242 | }
243 | return mResults;
244 | }
245 |
246 | /**
247 | * Check the current permissions
248 | * 检查当前的权限情况
249 | *
250 | * @param permissions
251 | * @return
252 | */
253 | public boolean hasPermission(@NonNull String... permissions) {
254 | //6.0以上才需要动态检查
255 | // above 6.0, dynamic check is required
256 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
257 | return true;
258 | }
259 | for (String permission : permissions) {
260 | if (ContextCompat.checkSelfPermission(getTopActivity(), permission) != PackageManager.PERMISSION_GRANTED) {
261 | // 只要有一个权限没有被授予, 则直接返回 false
262 | // False is returned as long as a permission is not granted
263 | return false;
264 | }
265 | }
266 | return true;
267 | }
268 |
269 |
270 | /**
271 | * Request permission but no permission result callback is required
272 | * 申请权限但是不需要权限结果回调
273 | *
274 | * @param requestCode 请求回调code
275 | * @param mAlertInfo 提示信息
276 | * @param permissions
277 | * @return
278 | */
279 | protected void requestPermission(int requestCode, PermissionAlertInfo mAlertInfo, @NonNull String... permissions) {
280 | //显示提示信息
281 | showAlert(mAlertInfo);
282 | this.doRequestPermission(requestCode, permissions);
283 | }
284 |
285 |
286 | /**
287 | * Request permission but no permission result callback is required
288 | * 申请权限但是不需要权限结果回调
289 | *
290 | * @param easyPermission
291 | * @return
292 | */
293 | protected void requestPermission(@NonNull EasyPermission easyPermission) {
294 | //更新请求的activity
295 | if(easyPermission.getContext() != null){
296 | updateTopActivity(easyPermission.getContext());
297 | }
298 | // this.mCurrentEasyPermission = easyPermission;
299 | if (easyPermission.getResult() == null) {
300 | //无需回调
301 | requestPermission(easyPermission.getAlertInfo(), easyPermission.getPerms());
302 | } else {
303 | requestPermission(easyPermission.getRequestCode(),
304 | easyPermission.getResult(), easyPermission.getAlertInfo(), easyPermission.getPerms());
305 | }
306 | }
307 |
308 | /**
309 | * Request permission but no permission result callback is required
310 | * 申请权限但是不需要权限结果回调
311 | *
312 | * @param mAlertInfo 提示信息
313 | * @param permissions
314 | * @return
315 | */
316 | protected void requestPermission(PermissionAlertInfo mAlertInfo, @NonNull String... permissions) {
317 | this.requestPermission(REQUESTCODE_DEFAULT, mAlertInfo, permissions);
318 | }
319 |
320 |
321 | /**
322 | * To do request permission
323 | * 执行申请权限
324 | *
325 | * @param requestCode
326 | * @param permissions
327 | * @return
328 | */
329 | protected void doRequestPermission(int requestCode, @NonNull String... permissions) {
330 | ActivityCompat.requestPermissions(getTopActivity(),
331 | permissions, requestCode);
332 | }
333 |
334 | /**
335 | * Requesting permission requires a callback of the permission result
336 | * 申请权限 需要权限结果回调
337 | *
338 | * @param permissions
339 | * @return
340 | */
341 | protected void requestPermission(int requestCode, EasyPermissionResult result, PermissionAlertInfo mAlertInfo, @NonNull String... permissions) {
342 | //保存结果回调
343 | //Save the result callback
344 | if (requestCode != REQUESTCODE_DEFAULT || result != null) {
345 | getResults().append(requestCode, result);
346 | }
347 | this.requestPermission(requestCode, mAlertInfo, permissions);
348 | }
349 |
350 | /**
351 | * 顶部提示框
352 | */
353 | private Dialog alertDialog;
354 |
355 | /**
356 | * Display permission description information
357 | * 权限说明信息展示
358 | */
359 | private void showAlert(PermissionAlertInfo mAlertInfo) {
360 | if (mAlertInfo == null || TextUtils.isEmpty(mAlertInfo.alertMessage)) {
361 | return;
362 | }
363 | //避免弹出多个
364 | if(alertDialog != null && alertDialog.isShowing()){
365 | alertDialog.dismiss();
366 | }
367 | Activity topActivity = getTopActivity();
368 | if(topActivity == null) return;
369 | EasyPermissionLog.d("showAlert:"+topActivity.getLocalClassName());
370 | alertDialog = EasyAppDialogTool.showTopAlertStyle(mAlertInfo,mTopAlertStyle);
371 |
372 | //
373 | // View alertView = View.inflate(topActivity, R.layout.alert_info_top, null);
374 | // alertDialog = new Dialog(topActivity, R.style.theme_alertdialog_transparent);
375 | // alertDialog.setOwnerActivity(topActivity);
376 | // TextView titleView = alertView.findViewById(R.id.tvAlertTitle);
377 | // titleView.setText(mAlertInfo.alertTitle);
378 | // TextView messageView = alertView.findViewById(R.id.tvAlertMessage);
379 | // messageView.setText(mAlertInfo.alertMessage);
380 | // Window win = alertDialog.getWindow();
381 | //// int with = EasyViewUtil.getScreenWidth(topActivity);
382 | //// int side = EasyViewUtil.dip2px(topActivity,5);
383 | // win.getDecorView().setPadding(0, 0, 0, 0);
384 | // WindowManager.LayoutParams lp = win.getAttributes();
385 | // lp.width = WindowManager.LayoutParams.MATCH_PARENT;
386 | // lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
387 | // lp.gravity = Gravity.TOP;
388 | // win.setAttributes(lp);
389 | // alertDialog.getWindow().setBackgroundDrawable(new BitmapDrawable(topActivity.getResources(), (Bitmap) null));
390 | // alertDialog.setContentView(alertView);
391 | // alertDialog.show();
392 | }
393 |
394 | /**
395 | * When an activity needs to be destroyed, its attached dialog also needs to be destroyed
396 | * activity需要销毁时,依附的dialog也需要销毁
397 | */
398 | private void dismissAlert(Activity activity) {
399 | if (alertDialog != null && alertDialog.isShowing()) {
400 | EasyPermissionLog.d(" dismissAlert:activity:"+activity.getLocalClassName());
401 | EasyPermissionLog.d(" dismissAlert:getOwnerActivity:"+alertDialog.getOwnerActivity().getLocalClassName());
402 | boolean isCurrentAlert = activity.equals(alertDialog.getOwnerActivity());
403 | if(isCurrentAlert){
404 | alertDialog.dismiss();
405 | }
406 | }
407 | }
408 |
409 | /**
410 | * Hide the instructions when the authorization result is called back
411 | * 授权结果回调时,隐藏说明提示
412 | */
413 | private void dismissAlert() {
414 | if (alertDialog != null && alertDialog.isShowing()) {
415 | alertDialog.dismiss();
416 | }
417 | }
418 | /**
419 | * Permissions are disabled from pop-ups
420 | * 权限被禁止弹窗
421 | */
422 | private void showDialog(EasyPermission easyPermission) {
423 | if(mDialogStyle == null){
424 | //默认样式
425 | //The default styles
426 | EasyAppDialogTool.showDialogWithDefaultStyle(easyPermission);
427 | }else {
428 | switch (mDialogStyle.getStyle()){
429 | case STYLE_CUSTOM:
430 | //自定义样式
431 | //Custom styles
432 | EasyAppDialogTool.showDialogWithCustomStyle(easyPermission,mDialogStyle);
433 | break;
434 | case STYLE_SYSTEM:
435 | //系统样式
436 | //System style
437 | EasyAppDialogTool.showDialogWithSystemStyle(easyPermission);
438 | break;
439 | default:
440 | //默认样式
441 | //The default styles
442 | EasyAppDialogTool.showDialogWithDefaultStyle(easyPermission);
443 | break;
444 | }
445 | }
446 | }
447 |
448 | /**
449 | * After requesting a callback, you can determine whether a second request has been denied
450 | * The original intention of Google is:
451 | * 1,If you have not applied for permission, just apply, so return false.
452 | * 2. If the application is rejected by the user, you will prompt the user, so return true;
453 | * 3. If the user chooses to reject the application and does not prompt the user any more,
454 | * then you should not apply or prompt the user, so return false.
455 | * 4. It has been allowed. No application or prompt is required, so return false.
456 | * So the use of pure shouldShowRequestPermissionRationale to do judgment,
457 | * it is no use, can only be used request permission again after correction.
458 | *
459 | * 在请求回调后可以判断是否被拒绝再次请求
460 | * Google的原意是:
461 | * 1,没有申请过权限,申请就是了,所以返回false;
462 | * 2,申请了用户拒绝了,那你就要提示用户了,所以返回true;
463 | * 3,用户选择了拒绝并且不再提示,那你也不要申请了,也不要提示用户了,所以返回false;
464 | * 4,已经允许了,不需要申请也不需要提示,所以返回false;
465 | * 所以单纯的使用shouldShowRequestPermissionRationale去做什么判断,是没用的,只能在请求权限回调后再使用。
466 | *
467 | * @param permission
468 | */
469 | private boolean shouldShowRequestPermissionRationale(String permission) {
470 | return ActivityCompat.shouldShowRequestPermissionRationale(getTopActivity(), permission);
471 | }
472 |
473 | /**
474 | * you can determine whether a second request has been denied
475 | *
476 | * 可以判断是否被拒绝再次请求
477 | *
478 | * @param permissions
479 | */
480 | public boolean hasBeanDismissAsk(String... permissions) {
481 | boolean tempDismissAsk = false;
482 | for (String permission : permissions) {
483 | //读取本地存储的被拒绝权限
484 | tempDismissAsk = EasyCacheData.getInstance().getBoolean(permission);
485 | EasyPermissionLog.d("haveBeanDismissAsk:" + tempDismissAsk);
486 | if (tempDismissAsk) return true;
487 | }
488 | return false;
489 | }
490 |
491 | /**
492 | * Update forbidden permission information
493 | * 更新被禁止的权限信息
494 | *
495 | * @param permissions 权限
496 | * @param state true被禁止,false不被禁止可以询问
497 | */
498 | protected void updateDismissState(String[] permissions, boolean state) {
499 | for (String permission : permissions) {
500 | updateDismissState(permission, state);
501 | }
502 | }
503 |
504 | /**
505 | * Update forbidden permission information
506 | * 更新被禁止的权限信息
507 | *
508 | * @param permission 权限
509 | * @param permission true被禁止,false不被禁止可以询问
510 | */
511 | protected void updateDismissState(String permission, boolean state) {
512 | EasyCacheData.getInstance().save(permission, state);
513 | }
514 |
515 | /**
516 | * Denied permission and forbidden to ask
517 | *
518 | * 被拒绝请求权限,且禁止询问
519 | *
520 | * @param permissions
521 | * @return
522 | */
523 | protected boolean hasDismissedAsk(@NonNull String... permissions) {
524 | return !hasPermission(permissions)
525 | && hasBeanDismissAsk(permissions);
526 | }
527 |
528 | /**
529 | * Open the APP's permission details Settings
530 | * Receive the permission callback result of requestCode in the onActivityResult, and re-execute the permission related logic
531 | * 打开 APP 的权限详情设置
532 | * 在onActivityResult中接收requestCode的权限回调结果,重新执行权限相关逻辑
533 | */
534 | protected void openAppDetails(@NonNull EasyPermission easyPermission) {
535 | this.mCurrentEasyPermission = easyPermission;
536 | //更新请求的activity
537 | if(easyPermission.getContext() != null){
538 | updateTopActivity(easyPermission.getContext());
539 | }
540 | showDialog(easyPermission);
541 | }
542 |
543 | /**
544 | * Skip To the Settings
545 | * 跳转设置页
546 | */
547 | public void goToAppSettings(@NonNull EasyPermission easyPermission) {
548 | //更新请求的activity
549 | if(easyPermission.getContext() != null){
550 | updateTopActivity(easyPermission.getContext());
551 | }
552 | this.mCurrentEasyPermission = easyPermission;
553 | goToAppSettings(easyPermission.getRequestCode());
554 | }
555 |
556 | /**
557 | * Skip To the Settings
558 | * 跳转设置页
559 | *
560 | * @param requestCode
561 | */
562 | public void goToAppSettings(int requestCode) {
563 | Activity topActivity = getTopActivity();
564 | Intent intent = new Intent();
565 | intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
566 | intent.addCategory(Intent.CATEGORY_DEFAULT);
567 | intent.setData(Uri.parse("package:" + topActivity.getPackageName()));
568 | intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
569 | intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
570 | topActivity.startActivityForResult(intent, requestCode);
571 | }
572 |
573 | /**
574 | * Handle permissions result callbacks
575 | * In the activity of need to access the callback rewrite onRequestPermissionsResult calls to this function
576 | *
577 | * 处理权限结果回调
578 | * 在需要权限回调的activity中重写onRequestPermissionsResult调用此函数
579 | *
580 | * @param requestCode
581 | * @param permissions
582 | * @param grantResults
583 | */
584 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults, @NonNull Activity context) {
585 | dismissAlert();
586 | EasyPermissionLog.d("权限结果回调,隐藏弹窗");
587 | // no callback required
588 | //不需要回调的情况
589 | if (requestCode == REQUESTCODE_DEFAULT) {
590 | return;
591 | }
592 | if (mResults == null || mResults.size() == 0) {
593 | return;
594 | }
595 | EasyPermissionResult permissionResult = mResults.get(requestCode);
596 | if (permissionResult == null) {
597 | return;
598 | }
599 | if (permissions.length <= 0) {
600 | return;
601 | }
602 | //Here are the situations where a callback is required
603 | //以下是需要回调的情况
604 |
605 | //grantResults is empty to indicate that permissions are not being asked but the request is being invoked
606 | //grantResults为空表示权限被禁止询问了但是还调用了申请请求
607 | if (grantResults == null) {
608 | //Do not process onpermissionsseparation when true
609 | //为true不处理onPermissionsDismiss
610 | boolean onPermissionsDismiss = false;
611 | //Permissions are forbidden to ask
612 | //权限被禁止询问
613 | EasyPermissionLog.d("权限已经被禁止询问");
614 | //保存被禁止的权限
615 | updateDismissState(permissions, true);
616 | onPermissionsDismiss = permissionResult.onDismissAsk(requestCode, Arrays.asList(permissions),true);
617 | //Permission not passed
618 | //权限未通过
619 | if (!onPermissionsDismiss) {
620 | permissionResult.onPermissionsDismiss(requestCode, Arrays.asList(permissions));
621 | }
622 | return;
623 | }
624 | if (grantResults.length < permissions.length) {
625 | return;
626 | }
627 | // permission to pass
628 | //通过的权限
629 | List granted = new ArrayList<>();
630 | // denied access
631 | //拒绝的权限
632 | List denied = new ArrayList<>();
633 | // rejected permissions that cannot be asked for
634 | //拒绝的且不能询问的权限
635 | List noask = new ArrayList<>();
636 | for (int i = 0; i < permissions.length; i++) {
637 | String perm = permissions[i];
638 | if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
639 | granted.add(perm);
640 | } else {
641 | denied.add(perm);
642 | // judgment cannot be questioned
643 | //判断不能被询问(未通化切不需要提示即为被禁止了)
644 | if (!shouldShowRequestPermissionRationale(perm)) {
645 | //保存被禁止的权限
646 | updateDismissState(perm, true);
647 | noask.add(perm);
648 | }
649 | }
650 | }
651 | //Do not process onpermissionsseparation when true
652 | //为true不处理onPermissionsDismiss
653 | boolean onPermissionsDismiss = false;
654 | // permission is forbidden to ask
655 | //有权限被禁止询问
656 | if (!noask.isEmpty()) {
657 | EasyPermissionLog.d("权限现在被禁止询问");
658 | onPermissionsDismiss = permissionResult.onDismissAsk(requestCode, noask,true);
659 | }
660 | // permission not passed
661 | //有权限未通过
662 | if (!onPermissionsDismiss && !denied.isEmpty()) {
663 | EasyPermissionLog.d("权限被拒绝");
664 | permissionResult.onPermissionsDismiss(requestCode, denied);
665 | }
666 | // all permissions passed
667 | // 所有权限都通过
668 | if (!granted.isEmpty() && granted.size() == permissions.length) {
669 | EasyPermissionLog.d("权限已通过");
670 | permissionResult.onPermissionsAccess(requestCode);
671 | }
672 | }
673 |
674 | /**
675 | * Handle permissions result callbacks from App-Settings
676 | * In the activity of need to access the callback rewrite onActivityResult calls to this function
677 | *
678 | * 处理从系统设置权限结果回调
679 | * 在需要权限回调的activity中重写onActivityResult调用此函数
680 | *
681 | * @param requestCode
682 | * @param resultCode
683 | * @param data
684 | */
685 | public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
686 | if (mCurrentEasyPermission == null || mCurrentEasyPermission.getResult() == null) {
687 | return;
688 | }
689 | if (mCurrentEasyPermission.getRequestCode() == requestCode) {
690 | //设置界面返回
691 | //Result from system setting
692 | if (mCurrentEasyPermission.hasPermission()) {
693 | //权限已通过
694 | //Permission approved
695 | mCurrentEasyPermission.onPermissionsAccess();
696 | } else {
697 | //从设置回来还是没给你权限
698 | //You still didn't get permission from Settings
699 | mCurrentEasyPermission.onPermissionsDismiss();
700 | }
701 | }
702 | }
703 |
704 |
705 | }
706 |
--------------------------------------------------------------------------------