使用ImagePicker 加载选择本地视频文件报错(共3台机器:2台正常,1台报错):
RNThumbnailModule.java
public void get(String filePath, Promise promise) {
filePath = filePath.replace("file://","");
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(filePath);
Bitmap image = retriever.getFrameAtTime(1000000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/thumb";
try {
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
}
OutputStream fOut = null;
// String fileName = "thumb-" + UUID.randomUUID().toString() + ".jpeg";
String fileName = "thumb-" + UUID.randomUUID().toString() + ".jpeg";
File file = new File(fullPath, fileName);
file.createNewFile();
fOut = new FileOutputStream(file);
// 100 means no compression, the lower you go, the stronger the compression
image.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
// MediaStore.Images.Media.insertImage(reactContext.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
WritableMap map = Arguments.createMap();
map.putString("path", "file://" + fullPath + '/' + fileName);
map.putDouble("width", image.getWidth());
map.putDouble("height", image.getHeight());
promise.resolve(map);
} catch (Exception e) {
Log.e("E_RNThumnail_ERROR", e.getMessage());
promise.reject("E_RNThumnail_ERROR", e);
}
}
}
参考网上各种
最近在使用MediaMetadataRetriever的setDataSource方法时,老是抛出IllegalArgumentException异常,上网查了一番,发现出现这个异常的原因无非就是两大点:
1、文件路径不对
2、文件访问权限不够
结合这两点原因我排查了一下,发现确实是我的权限不够导致的,因为我测试时使用的Android 10.0的手机,虽然我已经动态申请了权限,但是Android10对权限的管理更加严格了,主要有以下两点:
1、权限按单个分配,不再按组分配,以前申请了读存储卡权限,即可获得同组的读写权限,现在需要逐个申请
2、存储卡读写权限需要在Application的Manifest清单中声明
Android10.0 需要在AndroidManifest.xml文件中application出加上 android:requestLegacyExternalStorage="true"
最后发现是机器不同,引起文件路径不对,
let file;
if (Platform.OS === 'android') {
file = response.uri
} else {
file = response.uri.replace('file://', '')
}
//获取视频的缩略图
if (file.indexOf('file:///') < 0) {
//组件返回的path就是真实路径
file = response.path;
if (file.indexOf('file') < 0) {
file = 'file://' + file;
}
}
let { path } = await RNThumbnail.get(file);
let video = this.state.video;
let videosThumbnail = this.state.videosThumbnail;
video.push(file);
videosThumbnail.push(path);
this.setState({
loading: true,
video: video,
videosThumbnail,
});
return this.state.imgs;