fix: 图片和语音改用 app OkHttp 4.12 下载(弃用系统 HttpURLConnection)

根因:HttpURLConnection 底层是系统内置的 com.android.okhttp 2.x
即使 Conscrypt 替换了 TLS provider,系统 OkHttp 的 ALPN/连接管理
仍是旧逻辑,阿里云 OSS 不接受。
改用 app 自带的 OkHttp 4.12.0(有完整 ALPN/HTTP2 支持)+ Conscrypt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-05-07 13:15:52 +09:30
parent bb489140f8
commit c653e5b78d

View File

@@ -517,19 +517,19 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
overlay.setOnTouchListener { _, event -> detector.onTouchEvent(event); true }
}
/** 异步加载图片到 ImageView使用系统 HttpURLConnection */
/** 异步加载图片到 ImageView使用 app OkHttp 4.12 + Conscrypt */
private fun loadImage(imageView: android.widget.ImageView, url: String) {
viewLifecycleOwner.lifecycleScope.launch {
try {
val bitmap = kotlinx.coroutines.withContext(kotlinx.coroutines.Dispatchers.IO) {
val conn = java.net.URL(url).openConnection() as java.net.HttpURLConnection
conn.connectTimeout = 10000
conn.readTimeout = 10000
conn.connect()
if (conn.responseCode == 200) {
conn.inputStream.use { android.graphics.BitmapFactory.decodeStream(it) }
val request = okhttp3.Request.Builder().url(url).build()
val response = downloadClient.newCall(request).execute()
if (response.isSuccessful) {
response.body?.byteStream()?.use {
android.graphics.BitmapFactory.decodeStream(it)
}
} else {
Timber.w("图片HTTP错误: ${conn.responseCode} $url")
Timber.w("图片HTTP错误: ${response.code} $url")
null
}
}
@@ -598,21 +598,27 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
}
}
/** 下载音频文件到缓存目录(使用系统 HttpURLConnection */
/** 用于下载 OSS 资源的 OkHttp 客户端(无拦截器,配合 Conscrypt TLS */
private val downloadClient by lazy {
okhttp3.OkHttpClient.Builder()
.connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
.build()
}
/** 下载音频文件到缓存目录(使用 app OkHttp 4.12 + Conscrypt */
private fun downloadToCache(url: String): java.io.File? {
return try {
val conn = java.net.URL(url).openConnection() as java.net.HttpURLConnection
conn.connectTimeout = 15000
conn.readTimeout = 15000
conn.connect()
if (conn.responseCode != 200) {
Timber.w("语音下载HTTP错误: ${conn.responseCode}")
val request = okhttp3.Request.Builder().url(url).build()
val response = downloadClient.newCall(request).execute()
if (!response.isSuccessful) {
Timber.w("语音下载HTTP错误: ${response.code}")
return null
}
// 写入缓存文件
val fileName = "voice_${url.hashCode()}.mp3"
val cacheFile = java.io.File(requireContext().cacheDir, fileName)
conn.inputStream.use { input ->
response.body?.byteStream()?.use { input ->
cacheFile.outputStream().use { output ->
input.copyTo(output)
}