Android 6.0权限管理比较严格
1.关于相机权限的申请
//判断sdk版本
if (Build.VERSION.SDK_INT >= 23) {
//申请权限
} else {
//直接做该做的
}
权限申请
if (writeExternalStorage != PackageManager.PERMISSION_GRANTED || cameraPre !=
//注意在判断多个权限时不要写成==,我当时惊讶了,为什么拒绝权限还是grant
PackageManager.PERMISSION_GRANTED || VedioPre != PackageManager.PERMISSION_GRANTED ||
readExternalStorage != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.CAMERA,
//请求相机的权限不要忘了加上内存卡的权限.
Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
//录像的时候不要忘记添加录音权限
Manifest.permission.RECORD_AUDIO}, REQUEST_PRE_CODE);
} else {
//直接做该做的
}
回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//打印方法返回值,一目了然.
// Log.d("onRequestPermissi", requestCode + ":" + permissions.length + ":" + permissions[0] + "" + grantResults.length + ":" + grantResults[0]);
switch (requestCode) {
case REQUEST_PRE_CODE:
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED && grantResults[1] ==
PackageManager.PERMISSION_GRANTED && grantResults[2] ==
PackageManager.PERMISSION_GRANTED && grantResults[3] == PackageManager.PERMISSION_GRANTED) {
} else {
ToastUtils.showTextToast(ApplyActivity.this, "请打开相关权限");
finish();
}
break;
}
}
2.Android 7.0目录权限
我遇到的情况,使用相机拍照片是没有问题的,但是用相机录像的时候无法保存到本地目录,经过一番查找解决了,但是问题又来了,视频文件比较大,要用ffmpeg进行压缩,ffmpeg作为Linux系统下的可执行文件竟然不能写到本地.
https://developer.android.google.cn/about/versions/nougat/android-7.0-changes.html#sharing-files
把视频存到本地,方法和官网上的一样
先配置fileprovider
<provider
android:name=".view.MyProvider"
android:authorities="xx.xx.xx.view.MyProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" >
</meta-data>
</provider>
再新建 file_paths
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<!-- root-path 代替 file-path, extendfile-path,cache-path-->
<root-path path="" name="download" />
<root-path path="" name="file_bin" />
</paths>
</resources>
java代码
if (Build.VERSION.SDK_INT > 23) {
File imagePath = new File(ctx.getFilesDir(), "file_bin");
File newFile = new File(imagePath, filename);
if(!imagePath.exists()){
imagePath.mkdirs();
}
if (newFile.exists()) {
newFile.delete();
}
Uri contentUri = FileProvider.getUriForFile(ctx, "xx.xx.xx.view.MyProvider", newFile);
ctx.grantUriPermission(ctx.getPackageName(), contentUri,
//设置uri可读可写的权限
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
FileOutputStream outputStream = (FileOutputStream)
//这里准备好一个输出流,输出到磁盘
//这里如果是个文件openFileDescriptor(contentUri, "rw"),准备好一个文件,写到本地
ctx.getContentResolver().openOutputStream(contentUri, "rw");
copyRawFile(ctx, resId, outputStream, "0755", newFile.getAbsolutePath());
return newFile.getCanonicalPath();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
这方法能把视频写到本地,我按照这个思路同样吧ffmpeg写到了/storage/emulated/0/download下,结果大
失所望,报了一个异常:Premission Denied;我的思路是见山开山,见水搭桥,解决权限问题,结果碰了一鼻子灰.此
路不开我绕路来过,我从/sdcard/download来访问,结果还是Denied.这个时候我几乎绝望了,我回到原点
https://developer.android.google.cn/reference/android/support/v4/content/FileProvider.html结果
灵机一动,我把ffmpeg放在/data/data/xx(包名下) ,同时加上Runtime.getRuntime().exec("chmod 755 " + mFfmpegBin);
放在包名下这个也是不能直接放的,是没办法访问的,直接放是放不进去的,要<root-path path="" name="file_bin" />
完美解决.