easypermissions为什么获取获取root权限失败败还是说有权限

Andorid6.0动态权限及开源项目EasyPermissions
Andorid在M之后 将原有权限进行了重新的设计 ,将权限分为两大块分别是NormalPermission 和Dangerous Permission 。不管是哪种权限都和M之前的系统一样 只要使用就需要在清单文件中进行注册。但是对于Dangerous Permission 这样做还远远不够 ,开发者必须要动态的在代码使用权限的地方进行申请,必须经过用户同意之后才可以使用相应的权限。官方文档给出的Dangerous Permission 如下所示:
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
申请方式主要是分为三步:
1、检查运行时权限
ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.READ_SMS)!= PackageManager.PERMISSION_GRANTED
检查是否有权限 如有则执行相应代码,没有则执行第二步 向用户申请权限
2、动态申请权限
ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, READ_SMS_CODE);
申请权限 最后申请的结果会在onRequestPermissionsResult 方法中处理即第三步
3、接受权限处理结果
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case READ_SMS_CODE: {
if (grantResults.length & 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//权限同意 TODO
//权限决绝 TODO
以上就是官方文档的处理方式,当然还有shouldShowRequestPermissionRationale方法,此方法是当用户第一次拒绝权限后 第二次在弹出 是 申请权限对话框又多一个选项:不在提示,当用户勾选了后 会返回true 这个时候需要给用户相应的申请权限解释。
按照这个方式去处理6.0的动态权限会觉得很繁琐 所以 EasyPermissions 开源框架 应运而生。
首先引入库
dependencies {
compile 'pub.devrel:easypermissions:0.2.1'
EasyPermission提供了一个接口 里面有两个方法需要开发者自己实现 即需要动态申请权限的页面实现此接口
public interface PermissionCallbacks extends
ActivityCompat.OnRequestPermissionsResultCallback {
void onPermissionsGranted(int requestCode, List perms); //权限同意
void onPermissionsDenied(int requestCode, List perms); //权限拒绝
此外还需要在本身的权限回调方法中将处理结果交由EasyPermission处理
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
@AfterPermissionGranted(CALL_PHONE)
public void requestCallPhonePermission() {
String[] perms = {Manifest.permission.CALL_PHONE};
if (EasyPermissions.hasPermissions(this.getContext(), perms)) {
EasyPermissions.requestPermissions(this, &xxx请求拨打电话权限!&, CALL_PHONE, perms);
此方法的方法名称随意起,hasPermissions是检查app是否已经拥有此权限 如有则执行相应代码,如没有则调用requestPermissions去申请权限 。权限申请的结果会回调到我们刚刚实现的那个接口中去处理。大家会看到 给这个方法加了注解@AfterPermissionGranted(CALL_PHONE)这个注解的代表的是 当申请的权限用户同意之后 在调用此方法其中参数CALL_PHONE代表的是request_code 。
但用户勾选不在提示弹框的时候 我们扔然需要给用户做出相应的解释。在onPermissionsDenied中处理权限拒绝后的逻辑 如下:
public void onPermissionsDenied(int requestCode, List perms) {
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this, &为了您能使用拨打电话功能,请开启打电话权限!&)
.setTitle(&提示&)
.setPositiveButton(&去设置&)
.setNegativeButton(&取消&, null)
.setRequestCode(CALL_PHONE)
这样就OK了 ,EasyPermissions框架就是将我们上面所讲的方式进行了二次封装,是我们的开发更加便捷和易懂。
最后附上EasyPermissions完整处理逻辑代码:
public class TestActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
private static final int CALL_PHONE = 0x01;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
TextView mTvCallPhone = (TextView) findViewById(R.id.tv_contacts);
mTvCallPhone.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
requestCallPhonePermission();
@AfterPermissionGranted(CALL_PHONE)
public void requestCallPhonePermission() {
String[] perms = {Manifest.permission.CALL_PHONE};
if (EasyPermissions.hasPermissions(this, perms)) {
EasyPermissions.requestPermissions(this, &xxx请求拨打电话权限!&, CALL_PHONE, perms);
public void onPermissionsGranted(int requestCode, List perms) {
//权限同意
public void onPermissionsDenied(int requestCode, List perms) {
//权限拒绝
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this, &为了您能使用电话功能,请开启打电话权限!&)
.setTitle(&提示&)
.setPositiveButton(&去设置&)
.setNegativeButton(&取消&, null)
.setRequestCode(CALL_PHONE)
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);1733人阅读
android(6)
这里推荐逻辑是,android6.0权限获取,单个获取,多个获取,拒绝后再次获取,记住拒绝后引导用户转到权限设置界面手动获取权限,是的,就是要这样获取权限。比如一个扫码功能,用户不小心拒绝了你就不能这样放弃权限不再获取了吗?
首先献上一个sample的例子,知道大家都喜欢看demo,扫码下载demo体验
Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,又新增了运行时权限动态检测,以下权限都需要在运行时判断:
身体传感器
使用goole官方提供的库(混淆时不需要额外keep):
compile 'pub.devrel:easypermissions:0.2.1'
这个库就几个类,不想引用库也可以直接把类复制到自己工程里,看图:
implements EasyPermissions.PermissionCallbacks
public void onPermissionsGranted(int requestCode, List&String& perms) {
public void onPermissionsDenied(int requestCode, List&String& perms) {
@AfterPermissionGranted(RC_CAMERA_PERM)
public void cameraTask() {
if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA)) {
Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show();
EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera),
RC_CAMERA_PERM, Manifest.permission.CAMERA);
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
1、第一次点击按钮打开相机,获取禁止
2、再次点击按钮打开相机
3、第二次获取禁止不再询问
4、再次点击按钮打开相机
5、引导进入权限手动设置
最后奉上demo源码
注:参考github googlesample
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15451次
排名:千里之外
原创:18篇
(1)(9)(6)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3a456bfd7045436a-ua98).
重新安装浏览器,或使用别的浏览器googlesamples之easypermissions使用
1.app/build.gradle
dependencies { compile 'pub.devrel:easypermissions:0.3.0'}
2. 在Activity / Fragment实现PermissionCallbacks,回调方法:
@Overridepublic void onPermissionsGranted(int requestCode, List&String& list) { // Some permissions have been granted // ... LogUtil.d("Some permissions have been granted=" + requestCode);}@Overridepublic void onPermissionsDenied(int requestCode, List&String& list) { // Some permissions have been denied // ... LogUtil.d("Some permissions have been denied=" + requestCode);}
3. 在需要使用到权限之前调用methodRequiresTwoPermission方法,如相机和发送短信:
@AfterPermissionGranted(1010)private void methodRequiresTwoPermission() { String[] perms = {Manifest.permission.CAMERA, SEND_SMS}; if (EasyPermissions.hasPermissions(this, perms)) { // Already have permission, do the thing // ... LogUtil.d("Already have permission, do the thing"); } else { // Do not have permissions, request them now LogUtil.d("Do not have permissions, request them now"); EasyPermissions.requestPermissions(this, "camera_and_send_sms", 1010, perms); }}
4.还是要授权回调:
@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);}
这样就over了。
/googlesamples/easypermissions ,点击底部「阅读原文」直达。
就在《》文章里,我对Android 6.0 运行权限做了个简单封装,但没有考虑到Fragment使用和勾上不再询问应该去setting,还一个问题,封装只是针对单个权限,推荐官方easypermissions库,来看看easypermissions是如何解决我未考虑的问题。
Fragment使用
直接提供了Fragment可以调用的方法:
@SuppressLint("NewApi")public static void requestPermissions(@NonNull Fragment fragment, @NonNull String rationale, @StringRes int positiveButton, @StringRes int negativeButton, int requestCode, @NonNull String... perms) { if (hasPermissions(fragment.getContext(), perms)) { notifyAlreadyHasPermissions(fragment, requestCode, perms); } if (shouldShowRationale(fragment, perms)) { RationaleDialogFragmentCompat .newInstance(positiveButton, negativeButton, rationale, requestCode, perms) .show(fragment.getChildFragmentManager(), DIALOG_TAG); } else { fragment.requestPermissions(perms, requestCode); }} 不再询问去setting
我在《》说当勾上“不再询问”,只能选择拒绝,再次进入,shouldShowRequestPermissionRationale方法始终false,当onPermissionsDenied方法回调时,肯定是都是拒绝,再根据shouldShowRequestPermissionRationale方法不就知道是否勾上了“不再询问”,我咋没有想到这点呢:
@Overridepublic void onPermissionsDenied(int requestCode, List&String& perms) { Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); // (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN." // This will display a dialog directing them to enable the permission in app settings. if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { new AppSettingsDialog.Builder(this).build().show(); }}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { // Do something after user returned from app settings screen, like showing a Toast. Toast.makeText(this, R.string.returned_from_app_settings_to_activity, Toast.LENGTH_SHORT) .show(); }}
EasyPermissions的somePermissionPermanentlyDenied方法,就是根据shouldShowRequestPermissionRationale方法判断是否勾上了“不再询问”。
public static boolean somePermissionPermanentlyDenied(@NonNull Activity activity, @NonNull List&String& deniedPermissions) { for (String deniedPermission : deniedPermissions) { if (permissionPermanentlyDenied(activity, deniedPermission)) { } }}public static boolean permissionPermanentlyDenied(@NonNull Activity activity, @NonNull String deniedPermission) { return !shouldShowRequestPermissionRationale(activity, deniedPermission);}
跳转setting代码:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);intent.setData(uri);// Start for result//noinspection NewApi The Builder constructor prevents thisstartForResult(intent); 封装只针对单个权限
我应该封装多个权限,多权限是个数组,如果只有一个元素,不就是单个权限嘛!
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点

我要回帖

更多关于 easypermissions demo 的文章

 

随机推荐