如何解决有没有办法在 Android 11 上将图像保存到没有 SAF 的 U 盘? 我可以使用此代码在 Android 10 上的 U 盘上存储文件,但不能在 Android 11 上存储文件
我想将使用相机从我的应用程序中拍摄的图像直接保存到插入我手机的 USB 记忆棒中。有没有办法在不要求用户从 SAF 中选择目录的情况下做到这一点?我想使用范围存储,因为我的目标是 Android 11 及更高版本。
没有连接到设备的 SD 卡。
我可以使用此代码在 Android 10 上的 U 盘上存储文件,但不能在 Android 11 上存储文件
// I pass the image taken from the camera by parameter
private void legacyToUsb(File image){
File[] externalStorageVolumes = ContextCompat.getExternalFilesDirs(getApplicationContext(),null);
String path = null;
for (File externalDir : externalStorageVolumes) {
Log.d(TAG,"Found dir at : " + externalDir);
path = externalDir.getPath();
}
if (path == null) {
showToast("Failed to found mounted device");
return;
}
String fileName = mDateFormat.format(System.currentTimeMillis()) + ".jpg";
File destFile = new File(path,fileName);
showToast("Going to save data to " + destFile.getPath());
if (destFile == null)
showToast("Failed to open file");
FileOutputStream os;
String msg = "Successfully saved to " + destFile.getPath();
try{
byte[] imageData = getBytesFromFile(image);
os = new FileOutputStream(destFile);
os.write(imageData);
} catch (IOException e) {
e.printStackTrace();
msg = "Failed to save file : " + e.getMessage();
}
showToast(msg);
}
但是,在 Android 11 上不起作用(我无法在 U 盘中创建文件),因为 getExternalFilesDirs()
没有给我 USB otg 的路径。
ContextCompat.getExternalFilesDirs(<context>)
返回:
Android 10
Found dir at : /storage/emulated/10/Android/data/com.example.MyApp/files
Found dir at : /storage/4406-15E5/Android/data/com.example.MyApp/files //I'm using this one
Android 11
Found dir at : /storage/emulated/0/Android/data/com.example.MyApp/files
据我所知,范围存储消除了通过这些功能访问可移动存储的可能性。所以我正在尝试这种方式
private void scopedToUsb(File image){
ContentResolver resolver = getContentResolver();
String fileName = mDateFormat.format(System.currentTimeMillis());
ContentValues fileDetails = new ContentValues();
fileDetails.put(MediaStore.Images.Media.DISPLAY_NAME,fileName);
fileDetails.put(MediaStore.Images.Media.MIME_TYPE,"image/jpeg");
fileDetails.put(MediaStore.Images.Media.RELATIVE_PATH,Environment.DIRECTORY_PICTURES);
fileDetails.put(MediaStore.Images.Media.IS_PENDING,1);
Set<String> volumeNames = MediaStore.getExternalVolumeNames(getApplicationContext());
String storageVolume = null;
// Get the first volume found here,it returns the hex with which the usb stick is identified
// in my case 4406-15e5
for (String volumeName : volumeNames){
storageVolume = volumeName;
Log.d(TAG,"Found volumeName : "+ volumeName);
break;
}
// I have tried here MediaStore.VOLUME_EXTERNAL and MediaStore.VOLUME_EXTERNAL_PRIMARY
// They both point to the same directory not in the usb stick
Uri collection = MediaStore.Images.Media.getContentUri(storageVolume);
Uri imageUri = resolver.insert(collection,fileDetails);
if(imageUri == null) {
showToast("Failed to insert image row to ContentResolver");
return;
}
Log.d(TAG,"Inserted,going to create ouput stream");
OutputStream out = null;
try {
out = resolver.openOutputStream(imageUri);
Bitmap bm = BitmapFactory.decodeFile(image.getAbsolutePath());
bm.compress(Bitmap.CompressFormat.JPEG,100,out);
out.close();
} catch (IOException e) {
e.printStackTrace();
showToast("Failed to sqve picture to Usb");
return;
}
showToast("Successfully saved to " + collection.getPath());
}
但我在这一行收到一个异常
Uri imageUri = resolver.insert(collection,fileDetails);
例外
java.lang.IllegalStateException: Failed to create directory: /mnt/media_rw/4406-15E5/Pictures/.pending-1621349186-2021-05-11-16-46-26-671.jpg
at android.os.Parcel.createExceptionOrNull(Parcel.java:2384)
at android.os.Parcel.createException(Parcel.java:2360)
at android.os.Parcel.readException(Parcel.java:2343)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:549)
at android.content.ContentResolver.insert(ContentResolver.java:2177)
at android.content.ContentResolver.insert(ContentResolver.java:2138)
at com.example.MyApp.MainActivity.scopedToUsb(MainActivity.java:368)
at com.example.MyApp.MainActivity.saveToUsb(MainActivity.java:294)
at com.example.MyApp.MainActivity.access$000(MainActivity.java:72)
at com.example.MyApp.MainActivity$1.onImageSaved(MainActivity.java:273)
at androidx.camera.core.ImageCapture$2.onImageSaved(ImageCapture.java:844)
at androidx.camera.core.ImageSaver.lambda$postSuccess$1$ImageSaver(ImageSaver.java:308)
at androidx.camera.core.-$$Lambda$ImageSaver$29vxg6qyjKwPRXgWrIwgYVInWKE.run(Unknown Source:4)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
有可能吗?我是否缺少任何许可?我应该强制使用存储访问框架吗?谢谢
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。