web-dev-qa-db-fra.com

Android Autorisation d'écriture de carte SD à l'aide de SAF (Storage Access Framework)

Après de nombreuses découvertes sur la façon d'écrire (et de renommer) un fichier sur la carte SD (Android 5 et supérieur), je pense que le nouveau SAF fourni par Android devra demander la permission de l'utilisateur pour écrire le fichier de la carte SD.

J'ai vu dans cette application File Manger ES File Explorer qu'au départ, il faut l'autorisation de lecture et d'écriture de la manière suivante, comme indiqué dans les images.

enter image description here

Picture 2

Après avoir sélectionné la carte SD, l'autorisation d'écriture est accordée.

Donc, de la même manière, j'ai essayé d'utiliser SAF, mais j'ai échoué à renommer un fichier. Mon code:

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

Toujours après avoir exécuté le code, l'autorisation EAacces est refusée.

18

Laisser l'utilisateur choisir la "carte SD" ou même la racine SAF "Stockage interne" permet à votre application d'accéder au stockage correspondant, mais uniquement via l'API SAF, pas directement via le système de fichiers. Par exemple, votre code pourrait être traduit en quelque chose comme:

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

Dans la version récente d'Android, accéder aux données en dehors de votre application en utilisant Java.io.File est presque complètement obsolète.

21
bwt