Подтвердить что ты не робот

Разрешение записи на SD-карту Android SD с использованием SAF (Storage Access Framework)

После многих выводов о том, как писать (и переименовывать) файл на SD-карте (Android 5 и выше), я думаю, что новый SAF, предоставленный андроидом, должен будет получить разрешение от пользователя писать файл SD-карты.

Я видел в этом приложении File Manger Application ES File Explorer, который изначально требует разрешения на чтение и запись следующим образом, как показано на рисунках.

введите описание изображения здесь

Изображение 2

После выбора SD-карты предоставляется разрешение на запись.

Таким образом, я попытался использовать SAF, но не смог переименовать файл. Мой код:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rename = (Button) findViewById(R.id.rename);

    startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), 42);
}

@Override
public void onActivityResult(int requestCode,int resultCode,Intent resultData) {
    if (resultCode != RESULT_OK)
        return;
    Uri treeUri = resultData.getData();
    DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
    grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}

public void renameclick(View v) {
    File ff = new File("/storage/sdcard1/try1.jpg");
    try {
        ff.createNewFile();
    } catch (Exception e) {
        Log.d("error", "creating");
        e.printStackTrace();
    }
}

После запуска кода я получаю разрешение EAacces.

4b9b3361

Ответ 1

Позволяя пользователю выбрать "SD-карту" или даже "корень SAF внутреннего хранилища", вы получите доступ к вашему приложению к соответствующему хранилищу, но только через API SAF, а не напрямую через файловую систему. Например, код можно перевести на что-то вроде:

public void writeFile(DocumentFile pickedDir) {
    try {
        DocumentFile file = pickedDir.createFile("image/jpeg", "try2.jpg");
        OutputStream out = getContentResolver().openOutputStream(file.getUri());
        try {

            // write the image content

        } finally {
            out.close();
        }

    } catch (IOException e) {
        throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
    }
}

В последней версии Android доступ к данным за пределами вашего приложения с помощью java.io.File почти полностью не рекомендуется.