это касается новой модели разрешений во время выполнения, введенных в Android Marshmallow при запросе разрешения Manifest.permission.WRITE_EXTERNAL_STORAGE
.
Короче говоря, то, что я испытываю, заключается в том, что если я запрашиваю (и позволяет пользователю) разрешение Manifest.permission.WRITE_EXTERNAL_STORAGE
, приложение не сможет читать и писать из внешнего каталога хранилища, пока я не уничтожу и не перезапущу приложение.
Это то, что я делаю/испытываю:
Мое приложение начинается с состояния, в котором:
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
Это значит, что у меня нет прав доступа к внешнему хранилищу.
Затем я запрашиваю разрешение Manifest.permission.WRITE_EXTERNAL_STORAGE так же, как Google объясняет
private void requestWriteExternalStoragePermission() {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(this)
.setTitle("Inform and request")
.setMessage("You need to enable permissions, bla bla bla")
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
})
.show();
} else {
ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
}
Как только пользователь разрешает разрешение, вызывается onRequestPermissionsResult
.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case RC_PERMISSION_WRITE_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && PackageManager.PERMISSION_GRANTED
// allowed
} else {
// denied
}
break;
}
}
}
Выполняется блок allowed
, подтверждающий, что пользователь предоставил разрешения.
Немедленно после этого, если я не уничтожу и не открою приложение снова, у меня все еще нет доступа к внешнему хранилищу. Более конкретно:
hasWriteExternalStoragePermission(); // returns true
Environment.getExternalStorageDirectory().canRead(); // RETURNS FALSE!!
Environment.getExternalStorageDirectory().canWrite(); // RETURNS FALSE!!
Итак, кажется, что среда выполнения Android думает, что у меня есть разрешения, но файловая система не...
Действительно, попытка доступа к Environment.getExternalStorageDirectory()
создает исключение:
android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:438)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
Если теперь уничтожить приложение и снова открыть его, поведение будет таким, каким оно есть, имея возможность читать и записывать во внешней папке хранилища.
Кто-нибудь испытывает это?
Я использую один официальный эмулятор с:
- Последний Android 6.0 (API 23) API 23, Rev 1.
- Эмулятор под управлением Intel X86 Atom System Image, API 23, Rev 1.
Я создаю приложение с помощью
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
}
...
}
Если кто-то подтвердит это, и я не единственный, я думаю, нам нужно будет открыть ошибку, но я надеюсь, что я делаю что-то неправильно, поскольку я думаю, что такая основная функция вряд ли будет ошибкой в SDK.