相机相关的问题,大部分都是权限的问题
- 开发相机相关的功能的时候,出现了许许多多的问题。有点的会报错,有点不报错也没反应,很多情况下不是代码写的有问题,大部分情况可能只是权限申请的问题。
1.打开相机报错
SecurityException revoked permission android.permission.CAMERA
- 这个错误比较明显可以看出来是权限申请问题,这个就是高版本android需要动态申请权限。
- 有的说在AndroidManifest文件添加权限会导致报错,我这里情况是不会,主要还是需要动态申请.
/**
* 获取相关权限
*/
private boolean askPermission() {
boolean result = false;
if (Build.VERSION.SDK_INT >= 23) {
String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
for (String permission : permissions) {
int checkCallPhonePermission = ContextCompat.checkSelfPermission(getActivityContext(), permission);
if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivityContext(), new String[]{permission}, 0);
result = true;
}
}
}
return result;
}
- 我这里没有去监听权限回调,如果没有权限直接不进入接下来的逻辑,每次使用功能判断一下,比较简单无脑。
2.使用MediaMetadataRetriever的setDataSource方法抛出IllegalArgumentException异常
/**
* 获取视频关键帧
*
* @param filePath
* @param kind
* @return
*/
public static Bitmap createVideoThumbnail(String filePath, int kind) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
if (filePath.startsWith("http://")
|| filePath.startsWith("https://")
|| filePath.startsWith("widevine://")) {
retriever.setDataSource(filePath, new Hashtable<String, String>());
} else {
retriever.setDataSource(filePath);
}
bitmap = retriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (RuntimeException ex) {
ex.printStackTrace();
} finally {
try {
retriever.release();
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (bitmap == null) {
return null;
}
if (kind == MediaStore.Images.Thumbnails.MINI_KIND) {//压缩图片 开始处
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int max = Math.max(width, height);
if (max > 512) {
float scale = 512f / max;
int w = Math.round(scale * width);
int h = Math.round(scale * height);
bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
}//压缩图片 结束处
} else if (kind == MediaStore.Images.Thumbnails.MICRO_KIND) {
bitmap = ThumbnailUtils.extractThumbnail(bitmap,
96,
96,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
}
return bitmap;
}
android:requestLegacyExternalStorage="true"
- 经过实验哈,上面这句不加也没问题啊,还是权限申请的问题。
3.获取视频路径总是为null
case CODE_VIDEO_GALLERY_REQUEST://视频库返回
if (data.getData() != null) { // 录像或者从视频库选择一个视频
Uri uriVideoGallery = data.getData(); // 获得已选择视频的路径对象
String realPathVideo = UriUtils.getPath(getActivityContext(), uriVideoGallery);
if (realPathVideo == null) return;
videoFile = new File(realPathVideo);
//保存关键帧图片
try {
ImageView imageView = currentView.findViewById(R.id.img_pic);
setImageToVideo(imageView, createVideoThumbnail(realPathVideo, 1));
} catch (Exception e) {
e.printStackTrace();
}
}
break;
/**
* 从Uri获取文件路径,存储路径需要获取
* android.permission.READ_EXTERNAL_STORAGE权限
* 适用于MediaStore和其他基于文件的内容提供
*
* @param context 上下文对象
* @param uri Uri
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static String getPath(Context context, Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
- 上面代码是用来获取获取视频的Uri类型中的文件路径,应为需要操作文件上传啥的。但是每次都是null,然后解决上面问题的时候,添加了动态权限,自然而然的就好了。
- 所以还是动态权限的锅...
动态权限,害人不浅,你罪大恶极啊。