安卓6.0以上常见权限处理

本文介绍了解决Android 2.3及以上版本中遇到的权限问题的方法,包括WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE等敏感权限的处理流程,并提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在用AS2.3后targetSDK自然就是25了,所以相应的,权限问题就来了
,今天老大叫我看别人家的广告平台,APPcoach,让我接了一下他的SDK ,然后各种报错,看了一下很多是权限问题,于是乎要来解决了。首先我看下我们的权限常规的在清单文件申明就好了,这几个(我用到的)申明了也没用:
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_PHONE_STATE,
别人也写过很多博客了,我就不多说啥了,直接上解决办法:
有一个类叫做ActivityCompat,他有个方法:

 private void checkMyPermission() {

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.READ_PHONE_STATE},
                    AppcoachConstants.WRITE_AND_READ_STORAGE_REQUEST_CODE);
        } else {

            mAppcoachsSdk.setCacheVideoModel(new int[]{Constants.VIDEO_SLOT/*, Constants.VIDEO_SLOT_SECOND*/});
//            mAppcoachsSdk.setCacheJsonModel(MainActivity.this);

        }
    }
接下来我们看下源码:
  public static void requestPermissions(final @NonNull Activity activity,
            final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode) {
        if (Build.VERSION.SDK_INT >= 23) {
            ActivityCompatApi23.requestPermissions(activity, permissions, requestCode);
        } else if (activity instanceof OnRequestPermissionsResultCallback) {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                @Override
                public void run() {
                    final int[] grantResults = new int[permissions.length];

                    PackageManager packageManager = activity.getPackageManager();
                    String packageName = activity.getPackageName();

                    final int permissionCount = permissions.length;
                    for (int i = 0; i < permissionCount; i++) {
                        grantResults[i] = packageManager.checkPermission(
                                permissions[i], packageName);
                    }

                    ((OnRequestPermissionsResultCallback) activity).onRequestPermissionsResult(
                            requestCode, permissions, grantResults);
                }
            });
        }
    }

要传三个参数,看他的源码很清楚的可以了解到他是先判断Build.VERSION.SDK_INT >= 23
如果是大于等于23说明我们要处理危险权限和运行时权限,如果小于就去主线程里开个线程去检查权限。我们继续往下跳:
public static void requestPermissions(Activity activity, String[] permissions,
int requestCode) {
if (activity instanceof RequestPermissionsRequestCodeValidator) {
((RequestPermissionsRequestCodeValidator) activity)
.validateRequestPermissionsRequestCode(requestCode);
}
activity.requestPermissions(permissions, requestCode);
}

   public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        if (mHasCurrentPermissionsRequest) {
            Log.w(TAG, "Can reqeust only one set of permissions at a time");
            // Dispatch the callback with empty arrays which means a cancellation.
            onRequestPermissionsResult(requestCode, new String[0], new int[0]);
            return;
        }
        Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
        startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
        mHasCurrentPermissionsRequest = true;
    }
```最后看到他是去startActivityForResult()了,相应的也有个回调接口,我们可以在回调里判断用户是否授权了:





<div class="se-preview-section-delimiter"></div>

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

    switch (requestCode) {

        case AppcoachConstants.WRITE_AND_READ_STORAGE_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mAppcoachsSdk.setCacheVideoModel(new int[]{Constants.VIDEO_SLOT/*, Constants.VIDEO_SLOT_SECOND*/});
            } else {
            }
            break;

        default:
            break;
    }

// if(requestCode == this.WRITE_EXTERNAL_STORAGE_REQUEST_CODE)
// mAppcoachsSdk.setCacheVideoModel(new int[]{Constants.VIDEO_SLOT, Constants.VIDEO_SLOT_SECOND});
}

Fragment中运行时权限要特殊处理,在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的 onRequestPermissionsResult
如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方 法,onRequestPermissionsResult不会回调回来,建议使用 getParentFragment().requestPermissions方法,这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment





<div class="se-preview-section-delimiter"></div>

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
List fragments = getChildFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment != null) {
fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}
}
}
“`以上就是我遇到的权限问题,至于其他的欢迎补充,当然现在也有好多的权限封装库了,可以去git上下下来看,郭霖大神的《第二行代码》也有详细介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值