You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android/Kotlin应用连接Postman gRPC Mock Server遇TLS ALPN协商失败

Android/Kotlin gRPC客户端连接Postman Mock Server时TLS ALPN协商失败的解决办法

核心问题分析

你遇到的TLS ALPN negotiation failed with protocols: [h2]错误,本质是旧Android系统(尤其是API 24及以下)默认安全提供者不支持HTTP/2必需的ALPN协议扩展。虽然尝试了Google安全提供者更新,但存在三个关键问题:

  1. 同步调用ProviderInstaller.installIfNeeded无法保证安全提供者更新完成后再发起gRPC请求
  2. 依赖不完整,缺少安全提供者更新所需的核心库
  3. 在主线程调用阻塞式gRPC Stub,既可能触发ANR,也会干扰TLS协商流程

分步解决方案

1. 修正依赖配置

替换原有的play-services-basement依赖为完整的安全服务依赖:

dependencies {
    // 保留原有gRPC依赖
    implementation 'io.grpc:grpc-okhttp:1.51.1'
    implementation 'io.grpc:grpc-protobuf-lite:1.51.1'
    implementation 'io.grpc:grpc-stub:1.51.1'
    implementation 'org.apache.tomcat:annotations-api:6.0.53'
    
    // 替换为完整的安全服务依赖
    implementation 'com.google.android.gms:play-services-security:20.0.0'
}

2. 异步执行安全提供者更新

使用ProviderInstaller的异步回调API,确保更新完成后再发起gRPC请求:

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.book.BookServiceGrpc
import com.book.Index.GetBookRequest
import com.google.android.gms.security.ProviderInstaller
import io.grpc.okhttp.OkHttpChannelBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 异步安装安全提供者
        ProviderInstaller.installIfNeededAsync(this, object : ProviderInstaller.ProviderInstallListener {
            override fun onProviderInstalled() {
                // 更新完成后,在后台线程发起gRPC请求
                CoroutineScope(Dispatchers.IO).launch {
                    startGrpc()
                }
            }

            override fun onProviderInstallFailed(errorCode: Int, recoveryIntent: android.content.Intent?) {
                Log.e("MainActivity", "安全提供者更新失败,错误码:$errorCode")
                // 可在此处引导用户更新Google Play服务
            }
        })
    }

    private fun startGrpc() {
        try {
            val channel = OkHttpChannelBuilder
                .forAddress("g-95d43o92ollxvwmm7nx895731r4g9y.srv.pstmn.io", 443)
                .useTransportSecurity()
                .build()
            val stub = BookServiceGrpc.newBlockingStub(channel)
            val request = GetBookRequest.newBuilder().setIsbn(123).build()
            val result = stub.getBook(request)
            
            // 处理返回结果,需切回主线程更新UI
            CoroutineScope(Dispatchers.Main).launch {
                Log.d("MainActivity", "获取到书籍:${result.title}")
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e("MainActivity", "gRPC请求失败:${e.message}")
        }
    }
}

3. 备选方案(无Google Play服务环境)

若设备无法访问Google服务,可使用Conscrypt替代Google安全提供者:
添加依赖:

implementation 'org.conscrypt:conscrypt-android:2.5.2'

在应用启动时初始化:

import org.conscrypt.Conscrypt
import java.security.Security

// 在自定义Application类的onCreate方法中添加
Security.insertProviderAt(Conscrypt.newProvider(), 1)

额外排查点

  • 确保测试设备/模拟器安装了Google Play服务,且版本符合依赖要求(建议使用带Google APIs的模拟器镜像)
  • API 21-24系统必须依赖安全提供者更新才能支持ALPN;API 25及以上系统默认支持
  • 禁止在主线程执行任何网络操作,包括gRPC阻塞调用

内容的提问来源于stack exchange,提问作者Aniokrait

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:55:22