fix(webview): 修复 Office 文件选择后无响应问题
ContentResolver.getType() 对 doc/docx/xls/xlsx 等 Office 文件经常 返回 "application/octet-stream" 而非精确 MIME 类型,导致 allowed 检查失败、文件被拒绝、H5 无响应。 修复:rawMime 为 null 或 application/octet-stream 时,从文件显示名 的扩展名推断精确 MIME(getMimeTypeFromExtension),使 .docx 能正确 匹配 accept 约束并进入缓存复制流程。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
efb9721ddf
当前提交
7b66fcf333
@ -448,14 +448,28 @@ fun XWebViewView(
|
||||
// Validate that the selected file's actual MIME type is within the accepted list.
|
||||
// Some devices show extra file types in the picker (e.g. .doc when only .docx was
|
||||
// requested). Passing an unsupported type to the WebView renderer can cause a native
|
||||
// crash. We accept the file only when its MIME type matches, or fall back to passing
|
||||
// it through when we can't determine the type (to avoid blocking legitimate uploads).
|
||||
// crash.
|
||||
val acceptedMimes = pendingAcceptMimes.value
|
||||
val actualMime = context.contentResolver.getType(uri)
|
||||
// ContentResolver returns "application/octet-stream" (or null) for most Office files
|
||||
// from file-system / Downloads providers. Fall back to extension-based inference so
|
||||
// .docx / .doc / .xls etc. are not incorrectly rejected.
|
||||
val rawMime = context.contentResolver.getType(uri)
|
||||
val actualMime: String? = if (rawMime == null || rawMime == "application/octet-stream") {
|
||||
val name = context.contentResolver.query(
|
||||
uri, arrayOf(OpenableColumns.DISPLAY_NAME), null, null, null
|
||||
)?.use { cursor -> if (cursor.moveToFirst()) cursor.getString(0) else null }
|
||||
val extMime = name?.substringAfterLast('.', "")
|
||||
?.lowercase(Locale.ROOT)
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.let { ext -> MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) }
|
||||
extMime ?: rawMime
|
||||
} else rawMime
|
||||
val allowed = acceptedMimes.isNullOrEmpty() ||
|
||||
acceptedMimes.any { accepted ->
|
||||
accepted == "*/*" ||
|
||||
(actualMime != null && (actualMime == accepted || actualMime.startsWith(accepted.substringBefore("*"))))
|
||||
actualMime == null || // truly unknown type — don't block
|
||||
actualMime == accepted ||
|
||||
actualMime.startsWith(accepted.substringBefore("*"))
|
||||
}
|
||||
if (!allowed) {
|
||||
android.util.Log.w("XWV", "Rejected file: actualMime=$actualMime not in accepted=$acceptedMimes")
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户