我尝试编写一个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
创建内容Uri有点天真。在日志中,我有以下警告(可能是由于使用上述朴素的Uri的DocumentFile.fromTreeUri()
引起的):
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)
当我首先手动测试此方案时,测试将运行,然后没有错误。我想是因为那时我的应用程序已经具有下载目录的权限。
我如何创建打算的结果意图,其中包括必要的许可。
如果要返回希望Uri
可以使用的DocumentFile
,则Uri
必须工作。它需要指向ContentProvider
:
DocumentsContract
将要调用的DocumentFile
API(或至少是测试所需的部分)关于权限...理想情况下,您的测试提供者不需要任何东西,只是为了简化事情。如果那不切实际,您可以尝试在addFlags()
上尝试使用Intent
来授予所需的内容(例如FLAG_GRANT_READ_URI_PERMISSION
),尽管我不知道在您的Espresso测试方案中该方法的效果如何。