Android-6.0动态权限

参考:

Android6.0权限适配的那些坑

一、动态权限的场景:

API版本:targetSdkVersion>=23,即Android6.0以上。

相关activity类:

public class ContextWrapper extends Context {...}

public class ContextThemeWrapper extends ContextWrapper {...}

public class Activity extends ContextThemeWrapper{...}

public class SupportActivity extends Activity {...}

abstract class BaseFragmentActivityGingerbread extends SupportActivity {...}

abstract class BaseFragmentActivityHoneycomb extends BaseFragmentActivityGingerbread {...}

abstract class BaseFragmentActivityJB extends BaseFragmentActivityHoneycomb {...}

//已经实现了ActivityCompat.OnRequestPermissionsResultCallback接口
public class FragmentActivity extends BaseFragmentActivityJB implements
        ActivityCompat.OnRequestPermissionsResultCallback,
        ActivityCompatApi23.RequestPermissionsRequestCodeValidator {
        ...
}


public class AppCompatActivity extends FragmentActivity{...}

相关类:

public class ContextCompat {...}

public class ActivityCompat extends ContextCompat {

    public interface OnRequestPermissionsResultCallback {

        void onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults);

    }

    ...
}

二、主要方法

ContextCompat.checkSelfPermission

ContextCompat类中:检测某权限是否授权

返回PackageManager.PERMISSION_GRANTED(已授权)或者PackageManager.PERMISSION_DENIED(未授权)


public static int checkSelfPermission(Context context,String permission) {...}

ActivityCompat.requestPermissions

ActivityCompat类中:为应用程序申请权限,系统会弹出对话框,询问用户是否给予应用授权该权限,用户可以选择允许或拒绝。

方法参数为(context,需要申请的权限数组,自定义的请求码),系统会弹出一个申请权限的对话框。


public static void requestPermissions(Activity activity,String[] permissions,int requestCode) {...}

ActivityCompat.shouldShowRequestPermissionRationale

ActivityCompat类中:是否需要弹框向用户解释为什么需要申请这个权限。

如果返回true证明用户上次点击已经选了拒绝或者一直未授权,所以我们进行一些友好的提示,这里做的是进行进行提示并让用户跳转到设置将权限打开。

public static boolean shouldShowRequestPermissionRationale(Activity activity, String permission) {
      if (Build.VERSION.SDK_INT >= 23) {
            return ActivityCompatApi23.shouldShowRequestPermissionRationale(activity, permission);
        }
        return false;
}
    //api23以下不会弹框,M之前版本调用,永远返回false。

onRequestPermissionsResult

ActivityCompat 类中的接口的抽象方法:申请权限结果的回调方法

如果继承自activity则需要实现ActivityCompat.OnRequestPermissionsResultCallback接口。

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == PERMISSON_REQUESTCODE) {
           ...
        }
    }

三、权限和权限组

大家都知道,并不是所有的权限都需要动态申请,只是一些系统规定的危险权限,权限被分组了:

同一组的任何一个权限被授权了,其他权限也自动被授权。例如,一旦WRITE_CONTENTS被授权了,APP也有READ_CONTACTS和GET_ACCOUNTS了。

但是:某些手机厂商比如小米,对于权限组好像有自己的策略,在测试当中,我们发现,当给应用赋予了CALL_PHONE
权限后,并没有获得READ_PHONE_STATE权限,测试手机的系统是MIUI 8.6.7.14开发版

示例:


public class GetPerAct extends AppCompatActivity {


    private static final int REQUESTCODE = 1;
    private String permission = Manifest.permission.CALL_PHONE;
    private Intent intent;
    private Uri data;

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

        intent = new Intent(Intent.ACTION_CALL);
        data = Uri.parse("tel:" + "10010");
        intent.setData(data);
    }

    public void onClick(View v) {
        //检测到未授权
        if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {

            Log.e("GetPerAct", "未授权");
            //已拒绝过再次温馨提示
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {

                Log.e("GetPerAct", "弹窗:已拒绝过再次温馨提示");
                new AlertDialog.Builder(this)
                        .setMessage("app需要开启权限才能使用此功能")
                        .setPositiveButton("设置", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                intent.setData(Uri.parse("package:" + getPackageName()));
                                startActivity(intent);//打开手机setting授权的页面
                            }
                        })
                        .setNegativeButton("取消", null)
                        .create()
                        .show();

            } else {//是否同意授权
                Log.e("GetPerAct", "弹窗:是否同意授权");
                ActivityCompat.requestPermissions(this, new String[]{permission}, REQUESTCODE);
            }

        } else {//检测到已授权
            Log.e("GetPerAct", "已授权");

            startActivity(intent);
        }
    }


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

        if (requestCode == REQUESTCODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.e("GetPerAct", "授权的回调结果:成功");
                //选择允许
                startActivity(intent);
            } else {
                Log.e("GetPerAct", "授权的回调结果:失败");
                //选择禁止
            }
        }
    }


}

第一次进入APP,如果点击”权限”按钮会弹出如图:

这里写图片描述

如果选择:始终允许,再次点击”权限”按钮就会 : 拨打电话:
打印的所有log为:

        //第一次点击"权限",选择"始终允许",拨通电话
未授权

弹窗:是否同意授权

授权的回调结果:成功

如果选择:禁止,再次点击”权限”按钮就会 : 温馨提示:

这里写图片描述

点击”设置”:

这里写图片描述

此页面即可重新设置权限。

打印的所有log为:

        //第一次点击"权限",选择"禁止"
未授权

弹窗:是否同意授权

授权的回调结果:失败

        //再次点击"权限",即弹出温馨提示
未授权

弹窗:已拒绝过再次温馨提示

参考:

Android 6.0+ 运行时权限探索

备注:

(1)checkSelfPermission:检查是否拥有这个权限
(2)requestPermissions:请求权限,一般会弹出一个系统对话框,询问用户是否开启这个权限。
(3)shouldShowRequestPermissionRationale:Android原生系统中,如果第二次弹出权限申请的对话框,会出现“以后不再弹出”的提示框,如果用户勾选了,你再申请权限,则shouldShowRequestPermissionRationale返回true,意思是说要给用户一个 解释,告诉用户为什么要这个权限。
然而,在实际开发中,需要注意的是,很多手机对原生系统做了修改,比如小米,小米4的6.0的shouldShowRequestPermissionRationale 就一直返回false,而且在申请权限时,如果用户选择了拒绝,则不会再弹出对话框了。。。。 所以说这个地方有坑,我的解决方法是,在回调里面处理,如果用户拒绝了这个权限,则打开本应用信息界面,由用户自己手动开启这个权限。
(4)每个应用都有自己的权限管理界面,里面有本应用申请的权限以及各种状态,即使用户已经同意了你申请的权限,他也随时可以关闭。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值