Запись на внешнее хранилище невозможна, если приложение не будет перезапущено после предоставления разрешения
Приложение не может выполнить запись во внешнее хранилище на Android 6.0 (я тестирую на эмуляторе), даже после того, как WRITE_EXTERNAL_STORAGE был предоставлен во время выполнения; если приложение не будет убито и перезапущено.
Фрагмент из AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
build.gradle
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
......
minSdkVersion 15
targetSdkVersion 23
}
Всякий раз, когда мне нужно записать во внешнее хранилище (для резервного копирования), я проверяю, есть ли у меня разрешение.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
getActivity().getBaseContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_RW_EXTERNAL_STORAGE);
mPendingAction = PendingAction.Backup;
} else {
BackupRestoreService.startBackup(getActivity().getBaseContext());
}
У меня также есть следующее
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.d("SettingsActivity", "grantResultsLength: " + grantResults.length);
if (requestCode == PERMISSION_REQUEST_RW_EXTERNAL_STORAGE) {
Log.d("SettingsActivity", "grantResultsLength: " + grantResults.length);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
switch (mPendingAction) {
case Backup:
BackupRestoreService.startBackup(getActivity().getBaseContext());
mPendingAction = PendingAction.None;
break;
case Restore:
break;
default:
}
} else {
Toast.makeText(getActivity(),
"Permission denied",
Toast.LENGTH_SHORT).show();
}
}
}
Когда разрешение предоставлено пользователем, следующий код
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), DIR_MY_PORTFOLIO);
if (!file.mkdirs())
Log.d("Backup", "Unable to create directories");
final String outputFilename = new SimpleDateFormat("'Backup'-yyyyMMdd-hhmmss'.mpb'", Locale.US).format(new Date());
File outputFile = new File(getBackupStorageDir(), outputFilename);
Log.d("Backup", "Can write to file: " + outputFile.canWrite());
Log.d("Backup", "File exists: " + outputFile.exists());
производит
in.whoopee.myportfolio D/Backup: Unable to create directories
in.whoopee.myportfolio D/Backup: Can write to file: false
in.whoopee.myportfolio D/Backup: File exists: false
in.whoopee.myportfolio W/System.err: java.io.FileNotFoundException: /storage/09FD-2F0C/Download/My Portfolio/Backup-20151011-051318.mpb: open failed: EACCES (Permission denied)
Если после предоставления разрешения приложение будет убито и перезапущено, все будет в порядке и файл резервной копии будет создан во внешнем хранилище.
Пожалуйста, подскажите, что я делаю не так.
2 ответа
Добавьте следующую строку в метод onRequestPermissionsResult() после успешной проверки разрешения.
android.os.Process.killProcess(android.os.Process.myPid());
Изменить: Проверьте, что вы установили целевую версию SDK равной 23. Если вы уже сделали это, и она не работает (или вы не хотите устанавливать ее на 23), чем вы можете пойти с этим решением (убивая процесс приложения),
Попробуйте эмулировать новое устройство (например, 6.0 x86_64 с API Google). У меня была точно такая же проблема, и я решил ее, запустив другой эмулятор.