Android 无法对 SD 卡进行写入和删除操作

Has*_*ter 2 java permissions android file-permissions storage-access-framework

我现在正在研究 ImageCompressor 应用程序。

我需要delete和write(更新)图像文件。在内部存储中完美运行,但 **SD​​ 卡无法让我访问删除和写入文件。

我的应用程序如何能够在 SD 卡writedelete(可移动存储)上执行和操作?

我已经完成了没有这个的整个项目,所以我必须找到一种方法。

更新:

我已经在研究和讨论这个问题。并了解我必须使用storage access framework但我是 SAF 的新手。

我使用了一个库来压缩需要File 而不是 Uri 的照片。为此,我Uri -> File使用Intent.ACTION_OPEN_DOCUMENT并从可移动存储中选择图像。

但是对于可移动存储,我无法从 uri 中找到 Image Real Path。

我不知道这是否正确。如果在 SAF 中有任何方法可以使用 uri 压缩我的图像,请告诉我。或如何从可移动存储照片的uri 获取图像真实路径。

更新代码 SAF:

//  -----------  Intent  -------------
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");

//  ------------  On Activity Result  --------------
Uri uri = data.getData();
try {
    ParcelFileDescriptor fileDescriptor = getContentResolver().openFileDescriptor(uri, "w");
    FileOutputStream fos = new FileOutputStream(fileDescriptor.getFileDescriptor());

    FileInputStream fis = new FileInputStream(getImageFilePath(uri));

    FileChannel source = fis.getChannel();
    FileChannel destination = fos.getChannel();
    destination.transferFrom(source, 0, source.size());

    fis.close();
    fos.close();
    fileDescriptor.close();
    Toast.makeText(this, "File save successfully.", Toast.LENGTH_SHORT).show();
}
Run Code Online (Sandbox Code Playgroud)

Uri 到文件路径,我在从媒体应用程序(如画廊、照片)中选择图像的地方完成了但是从 SD 卡中选择什么而不是MediaStore.Images.Media.DATA我不知道。代码:

private File getImageFilePath(Uri uri) throws IOException {
    String image_id = null, imagePath = null;

    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    if (cursor != null) {
        cursor.moveToFirst();
        image_id = cursor.getString(0);
        image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
        cursor.close();
    }
    cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
    if (cursor!=null) {
        cursor.moveToFirst();
        imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        cursor.close();
    }

    File file = new File(imagePath);
    return new Compressor(this).setQuality(50).compressToFile(file);
}
Run Code Online (Sandbox Code Playgroud)

gre*_*pps 5

如果您使用 File 和 FileOutputStream 类,可移动 SD 卡只能在现代 Android 设备上写入。

如果您很幸运,那么您使用的设备会getExternalFilesDirs()返回卡上的应用程序特定目录作为第二项,您仍然可以在其中写入。

对于其余部分,请改用Storage Access Framework。

首先让用户选择Intent.ACTION_OPEN_DOCUMENT_TREE带有Intent.ACTION_OPEN_DOCUMENT.