在用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上下下来看,郭霖大神的《第二行代码》也有详细介绍。