Разрешение записи SD-карты Android с использованием SAF (Storage Access Framework)
После многих выводов о том, как записать (и переименовать) файл на SD-карту (android 5 и выше), я думаю, что новый SAF, предоставленный android, должен будет получить разрешение пользователя на запись файла SD-карты.
В этом приложении File Manger ES File Explorer я видел, что изначально он получает права на чтение и запись следующим образом, как показано на рисунках.
После выбора 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.
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
почти полностью устарела.