不下载直接打开文件报A resource failed to call close 华为Android11白屏如何解决
根因说明
你遇到的华为设备异常本质是华为ROM对ACTION_VIEW传入的非本地Content URI校验规则比三星更严格:直接传入远程HTTP/HTTPS URI时,接收Intent的第三方查看应用通常没有网络访问权限、也没有该远程URI的访问授权,无法正常拉取资源,导致资源流异常中断未调用close,就会输出你看到的W/System: A resource failed to call close警告,同时出现白屏加载的问题。
可行解决方案
- 优先修正MIME类型校验逻辑:你现有代码中定义了
detectedMime但未使用,且仅通过URL后缀判断MIME类型准确率极低,在线资源建议先请求一次资源接口的响应头,取Content-Type字段作为MIME值传入,华为ROM会拦截MIME类型和资源不匹配的Intent请求。 - 不要直接传入远程URI给
ACTION_VIEW:不想全量下载到公共目录的话,可以先将资源流写入应用自身的内部缓存目录生成临时文件,再通过FileProvider生成合规的Content URI传入Intent,示例修正代码如下:
// 先将远程资源写入缓存目录(可边下载边写入,不需要等全量下载完再打开) File cacheFile = new File(context.getCacheDir(), "temp_" + System.currentTimeMillis() + getFileSuffix(href)); // 此处省略将远程资源输入流写入cacheFile的逻辑 Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", cacheFile); Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addCategory(Intent.CATEGORY_DEFAULT); String mime = getContentTypeFromRemote(href); // 从资源响应头取正确MIME intent.setDataAndType(contentUri, mime); // 启动前先校验是否有可接收的应用 if (intent.resolveActivity(context.getPackageManager()) != null) { context.startActivity(intent); } else { // 无匹配应用时提示用户安装对应查看工具 }
- 增加Intent可用性校验:启动前先调用
resolveActivity判断是否有应用可以接收该Intent,避免华为ROM无匹配应用时直接显示白屏的问题。
权限说明
该场景不需要申请额外权限:
- 读写应用内部缓存目录不需要申请
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限 - targetSdk>=30时也不需要申请
MANAGE_EXTERNAL_STORAGE权限,不会引入额外的上架审核风险 - 仅需在Manifest中正确注册FileProvider即可
高适配性第三方文件查看库推荐
- TBS腾讯浏览服务:支持PDF、Word、Excel、PPT等绝大多数常见办公格式,不依赖用户安装第三方办公应用,对国内华为、小米等厂商的ROM适配做的比较完善,兼容性较高。
- AndroidPdfViewer:如果仅需要查看PDF格式,该库轻量无冗余依赖,本地渲染不需要调用系统应用,适配问题极少。
- 系统原生能力封装:如果不想引入第三方SDK,可以封装系统自带的
PdfRenderer处理PDF、WebView加载文本/图片类资源,适配性也有保障。
内容的提问来源于stack exchange,提问作者Slava
相关产品推荐
相关产品推荐

