Сохранение изображения после получения папки из пользовательского интерфейса Storage Access Framework

Я установил предпочтение пользователям выбирать папку сохранения для моего приложения с помощью Storage Access Framework. После получения URI onActivityResult Я сохраняю это SharedPreferences в виде строки и сохранить изображение, когда оно будет сохранено.

Я использую этот метод для успешного сохранения изображения.

public void saveImageWithDocumentFile(String uriString, String mimeType, String name) {
    isImageSaved = false;
    try {
        Uri uri = Uri.parse(uriString);
        DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri);
        DocumentFile file = pickedDir.createFile(mimeType, name);
        OutputStream out = getContentResolver().openOutputStream(file.getUri());
        isImageSaved = mBitmap.compress(CompressFormat.JPEG, 100, out);
        out.close();

    } catch (IOException e) {
        throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
    }
    Toast.makeText(MainActivity.this, "Image saved  " + isImageSaved, Toast.LENGTH_SHORT).show();
}

Если пользователь удаляет папку, выбранную с помощью SAF, iget null DocumentFile file и приложение вылетает. Мой первый вопрос: как я могу проверить, существует ли папка, не открывая SAF ui снова.

Я также хочу использовать ParcelFileDescriptor, чтобы сохранить то же изображение с этим методом

public void saveImageWithParcelFileDescriptor(String folder, String name) {
    if (mBitmap == null) {
        Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT).show();
        return;
    }
    String image = folder + File.separator + name + ".jpg";
    Toast.makeText(MainActivity.this, "image " + image, Toast.LENGTH_LONG).show();

    Uri uri = Uri.parse(image);
    ParcelFileDescriptor pfd = null;
    FileOutputStream fileOutputStream = null;
    try {
        pfd = getContentResolver().openFileDescriptor(uri, "w");
        fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
        mBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (pfd != null) {
            try {
                pfd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (fileOutputStream != null) {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    Toast.makeText(MainActivity.this, "Image saved  " + isImageSaved, Toast.LENGTH_SHORT).show();

}

я получил java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/612E-B7BF%3Aname/imagePFD.jpg онлайнpfd = getContentResolver().openFileDescriptor(uri, "w");

Вот как я называю этот метод, currentFolder - это папка, которую я получаю, используя намерение и ту же папку в первом методе.

saveImageWithParcelFileDescriptor(currentFolder, "imagePFD");

Как я могу это исправить, и какой метод является более предпочтительным и почему?

1 ответ

Решение

как я могу проверить, существует ли папка

DocumentFile имеет exists() метод. Теоретически, pickedDir.exists() должен сказать вам, если он существует. На практике это зависит от поставщика услуг хранения.

Я также хочу использовать ParcelFileDescriptor, чтобы сохранить то же изображение с этим методом

Этот код имеет ошибки:

  • Вы не можете предоставить себе разрешения, используя grantUriPermission()

  • Вы не можете изобрести произвольное Uri значения через конкатенацию, особенно для провайдера, который не является вашим

Как я могу это исправить

Удали это.

какой метод является более предпочтительным

Первый.

и почему?

Первый будет работать, возможно, с незначительной корректировкой. У второго нет шансов на работу.

Другие вопросы по тегам