概述
最近公司相机升级到AndroidQ 遇到无法存储SD卡,原来是Goole抛弃了原有的API(不是过时,是抛弃,导致之前的存储API不能用)查看Google API 进行了代码更换, 在在更换过程中遇到了比较多的坑,将部分关键代码记录下来,方便下次使用。
如果不使用外置可插拔SD卡的AndroidQ存储可以使用如下方法暂时不用 AndroidQ的存储方式
在AndroidManifest.xml 中添加android:requestLegacyExternalStorage="true"即可 如下
<application
......省略代码
android:requestLegacyExternalStorage="true"
.
<activity>
.......... 省略代码
</activity>
</application>
如果是AndroidQ上 可插拔SD卡请看下面的方法;
Android 获取SD卡名称的时候区分大小写,我们用getUUid获取的是SD卡的大写名称,而Android只识别SD的小写名称,不知道是不是Bug,此坑比较深,一定切记。
如下是存储图片的关键代码
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;
}
获取SD卡的 Volume VOLUME_SDCARD_INDEX =1 为可插拔SD卡 VOLUME_SDCARD_INDEX =0 为内置SD卡
private void initVolume() {
final StorageVolume[] volumes = ReflectionUtils.getVolumeList(mStorageManager);
mVolume = (volumes.length > VOLUME_SDCARD_INDEX) ?
volumes[VOLUME_SDCARD_INDEX] : null;
mPath = null;
mRawpath = null;
}
判断是否存在SD卡
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;
}
最后
以上就是凶狠老鼠为你收集整理的Android Q存储SD卡-Android29 存储外置SD卡的全部内容,希望文章能够帮你解决Android Q存储SD卡-Android29 存储外置SD卡所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复