Android Q (10) запрашивает разрешение на доступ ко всему хранилищу. Объем хранения
В приложениях Android 10, которым требуется доступ к хранилищу, необходимо запрашивать разрешение на конкретный путь. Но такие приложения, как проводник, могут запрашивать разрешение для корневого хранилища и получать разрешение на чтение / запись всего хранилища. Это то, что я пытаюсь.
В соответствии с Android мы должны использовать для этого "ACTION_OPEN_DOCUMENT_TREE". У меня проблема в том, что все кажется правильным, но разрешение, наконец, не предоставляется приложению.
private void askAndroid10Perm()
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
}
Здесь пользователь видит дерево файлов Android и с выделенным основным хранилищем нажимает в разрешении garant. "Это позволит - имя приложения - получить полный доступ ко всем файлам, которые в данный момент хранятся в этом месте, и к любому будущему содержимому, хранящемуся здесь"
Затем:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_OPEN_DOCUMENT_TREE:
if (resultCode == Activity.RESULT_OK) {
Uri treeUri = data.getData();
int takeFlags = data.getFlags();
takeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.i("TAG", "takePersistableUriPermission: " + treeUri);
this.getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
}
}
}
}
Журнал:
takePersistableUriPermission: content: //com.android.externalstorage.documents/tree/primary%3A
Тогда у приложения нет разрешения на доступ к root.
открыть не удалось: EACCES (В доступе отказано)
Проклятия у меня есть
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Приобретено пользователем.
5 ответов
В Android Q. Если вы даете разрешение, и оно предоставлено или не работает, перейдите в Manifest и добавьте
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true" //Add this Line
android:label="@string/app_name">
---------<Activity, Sevices or Recivers>----------
</application>
Вы должны добавить эту строку в свой AndroidManifest.xml
android:requestLegacyExternalStorage="true"
Проблема заключалась в том, что я использую объект File для доступа к файлам, но разрешение работает, только если мы используем объект DocumentFile для манипулирования файлами.
Решено с использованием DocumentFile вместо File.
Он имеет несколько отрицательных моментов для использования DocumentFile, таких как производительность, и то, что у вас нет доступа к библиотекам Apache Commons, например, но другого варианта нет.
добавьте это в свой файл манифеста в приложении, чтобы ваше приложение выглядело следующим образом:
<application
android:requestLegacyExternalStorage="true"
Это может быть проще с Simple Storage. Вы можете запросить полный доступ к хранилищу у пользователя:
class MainActivity : AppCompatActivity() {
private val storageHelper = SimpleStorageHelper(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnRequestStorageAccess.setOnClickListener {
storageHelper.requestStorageAccess()
}
storageHelper.onStorageAccessGranted = { requestCode, root ->
// do stuff
}
}
}
Работает на Android 10 и выше. Нет необходимости добавлять
android:requestLegacyExternalStorage="true"
в файл манифеста.