Skip to content

Commit

Permalink
fix update
Browse files Browse the repository at this point in the history
  • Loading branch information
lizongying committed May 7, 2024
1 parent fc83def commit 0286d11
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 50 deletions.
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## 更新日志

### v1.9.6(通用)

* 优化在线升级
* 优化可能状态错误的问题

### v1.9.4(通用)

* 修复默认时间不显示问题
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

<application
android:name=".MyTvApplication"
Expand Down Expand Up @@ -63,5 +64,14 @@
android:exported="false" />

<meta-data android:name="android.max_aspect" android:value="2.5" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
14 changes: 8 additions & 6 deletions app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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(
"确定"
Expand All @@ -27,10 +28,11 @@ class ConfirmationFragment(
listener.onCancel()
}
} else {
builder.setNegativeButton(
"好的"
) { _, _ ->
}
builder.setMessage("")
.setNegativeButton(
"好的"
) { _, _ ->
}
}
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/lizongying/mytv/SettingFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
110 changes: 83 additions & 27 deletions app/src/main/java/com/lizongying/mytv/UpdateManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,7 +29,6 @@ import java.io.File

class UpdateManager(
private var context: Context,
private var settingFragment: SettingFragment,
private var versionCode: Long
) :
ConfirmationFragment.ConfirmationListener {
Expand All @@ -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
) {
Expand All @@ -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")
Expand Down Expand Up @@ -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!")
}
}
}

Expand Down
21 changes: 20 additions & 1 deletion app/src/main/java/com/lizongying/mytv/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 时间戳
Expand All @@ -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()
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/com/lizongying/mytv/api/ApiClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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/"
}
}
12 changes: 0 additions & 12 deletions app/src/main/java/com/lizongying/mytv/api/ReleaseService.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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<ReleaseResponse>
}
3 changes: 3 additions & 0 deletions app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version_code": 17368064, "version_name": "v1.9.4"}
{"version_code": 17368576, "version_name": "v1.9.6"}

0 comments on commit 0286d11

Please sign in to comment.