Android 11下预安装PdfViewerActivity无法兼容自签名用户证书问题
首先明确:这不是你的应用配置问题,也算不上PdfViewerActivity的bug,核心原因是Android应用的沙盒隔离机制——你的network-security-config.xml只对自己的应用进程生效,而你调用的PdfViewerActivity属于Google Docs(com.google.android.apps.docs)这个独立应用,它的网络安全策略并没有包含信任用户添加的CA证书。
你的应用和Chrome能正常访问服务器,是因为:
- 你的app配置了信任用户CA;
- Chrome本身有自己的证书信任逻辑,会识别系统的用户凭据列表。
但Google Docs的PdfViewerActivity是独立进程,它的默认网络安全配置只会信任系统预装的CA,不会读取用户添加的CA,所以才会抛出CertPathValidatorException。
可行的解决方法
方法一:先下载PDF到本地,再打开本地文件
因为你的应用已经能正常和服务器交互,所以可以先把PDF文件下载到设备存储,再通过Intent打开本地文件,绕开PdfViewerActivity的远程HTTPS请求。
示例步骤:
- 用你已有的网络请求工具(OkHttp/HttpURLConnection)从服务器下载PDF文件到本地(比如外部存储的
getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)目录); - 用
FileProvider生成可共享的文件Uri(Android 7.0+必须用FileProvider,不能直接用Uri.fromFile); - 调用
ACTION_VIEW打开本地Uri:
File pdfFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "example.pdf"); Uri pdfUri = FileProvider.getUriForFile(this, "your.app.id.fileprovider", pdfFile); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(pdfUri, "application/pdf"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent);
方法二:在自己的应用内集成PDF查看库
放弃调用外部的PdfViewerActivity,改用开源的PDF查看库(比如AndroidPdfViewer)在自己的应用内加载远程PDF。这样整个网络请求都在你的应用进程内,会遵循你配置的network-security-config,自然能信任用户添加的CA证书。
方法三:(不推荐)将证书安装到系统凭据(需要Root)
如果把自签名证书安装到“受信任凭据/系统”列表,PdfViewerActivity会信任这个CA,但Android 11+下安装系统证书需要Root权限,普通用户无法操作,所以这个方案实用性极低。
你提到的《Trust Anchor not found for Android SSL Connection》不适用,是因为那个问题是针对应用自身进程内的网络请求,而你的场景是跨应用调用外部组件,属于完全不同的情况。
内容的提问来源于stack exchange,提问作者Tina Zh

