最近公司相机升级到AndroidQ 遇到无法存储SD卡,原来是Goole抛弃了原有的API(不是过时,是抛弃,导致之前的存储API不能用)查看Google API 进行了代码更换, 在在更换过程中遇到了比较多的坑,将部分关键代码记录下来,方便下次使用。
如果不使用外置可插拔SD卡的AndroidQ存储可以使用如下方法暂时不用 AndroidQ的存储方式
在AndroidManifest.xml 中添加android:requestLegacyExternalStorage="true"即可 如下
复制代码
1
2
3
4
5
6
7
8<application ......省略代码 android:requestLegacyExternalStorage="true" . <activity> .......... 省略代码 </activity> </application>
如果是AndroidQ上 可插拔SD卡请看下面的方法;
Android 获取SD卡名称的时候区分大小写,我们用getUUid获取的是SD卡的大写名称,而Android只识别SD的小写名称,不知道是不是Bug,此坑比较深,一定切记。
如下是存储图片的关键代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38public 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; }
如下是进行视频录像传路径的代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Log.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卡名称
复制代码
1
2
3
4
5
6
7
8public 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卡
复制代码
1
2
3
4
5
6
7
8private void initVolume() { final StorageVolume[] volumes = ReflectionUtils.getVolumeList(mStorageManager); mVolume = (volumes.length > VOLUME_SDCARD_INDEX) ? volumes[VOLUME_SDCARD_INDEX] : null; mPath = null; mRawpath = null; }
判断是否存在SD卡
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public 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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复