feat(webview): 添加blob下载功能并完善存储权限处理
- 添加pendingBlobDownload状态管理blob下载请求 - 实现API 30+系统上MANAGE_EXTERNAL_STORAGE权限检查 - 添加blob数据解码和文件保存功能 - 集成下载完成事件分发机制 - 完善存储权限对话框中的状态清理逻辑 - 实现blob下载成功后的相册保存或文件打开操作
这个提交包含在:
父节点
aca0d009a8
当前提交
f0276bb440
@ -231,6 +231,8 @@ fun XWebViewView(
|
||||
var showImageSourceDialog by remember { mutableStateOf(false) }
|
||||
var showStoragePermissionDialog by remember { mutableStateOf(false) }
|
||||
val pendingUrlDownload = remember { mutableStateOf<Pair<String, String?>?>(null) }
|
||||
// blobdownload pending: (url, filename, base64Data)
|
||||
val pendingBlobDownload = remember { mutableStateOf<Triple<String, String, String>?>(null) }
|
||||
|
||||
val notificationPermissionLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
@ -304,6 +306,15 @@ fun XWebViewView(
|
||||
android.util.Log.e("XWV", "blobdownload: empty data")
|
||||
return@handler
|
||||
}
|
||||
// On API 30+, writing to public Downloads requires MANAGE_EXTERNAL_STORAGE.
|
||||
if (config.downloadDestination == FileDownloadDestination.PublicDownloads &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
|
||||
!FileSDK.isManageStorageGranted(context)
|
||||
) {
|
||||
pendingBlobDownload.value = Triple(url, filename, b64)
|
||||
showStoragePermissionDialog = true
|
||||
return@handler
|
||||
}
|
||||
android.util.Log.d("XWV", "blobdownload: filename=$filename, b64Len=${b64.length}, dest=${config.downloadDestination}")
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
runCatching {
|
||||
@ -402,6 +413,7 @@ fun XWebViewView(
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME) {
|
||||
val pd = pendingUrlDownload.value
|
||||
val pbd = pendingBlobDownload.value
|
||||
if (pd != null && FileSDK.isManageStorageGranted(context)) {
|
||||
val (url, filename) = pd
|
||||
pendingUrlDownload.value = null
|
||||
@ -436,6 +448,27 @@ fun XWebViewView(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pbd != null && FileSDK.isManageStorageGranted(context)) {
|
||||
val (url, filename, b64) = pbd
|
||||
pendingBlobDownload.value = null
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
runCatching {
|
||||
FileSDK.saveBlobDownload(context, b64, filename, config.downloadDestination)
|
||||
}.onSuccess { file ->
|
||||
android.util.Log.d("XWV", "blobdownload saved: ${file.absolutePath}, size=${file.length()}")
|
||||
val savedToGallery = runCatching { FileSDK.saveImageToGallery(context, file) }.getOrDefault(false)
|
||||
withContext(Dispatchers.Main) {
|
||||
dispatchDownloadEvent("__xwvDownloadDone", url, ",success:true")
|
||||
if (!savedToGallery) FileSDK.openFile(context, file)
|
||||
}
|
||||
}.onFailure { e ->
|
||||
android.util.Log.e("XWV", "blobdownload FAILED", e)
|
||||
withContext(Dispatchers.Main) {
|
||||
dispatchDownloadEvent("__xwvDownloadDone", url, ",success:false,error:'${e.message?.escapeJs()}'")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
@ -564,6 +597,7 @@ fun XWebViewView(
|
||||
onDismissRequest = {
|
||||
showStoragePermissionDialog = false
|
||||
pendingUrlDownload.value = null
|
||||
pendingBlobDownload.value = null
|
||||
},
|
||||
title = { Text("需要存储权限") },
|
||||
text = { Text("下载文件需要「所有文件访问权限」,请在设置中授权后将自动继续下载。") },
|
||||
@ -577,6 +611,7 @@ fun XWebViewView(
|
||||
TextButton(onClick = {
|
||||
showStoragePermissionDialog = false
|
||||
pendingUrlDownload.value = null
|
||||
pendingBlobDownload.value = null
|
||||
}) { Text("取消") }
|
||||
},
|
||||
)
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户