После Android 4.4 Kitkat, а с 2017 года доля Android 4.4 и ниже составляет около 20% и уменьшается, сохранение на SD-карту невозможно, используя класс File
и метод getExternalStorageDirectory()
. Этот метод возвращает внутреннюю память устройства и сохраненные изображения, видимые для каждого приложения. Вы также можете сохранять изображения только для вашего приложения и удалять, когда пользователь удаляет ваше приложение методом openFileOutput()
.
Начиная с Android 6.0, вы можете отформатировать свою SD-карту как внутреннюю память, но только для своего устройства. (Если вы отформатируете SD-автомобиль как внутреннюю память, только ваше устройство может получить доступ к его содержимому или просмотреть его). SD-карта использует другие ответы, но если вы хотите использовать съемную SD-карту, прочитайте мой ответ ниже.
Вы должны использовать Storage Access Framework , чтобы получить uri к папке onActivityResult
метод действия, чтобы получить папку, выбранную пользователем, и добавить извлекаемое постоянное разрешение, чтобы иметь возможность доступа к папке после того, как пользователь перезапустит устройство.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// selectDirectory() invoked
if (requestCode == REQUEST_FOLDER_ACCESS) {
if (data.getData() != null) {
Uri treeUri = data.getData();
tvSAF.setText("Dir: " + data.getData().toString());
currentFolder = treeUri.toString();
saveCurrentFolderToPrefs();
// grantUriPermission(getPackageName(), treeUri,
// Intent.FLAG_GRANT_READ_URI_PERMISSION |
// Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
}
}
}
}
Теперь сохраните папку сохранения в общих настройках, чтобы не просить пользователя выбирать папку каждый раз, когда вы хотите сохранить изображение.
Вы должны использовать DocumentFile
класс для сохранения вашего изображения, а не File
или ParcelFileDescriptor
, для получения дополнительной информации вы можете проверить этот поток для сохранения изображения на SD-карту с помощью метода compress(CompressFormat.JPEG, 100, out);
и DocumentFile
классы.