国产系统问题
- 目前测试的锤子手机,判断任何权限都返回"已允许", 只有开始调用时才弹出权限确认对话框,例如调用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函数的一点儿注意事项:
- 一般放在onRequestPermissionsResult中,判断用户是否勾选了不再提醒,并提示打开系统设置
- 某个请求从未申请过时一直返回false;
- 第一次请求权限时,用户拒绝了,再次调用shouldShowRequestPermissionRationale(),则返回true;
- 第二次请求权限时,用户拒绝了,并选择了“不在询问”的选项时,再次调用shouldShowRequestPermissionRationale()时,返回false;
- 设备的系统设置中,禁止了应用获取这个权限的授权,则调用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
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{
// 至少有一个被拒绝的请求再也没有问过
// 需要进入设置
}
});
网友评论