Android ConnectSDK加载LG TV应用图标失败:证书信任锚未找到
解决ConnectSDK控制LG TV时Glide加载应用图标证书验证失败问题
通过ConnectSDK成功连接LG WebOS TV,能正常控制设备、获取应用列表JSON,但使用Glide加载应用图标时抛出java.security.cert.CertPathValidatorException: Trust anchor for certification path not found,尝试配置WebOSTVTrustManager未生效。
核心原因
LG TV的应用图标URL是设备本地HTTPS地址,系统默认不信任其自签名证书。WebOSTVTrustManager仅作用于ConnectSDK与TV的内部通信,Glide的网络请求使用独立的网络栈,未复用该信任配置。
方案1:让Glide复用ConnectSDK的SSLSocketFactory
ConnectSDK的WebOSTVService已经持有信任TV证书的SSLSocketFactory,直接让Glide复用这个工厂即可:
- 创建自定义Glide Module(Glide v4+适用):
class TVGlideModule : AppGlideModule() { override fun registerComponents(context: Context, glide: Glide, registry: Registry) { // 替换为你全局持有的WebOSTVService实例 val webOSService: WebOSTVService? = yourGlobalWebOSServiceInstance webOSService?.let { service -> val sslSocketFactory = service.webOSTVServiceConfig.sslSocketFactory val trustManager = service.webOSTVServiceConfig.trustManager as X509TrustManager val client = OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustManager) .build() registry.replace(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(client)) } } }
- 在
AndroidManifest.xml中注册Module:
<meta-data android:name="com.your.package.TVGlideModule" android:value="GlideModule" />
- Compose中直接使用
GlideImage即可,Glide会自动应用配置:
GlideImage( model = test, contentDescription = "应用图标", modifier = Modifier .padding(10.dp) .size(100.dp), )
方案2:手动导入TV证书到应用信任存储
若无法获取ConnectSDK的SSLSocketFactory,可手动提取TV证书并添加到项目:
获取TV证书:
- 浏览器访问图标URL(如
https://[TV_IP]:3000/icon/xxx.png),导出证书为.cer格式; - 或从
webOSService.webOSTVServiceConfig.serverCertificate获取证书并保存为文件。
- 浏览器访问图标URL(如
将证书放入
res/raw目录,命名为lg_tv_cert.cer。创建自定义SSLContext:
fun getCustomSSLSocketFactory(context: Context): SSLSocketFactory { val certInputStream = context.resources.openRawResource(R.raw.lg_tv_cert) val certificateFactory = CertificateFactory.getInstance("X.509") val cert = certificateFactory.generateCertificate(certInputStream) as X509Certificate val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply { load(null, null) setCertificateEntry("lg_tv", cert) } val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply { init(keyStore) } return SSLContext.getInstance("TLS").apply { init(null, tmf.trustManagers, SecureRandom()) }.socketFactory }
- 同方案1,在Glide Module中配置该SSLSocketFactory即可。
方案3:临时禁用证书验证(仅开发测试用)
注意:此方法存在安全风险,禁止上线使用
fun getUnsafeOkHttpClient(): OkHttpClient { return try { val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf() }) val sslContext = SSLContext.getInstance("TLS").apply { init(null, trustAllCerts, SecureRandom()) } OkHttpClient.Builder() .sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager) .hostnameVerifier { _, _ -> true } .build() } catch (e: Exception) { throw RuntimeException(e) } }
配置Glide使用该OkHttpClient即可绕过证书验证。
内容的提问来源于stack exchange,提问作者Russell Sjoblom
相关产品推荐
相关产品推荐

