版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
Android Q最近公司相机升级到AndroidQ 存储SD卡,遇到了比较多的坑,将部分关键代码记录下来,方便下次使用。
Android 区分大小写 再使用 StorageVolume.java 的getUuid()方法只能得到大写,此坑比较深,已经帮你把坑填好。
如下是存储图片的关键代码 使用
public static boolean writeFile(ContentResolver contentResolver, String title, String path, byte[] data) {
FileOutputStream out = null;
try {
if (isSaveSDCard() && SDCard.instance().isWriteable()){
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM+"/Camera/"); //修改路径
Uri collection = MediaStore.Images.Media.getContentUri(SDCard.instance().getSdCardExternalVolumeName());
Uri item = contentResolver.insert(collection, values);//获取插入路径
Log.d("chencl_"," item insert Uri : " +item);
ParcelFileDescriptor pfd = contentResolver.openFileDescriptor(item, "rw", null);
if (pfd != null){
out = (FileOutputStream) contentResolver.openOutputStream(item);
if (out != null) {
out.write(data);
}
}
} else {
out = new FileOutputStream(path);
out.write(data);
}
} catch (Exception e) {
Log.e(TAG, "Failed to write data", e);
return false;
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
Log.e(TAG, "Failed to close file after write", e);
}
}
return true;
}
Log.v(TAG, "New video filename: " + path);
if (Storage.isSaveSDCard() && SDCard.instance().isWriteable()) {
mCurrentVideoValues.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM+"/Camera");
Uri collection = MediaStore.Video.Media.getContentUri(SDCard.instance().getSdCardExternalVolumeName());
Uri item = mContentResolver.insert(collection, mCurrentVideoValues);
try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(item, "rw", null)) {
ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.fromFd(pfd.getFd());//必须转化一下不然录像提示无次文件
mMediaRecorder.setOutputFile(parcelFileDescriptor.getFileDescriptor());
// Write data into the pending image.
} catch (IOException e) {
e.printStackTrace();
}
} else {
mMediaRecorder.setOutputFile(path);
}
获取SD卡名称
public String getSdCardExternalVolumeName() {
ArrayList<String> volumenames = new ArrayList<>( MediaStore.getExternalVolumeNames(mContext));
return (volumenames.size() > VOLUME_SDCARD_INDEX) ? volumenames.get(VOLUME_SDCARD_INDEX) : null;
}
private void initVolume() {
final StorageVolume[] volumes = ReflectionUtils.getVolumeList(mStorageManager);
mVolume = (volumes.length > VOLUME_SDCARD_INDEX) ?
volumes[VOLUME_SDCARD_INDEX] : null;
mPath = null;
mRawpath = null;
}
public static StorageVolume[] getVolumeList(StorageManager storageManager) {
StorageVolume[] result = null;
try {
Class storageManagerCls = Class.forName("android.os.storage.StorageManager");
Method getVolumeListMethod = storageManagerCls.getMethod("getVolumeList");
getVolumeListMethod.setAccessible(true);
result = (StorageVolume[]) getVolumeListMethod.invoke(storageManager);
} catch (Exception e) {
Log.e(TAG, "getVolumeList Exp:" + expToString(e));
return result;
}
if (DEBUG) {
Log.d(TAG, "getVolumeList result:" + result);
}
return result;
}