Как создать Uri для содержимого для ACTION_OPEN_DOCUMENT_TREE - PullRequest
1 голос
/ 21 октября 2019

Я пытаюсь написать тест Android Instrumentation, где пользователь должен выбрать папку для сохранения некоторых файлов. Но я не знаю, как создать результат, необходимый для intending.

Следующий код - это то, что я придумал до сих пор.

val testUri = Uri.parse("content://com.android.providers.downloads.documents/tree/downloads")
val openDocumentTreeResult = 
    Intent(Intent.ACTION_OPEN_DOCUMENT_TREE, testUri)

openDocumentTreeResult.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION and Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

intending(hasAction(Intent.ACTION_OPEN_DOCUMENT_TREE))
    .respondWith(
        Instrumentation.ActivityResult(Activity.RESULT_OK, openDocumentTreeResult
     )
)

Конечно, использование Uri.parse для создания контента Ури немного наивен. В журналах у меня есть следующее предупреждение (вероятно, вызванное DocumentFile.fromTreeUri() с использованием вышеуказанного наивного Uri):

W/DocumentFile: Failed query: java.lang.SecurityException: 
Permission Denial: opening provider com.android.providers.downloads.DownloadStorageProvider from ProcessRecord{edb1c64 4157:xyz.com.abc/u0a87} (pid=4157, uid=10087) 
requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

и позже DocumentFile.createFile() завершается неудачно, давая мне нулевое значение. Соответствующий код:

val treeUri = intent.data
val pickedDir = DocumentFile.fromTreeUri(this, treeUri)
val target = pickedDir.createFile(mimetype, f.name)

Когда я сначала тестирую этот сценарий вручную, тест выполняется без ошибок. Я думаю, потому что тогда у моего приложения уже есть разрешение для каталога загрузок.

Как создать намерение результата для намерения, которое включает в себя необходимые разрешения.

1 Ответ

0 голосов
/ 03 ноября 2019

Если вы собираетесь вернуть Uri, который хотите, чтобы DocumentFile мог использовать, Uri должен работать. Необходимо указать ContentProvider, что:

  • Существует
  • Соответствует API DocumentsContract, который будет вызывать DocumentFile (или, по крайней мере, его части)что вам нужно для вашего теста)
  • Возвращает то, что вы хотите для своих тестов

С точки зрения разрешений ... в идеале, ваш поставщик тестов не требует никаких, просто для упрощения вопросов,Если это нецелесообразно, вы можете попробовать addFlags() на вашем Intent, чтобы предоставить то, что вам нужно (например, FLAG_GRANT_READ_URI_PERMISSION), хотя я не знаю, насколько хорошо это работает в вашем сценарии тестирования эспрессо.

...