From 0286d118edb4eb75f0fde3de0f48be18982901d4 Mon Sep 17 00:00:00 2001 From: Li ZongYing Date: Tue, 7 May 2024 17:55:08 +0800 Subject: [PATCH] fix update --- HISTORY.md | 5 + app/src/main/AndroidManifest.xml | 10 ++ .../lizongying/mytv/ConfirmationFragment.kt | 14 ++- .../com/lizongying/mytv/SettingFragment.kt | 2 +- .../java/com/lizongying/mytv/UpdateManager.kt | 110 +++++++++++++----- .../main/java/com/lizongying/mytv/Utils.kt | 21 +++- .../java/com/lizongying/mytv/api/ApiClient.kt | 3 +- .../com/lizongying/mytv/api/ReleaseService.kt | 12 -- .../mytv/requests/ReleaseService.kt | 2 +- app/src/main/res/xml/file_paths.xml | 3 + version.json | 2 +- 11 files changed, 134 insertions(+), 50 deletions(-) delete mode 100644 app/src/main/java/com/lizongying/mytv/api/ReleaseService.kt create mode 100644 app/src/main/res/xml/file_paths.xml diff --git a/HISTORY.md b/HISTORY.md index a65205c5..00f1e18c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ ## 更新日志 +### v1.9.6(通用) + +* 优化在线升级 +* 优化可能状态错误的问题 + ### v1.9.4(通用) * 修复默认时间不显示问题 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3914f7d6..f8ede284 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt b/app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt index ec249a79..5d929e53 100644 --- a/app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt @@ -7,14 +7,15 @@ import androidx.fragment.app.DialogFragment class ConfirmationFragment( private val listener: ConfirmationListener, - private val message: String + private val message: String, + private val update: Boolean ) : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = AlertDialog.Builder(it) builder.setTitle(message) - if (message != "版本获取失败") { + if (update) { builder.setMessage("确定更新吗?") .setPositiveButton( "确定" @@ -27,10 +28,11 @@ class ConfirmationFragment( listener.onCancel() } } else { - builder.setNegativeButton( - "好的" - ) { _, _ -> - } + builder.setMessage("") + .setNegativeButton( + "好的" + ) { _, _ -> + } } builder.create() } ?: throw IllegalStateException("Activity cannot be null") diff --git a/app/src/main/java/com/lizongying/mytv/SettingFragment.kt b/app/src/main/java/com/lizongying/mytv/SettingFragment.kt index bdd94d9b..612c6d2c 100644 --- a/app/src/main/java/com/lizongying/mytv/SettingFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/SettingFragment.kt @@ -87,7 +87,7 @@ class SettingFragment : DialogFragment() { } } - updateManager = UpdateManager(context, this, context.appVersionCode) + updateManager = UpdateManager(context, context.appVersionCode) binding.checkVersion.setOnClickListener( OnClickListenerCheckVersion( activity as MainActivity, diff --git a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt index 4d51d4dd..5cb4aa8d 100644 --- a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt +++ b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt @@ -17,6 +17,7 @@ import android.util.Log import androidx.core.app.ActivityCompat import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.checkSelfPermission +import androidx.fragment.app.FragmentActivity import com.lizongying.mytv.api.ApiClient import com.lizongying.mytv.requests.ReleaseRequest import com.lizongying.mytv.requests.ReleaseResponse @@ -28,7 +29,6 @@ import java.io.File class UpdateManager( private var context: Context, - private var settingFragment: SettingFragment, private var versionCode: Long ) : ConfirmationFragment.ConfirmationListener { @@ -44,30 +44,32 @@ class UpdateManager( } CoroutineScope(Dispatchers.Main).launch { var text = "版本获取失败" + var update = false try { release = releaseRequest.getRelease() Log.i(TAG, "versionCode $versionCode ${release?.version_code}") if (release?.version_code != null) { - text = if (release?.version_code!! >= versionCode) { - "最新版本:${release?.version_name}}" + if (release?.version_code!! > versionCode) { + text = "最新版本:${release?.version_name}" + update = true } else { - "已是最新版本,不需要更新" + text = "已是最新版本,不需要更新" } } } catch (e: Exception) { Log.e(TAG, "Error occurred: ${e.message}", e) } - updateUI(text) + updateUI(text, update) } } - private fun updateUI(text: String) { - val dialog = ConfirmationFragment(this@UpdateManager, text) - settingFragment.fragmentManager?.let { dialog.show(it, TAG) } + private fun updateUI(text: String, update: Boolean) { + val dialog = ConfirmationFragment(this@UpdateManager, text, update) + dialog.show((context as FragmentActivity).supportFragmentManager, TAG) } private fun haveStoragePermission(): Boolean { - if (Build.VERSION.SDK_INT >= 23) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) === PermissionChecker.PERMISSION_GRANTED ) { @@ -90,23 +92,31 @@ class UpdateManager( private fun startDownload(release: ReleaseResponse) { - val apkFileName = "my-tv-${release.version_name}.apk" + val packageInstaller = context.packageManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (!packageInstaller.canRequestPackageInstalls()) { + } + } + + val apkName = "my-tv" + val apkFileName = "$apkName-${release.version_name}.apk" Log.i(TAG, "apkFileName $apkFileName") val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val request = - Request(Uri.parse("${ApiClient.HOST}/release/download/${release.version_name}/my-tv-${release.version_name}.apk")) + Request(Uri.parse("${ApiClient.DOWNLOAD_HOST}${release.version_name}/$apkName-${release.version_name}.apk")) Log.i( TAG, - "url ${Uri.parse("${ApiClient.HOST}/release/download/${release.version_name}/my-tv-0-${release.version_name}.apk")}" + "url ${Uri.parse("${ApiClient.DOWNLOAD_HOST}${release.version_name}/$apkName-${release.version_name}.apk")}" ) context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.mkdirs() + Log.i(TAG, "save dir ${Environment.DIRECTORY_DOWNLOADS}") request.setDestinationInExternalFilesDir( context, Environment.DIRECTORY_DOWNLOADS, apkFileName ) - request.setTitle("${settingFragment.resources.getString(R.string.app_name)} ${release.version_name}") + request.setTitle("${context.resources.getString(R.string.app_name)} ${release.version_name}") request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) request.setAllowedOverRoaming(false) request.setMimeType("application/vnd.android.package-archive") @@ -184,27 +194,73 @@ class UpdateManager( override fun onReceive(context: Context, intent: Intent) { val reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) Log.i(TAG, "reference $reference") - val progress = intent.getIntExtra("progress", 0) - Log.i(TAG, "progress $progress") - // 检查是否是我们发起的下载 if (reference == downloadReference) { - // 下载完成,触发安装 - installNewVersion() + val downloadManager = + context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + val query = DownloadManager.Query().setFilterById(downloadReference) + val cursor = downloadManager.query(query) + if (cursor != null && cursor.moveToFirst()) { + val statusIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS) + if (statusIndex < 0) { + Log.i(TAG, "Download failure") + return + } + val status = cursor.getInt(statusIndex) + + val progressIndex = + cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR) + if (progressIndex < 0) { + Log.i(TAG, "Download failure") + return + } + val progress = cursor.getInt(progressIndex) + + val totalSizeIndex = + cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES) + val totalSize = cursor.getInt(totalSizeIndex) + + cursor.close() + + when (status) { + DownloadManager.STATUS_SUCCESSFUL -> { + installNewVersion() + } + + DownloadManager.STATUS_FAILED -> { + // Handle download failure + Log.i(TAG, "Download failure") + } + + else -> { + // Update UI with download progress + val percentage = progress * 100 / totalSize + Log.i(TAG, "Download progress: $percentage%") + } + } + } } } private fun installNewVersion() { - val installIntent = Intent(Intent.ACTION_VIEW) - val apkUri = Uri.fromFile( - File( - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), - apkFileName - ) + val apkFile = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), + apkFileName ) - installIntent.setDataAndType(apkUri, "application/vnd.android.package-archive") - installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(installIntent) + Log.i(TAG, "apkFile $apkFile") + + if (apkFile.exists()) { + val apkUri = Uri.parse("file://$apkFile") + Log.i(TAG, "apkUri $apkUri") + val installIntent = Intent(Intent.ACTION_VIEW).apply { + setDataAndType(apkUri, "application/vnd.android.package-archive") + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK) + } + + context.startActivity(installIntent) + } else { + Log.e(TAG, "APK file does not exist!") + } } } diff --git a/app/src/main/java/com/lizongying/mytv/Utils.kt b/app/src/main/java/com/lizongying/mytv/Utils.kt index 76126a31..467afe7d 100644 --- a/app/src/main/java/com/lizongying/mytv/Utils.kt +++ b/app/src/main/java/com/lizongying/mytv/Utils.kt @@ -2,12 +2,15 @@ package com.lizongying.mytv import android.content.res.Resources import android.os.Build +import android.util.Log import android.util.TypedValue import com.google.gson.Gson import com.lizongying.mytv.api.TimeResponse import com.lizongying.mytv.requests.Request import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import okhttp3.Interceptor +import okhttp3.Response import java.io.IOException import java.text.SimpleDateFormat import java.util.Date @@ -47,6 +50,20 @@ object Utils { } } + class RetryInterceptor(private val maxRetry: Int) : Interceptor { + @Throws(IOException::class) + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + var response = chain.proceed(request) + var tryCount = 0 + while (!response.isSuccessful && tryCount < maxRetry) { + tryCount++ + response = chain.proceed(request) + } + return response + } + } + /** * 从服务器获取时间戳 * @return Long 时间戳 @@ -55,7 +72,9 @@ object Utils { return withContext(Dispatchers.IO) { val client = okhttp3.OkHttpClient.Builder() .connectTimeout(500, java.util.concurrent.TimeUnit.MILLISECONDS) - .readTimeout(1, java.util.concurrent.TimeUnit.SECONDS).build() + .readTimeout(1, java.util.concurrent.TimeUnit.SECONDS) + .addInterceptor(RetryInterceptor(3)) + .build() val request = okhttp3.Request.Builder() .url("https://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp") .build() diff --git a/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt b/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt index f51178f1..19a52c00 100644 --- a/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt +++ b/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt @@ -173,6 +173,7 @@ class ApiClient { } companion object { - const val HOST = "https://gitee.com/lizongying/my-tv/" + const val HOST = "https://gitee.com/lizongying/my-tv/raw/" + const val DOWNLOAD_HOST = "https://gitee.com/lizongying/my-tv/releases/download/" } } \ No newline at end of file diff --git a/app/src/main/java/com/lizongying/mytv/api/ReleaseService.kt b/app/src/main/java/com/lizongying/mytv/api/ReleaseService.kt deleted file mode 100644 index 8870d48a..00000000 --- a/app/src/main/java/com/lizongying/mytv/api/ReleaseService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.lizongying.mytv.api - -import retrofit2.Call -import retrofit2.http.GET -import retrofit2.http.Path - -interface ReleaseService { - @GET("my-tv/v2/release/{name}") - fun getRelease( - @Path("name") date: String = "2", - ): Call -} \ No newline at end of file diff --git a/app/src/main/java/com/lizongying/mytv/requests/ReleaseService.kt b/app/src/main/java/com/lizongying/mytv/requests/ReleaseService.kt index 783c61d7..3af2a87d 100644 --- a/app/src/main/java/com/lizongying/mytv/requests/ReleaseService.kt +++ b/app/src/main/java/com/lizongying/mytv/requests/ReleaseService.kt @@ -4,7 +4,7 @@ import retrofit2.Call import retrofit2.http.GET interface ReleaseService { - @GET("/raw/JELLY_BEAN_MR1/version.json") + @GET("JELLY_BEAN_MR1/version.json") fun getRelease( ): Call } \ No newline at end of file diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml new file mode 100644 index 00000000..bb368b06 --- /dev/null +++ b/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,3 @@ + + + diff --git a/version.json b/version.json index 52075b08..39b93f82 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version_code": 17368064, "version_name": "v1.9.4"} +{"version_code": 17368576, "version_name": "v1.9.6"}