Android SD Card Write Permission usando SAF (Storage Access Framework)

Después de muchos hallazgos sobre cómo escribir (y renombrar) un archivo en la tarjeta SD (Android 5 y superior), creo que la nueva SAF provista por Android requerirá permiso del usuario para escribir el archivo de la tarjeta SD.

He visto ES File Explorer en ES File Explorer que inicialmente requiere permiso de lectura y escritura de la siguiente manera como se muestra en las imágenes.

enter image description here

Cuadro 2

Después de seleccionar la tarjeta SD, se concede el permiso de escritura.

Así que de la misma manera traté de usar SAF, pero no pude cambiar el nombre de un archivo. Mi código:

@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(); } } 

Aún después de ejecutar el código obtengo el permiso de EAacces denegado.

Permitir que el usuario elija la “tarjeta SD” o incluso la raíz SAF “Almacenamiento interno” dan acceso a su aplicación al almacenamiento correspondiente, pero solo a través de la API SAF, no directamente a través del sistema de archivos. Por ejemplo, tu código podría traducirse a algo así como:

 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); } } 

En la versión más reciente de Android, el acceso a los datos fuera de su aplicación usando java.io.File está casi completamente obsoleto.