美文网首页
Android权限申请与EasyPermission、RxPer

Android权限申请与EasyPermission、RxPer

作者: 周末不加班 | 来源:发表于2019-08-20 23:09 被阅读0次

国产系统问题

  • 目前测试的锤子手机,判断任何权限都返回"已允许", 只有开始调用时才弹出权限确认对话框,例如调用local()定位方法
private void local() {
    LocationManager mLocationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度
    criteria.setAltitudeRequired(false);//无海拔要求   criteria.setBearingRequired(false);//无方位要求
    criteria.setCostAllowed(true);//允许产生资费   criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗
    // 获取最佳服务对象
    String provider = mLocationManager.getBestProvider(criteria, true);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    mLocationManager.getLastKnownLocation(provider);//getLastKnownLocation(provider);
}

Android 权限请求

  • 判断相机权限是否已经授权
int permissionCheck = ContextCompat.checkSelfPermission(HomeActivity.this, Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED)
{
     // 以获得权限
}else if (permissionCheck == PackageManager.PERMISSION_DENIED)
{
    // 没有授权
}
  • 请求权限
ActivityCompat.requestPermissions(activity, new String{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
  • 重写onRequestPermissionsResult方法判断权限授予情况
    int requestCode :权限状态码
    String[] permissions:申请的权限组
    grantResults:权限状态码 0已经授权,-1未授权
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {
        case 1:
        {
            // 如果请求被取消了,那么结果数组就是空的
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 权限被授予
            } else {
                // 权限请求被拒绝了
            }
            break;
        }
      //case其它权限请求...
    }
}
  • 判断用户是否拒绝并选择不再提示
    关于shouldShowRequestPermissionRationale函数的一点儿注意事项:
    1. 一般放在onRequestPermissionsResult中,判断用户是否勾选了不再提醒,并提示打开系统设置
    2. 某个请求从未申请过时一直返回false;
    3. 第一次请求权限时,用户拒绝了,再次调用shouldShowRequestPermissionRationale(),则返回true;
    4. 第二次请求权限时,用户拒绝了,并选择了“不在询问”的选项时,再次调用shouldShowRequestPermissionRationale()时,返回false;
    5. 设备的系统设置中,禁止了应用获取这个权限的授权,则调用shouldShowRequestPermissionRationale(),返回false;
boolean permission = shouldShowRequestPermissionRationale(Manifest.permission.CAMERA);
if (permission) {
    //拒绝过
    //再次请求权限
    ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.CAMERA}, 1);
} else {
    //拒绝且不再询问
    //提示打开系统设置
}

EasyPermission

  • 安装: 二选一 使用androidx 库的使用第一个
dependencies {
    // AndroidX
    implementation 'pub.devrel:easypermissions:3.0.0'
 
    // Support Library
    implementation 'pub.devrel:easypermissions:2.0.1'
}
  • 判断相机、定位权限
private int RC_CAMERA_AND_LOCATION = 0;
private void methodRequiresTwoPermission()
{
    String[] perms = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION};
    if (EasyPermissions.hasPermissions(this, perms))
    {
        // 已经有权限
        local();
    } else {
        // 没有权限,现在请求他们
        //只有用户首次安装时拒绝了权限,才会在下次申请时弹出 "此app需要xxx权限"提示框
        EasyPermissions.requestPermissions(this, "此app需要获取xxx权限", RC_CAMERA_AND_LOCATION, perms);
    }
}
  • 更改对话框主题(可选)
EasyPermissions.requestPermissions(
    new PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, perms)
            .setRationale("此app需要获取xxx权限")
            .setPositiveButtonText("确定")
            .setNegativeButtonText("取消")
            .setTheme(R.style.Theme_AppCompat_Dialog)//主题
            .build());//第一次拒绝后 再次申请提示用户
  • 实现EasyPermissions.RationaleCallbacks接口 监听对话框确定、取消(可选)
@Override
public void onRationaleAccepted(int requestCode) {
    // 确定授权
}

@Override
public void onRationaleDenied(int requestCode) {
    // 取消
}
  • 实现EasyPermissions.PermissionCallbacks 监听权限获取
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

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

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

        // 将结果转发给EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> list) {
        // 已授予某些权限
        // ...
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> list) {
        // 某些权限已被拒绝
        // ...
    }
}
  • 检查用户是否拒绝任何权限并选中“不再询问“ 并跳转系统设置(可选)
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) 
{
    // (可选)检查用户是否拒绝任何权限并选中“不再询问“
    // 这将显示一个对话框,指示用户在应用程序设置中启用权限
    if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
        new AppSettingsDialog.Builder(this).build().show();
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
        // 用户从应用设置屏幕返回后执行某些操作, 例如再次检查权限
    }
}

RxPermissions

  • 安装 依赖rxjava
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
  implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
  implementation "io.reactivex.rxjava2:rxjava:2.2.11"
}
  • 初始化 this:Activity或Fragment实例
final  RxPermissions rxPermissions =  new  RxPermissions(this);
  • request 授权方式
    多个权限必须全部允许 否则为拒绝
rxPermissions
    .request(Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_FINE_LOCATION)
    .subscribe(granted -> {
        if (granted) { 
            // 已获得所有权限
        } else {
            // 部分或所有权限被拒绝
        }
    });
  • requestEach 授权方式
    //申请了多少个权限就回调多少次
    //这种方式可以跟踪具体哪个权限被允许和拒绝
rxPermissions
    .requestEach(Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_FINE_LOCATION)
    .subscribe(permission -> {
        if (permission.granted)
        {
            // permission.name 权限被授予
        } else if (permission.shouldShowRequestPermissionRationale) {
            // permission.name 权限拒绝许可
        } else {
            // permission.name权限拒绝并不再提醒
            // 需要进入设置
        }
    });
  • requestEachCombined 授权方式
    // 与request类似
    // 多个权限只回调一次
    // 只有全部都允许才返回授予所有权限,
    //全部禁止或部分允许会返回禁止权限,实际上部分允许的权限已被打开
rxPermissions
    .requestEachCombined(Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_FINE_LOCATION)
    .subscribe(permission -> {
        if (permission.granted)
        {
            // 授予所有权限
        } else if (permission.shouldShowRequestPermissionRationale)
        {
            // 至少有一个权限被拒绝
        } else{
            // 至少有一个被拒绝的请求再也没有问过
            // 需要进入设置
        }
    });

相关文章

网友评论

      本文标题:Android权限申请与EasyPermission、RxPer

      本文链接:https://www.haomeiwen.com/subject/wujesctx.html