2.3.5 release
parent
2da7de0a60
commit
a8b9647c62
@ -0,0 +1,179 @@
|
||||
package com.rehome.zhdcoa.utils
|
||||
|
||||
|
||||
import android.content.Context
|
||||
import com.azhon.appupdate.base.BaseHttpDownloadManager
|
||||
import com.azhon.appupdate.base.bean.DownloadStatus
|
||||
import com.azhon.appupdate.config.Constant
|
||||
import com.azhon.appupdate.util.LogUtil
|
||||
import com.rehome.zhdcoa.R
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.URL
|
||||
import java.security.KeyStore
|
||||
import java.security.SecureRandom
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.HostnameVerifier
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLSocketFactory
|
||||
import javax.net.ssl.TrustManager
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
|
||||
/**
|
||||
* ProjectName: AppUpdate
|
||||
* PackageName: com.azhon.appupdate.manager
|
||||
* FileName: HttpDownloadManager
|
||||
* CreateDate: 2022/4/7 on 14:29
|
||||
* Desc:
|
||||
*
|
||||
* @author azhon
|
||||
*/
|
||||
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
class AppUpdateHttpDownloadManager(private val path: String,private val context: Context) : BaseHttpDownloadManager() {
|
||||
companion object {
|
||||
private const val TAG = "HttpDownloadManager"
|
||||
}
|
||||
|
||||
private var shutdown: Boolean = false
|
||||
|
||||
override fun download(apkUrl: String, apkName: String): Flow<DownloadStatus> {
|
||||
LogUtil.i("app","-------------apkUrl----------")
|
||||
LogUtil.i("app",apkUrl)
|
||||
trustAllHosts(apkUrl)
|
||||
shutdown = false
|
||||
File(path, apkName).let {
|
||||
if (it.exists()) it.delete()
|
||||
}
|
||||
return flow {
|
||||
emit(DownloadStatus.Start)
|
||||
connectToDownload(apkUrl, apkName, this)
|
||||
}.catch {
|
||||
emit(DownloadStatus.Error(it))
|
||||
}.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
private suspend fun connectToDownload(
|
||||
apkUrl: String, apkName: String, flow: FlowCollector<DownloadStatus>
|
||||
) {
|
||||
val con = URL(apkUrl).openConnection() as HttpURLConnection
|
||||
con.apply {
|
||||
requestMethod = "GET"
|
||||
readTimeout = Constant.HTTP_TIME_OUT
|
||||
connectTimeout = Constant.HTTP_TIME_OUT
|
||||
setRequestProperty("Accept-Encoding", "identity")
|
||||
}
|
||||
if (con.responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val inStream = con.inputStream
|
||||
val length = con.contentLength
|
||||
var len: Int
|
||||
var progress = 0
|
||||
val buffer = ByteArray(1024 * 2)
|
||||
val file = File(path, apkName)
|
||||
FileOutputStream(file).use { out ->
|
||||
while (inStream.read(buffer).also { len = it } != -1 && !shutdown) {
|
||||
out.write(buffer, 0, len)
|
||||
progress += len
|
||||
flow.emit(DownloadStatus.Downloading(length, progress))
|
||||
}
|
||||
out.flush()
|
||||
}
|
||||
inStream.close()
|
||||
if (shutdown) {
|
||||
flow.emit(DownloadStatus.Cancel)
|
||||
} else {
|
||||
flow.emit(DownloadStatus.Done(file))
|
||||
}
|
||||
} else if (con.responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| con.responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|
||||
) {
|
||||
con.disconnect()
|
||||
val locationUrl = con.getHeaderField("Location")
|
||||
LogUtil.d(
|
||||
TAG,
|
||||
"The current url is the redirect Url, the redirected url is $locationUrl"
|
||||
)
|
||||
connectToDownload(locationUrl, apkName, flow)
|
||||
} else {
|
||||
val e = SocketTimeoutException("Error: Http response code = ${con.responseCode}")
|
||||
flow.emit(DownloadStatus.Error(e))
|
||||
}
|
||||
con.disconnect()
|
||||
}
|
||||
|
||||
/**
|
||||
* fix https url (SSLHandshakeException) exception
|
||||
*/
|
||||
private fun trustAllHosts(url:String) {
|
||||
if (url.startsWith("https://219.131.195.3:7100") || url.startsWith("https://219.131.195.3:7011") || url.startsWith(
|
||||
"https://219.131.195.3:7081"
|
||||
) || url.startsWith("https://219.131.195.3:7082")
|
||||
) {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(getSSLSocketFactory(context))
|
||||
HttpsURLConnection.setDefaultHostnameVerifier { _, _ -> true }
|
||||
}else{
|
||||
val manager: TrustManager = object : X509TrustManager {
|
||||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
||||
return arrayOf()
|
||||
}
|
||||
|
||||
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
|
||||
LogUtil.d(TAG, "checkClientTrusted")
|
||||
}
|
||||
|
||||
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
|
||||
LogUtil.d(TAG, "checkServerTrusted")
|
||||
}
|
||||
}
|
||||
try {
|
||||
val sslContext = SSLContext.getInstance("TLS")
|
||||
sslContext.init(null, arrayOf(manager), SecureRandom())
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.socketFactory)
|
||||
} catch (e: Exception) {
|
||||
LogUtil.e(TAG, "trustAllHosts error: $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
shutdown = true
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
cancel()
|
||||
}
|
||||
|
||||
fun getSSLSocketFactory(context: Context): SSLSocketFactory? {
|
||||
try {
|
||||
val certificateFactory = CertificateFactory.getInstance("X.509")
|
||||
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
|
||||
keyStore.load(null)
|
||||
val certificateAlias = 0.toString()
|
||||
keyStore.setCertificateEntry(
|
||||
certificateAlias, certificateFactory.generateCertificate
|
||||
(context.resources.openRawResource(R.raw.domain))
|
||||
)
|
||||
val sslContext = SSLContext.getInstance("TLS")
|
||||
val trustManagerFactory =
|
||||
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
trustManagerFactory.init(keyStore)
|
||||
sslContext.init(
|
||||
null,
|
||||
trustManagerFactory.trustManagers,
|
||||
SecureRandom()
|
||||
)
|
||||
return sslContext.socketFactory
|
||||
} catch (ex: java.lang.Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue