diff --git a/HISTORY.md b/HISTORY.md
index b8e4ea6..8f947e1 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,261 +1,265 @@
-## 更新日志
+## 更新日誌
-### v2.0.9
+### v2.1.0
-* 修复部分设备闪退的问题
-* 修复设置页可能显示不全的问题
-
-### v2.0.5
-
-* 设置页增加恢复默认按钮,目前只用于同步系统时间
-
-### v2.0.4
-
-* 修复不能播放的问题
-* 包含国际频道
-
-### v2.0.3
-
-* 修复不能播放的问题
-* 不包含国际频道
-
-### v2.0.0
-
-* 解决卡顿问题
-* 解决网格样式时,点击空白处不退出的问题
-* 解决频道列表样式切换可能不生效的问题
-
-### v1.9.8(通用)
-
-* 优化在线升级
-* 优化可能状态错误的问题
-
-### v1.9.6(通用)
-
-* 优化在线升级
-* 优化可能状态错误的问题
-
-### v1.9.4(通用)
-
-* 修复默认时间不显示问题
-* 设置页居中
-* 频道号和时间对齐
-
-### v1.9.2(通用)
-
-* 修复一个重试的错误
-
-### v1.9.0(通用)
-
-* 减少视频播放失败情况
-* 全面屏手机居中显示
-
-### v1.8.8(通用)
-
-* 样式优化
-
-### v1.8.6(通用)
-
-* 增加错误显示
-* 节目预告优化
-* 频道列表页单击切换频道
-
-### v1.8.4(通用)
-
-* 解決部分情況下打開後黑屏问题
-* 延长频道信息显示时间,增加信息显示长度
-* 调整频道列表间距
-* 其他样式优化
-
-### v1.8.2(通用)
-
-* 修复无法播放问题
+* 恢復播放
### 以下已不可用
+### v2.0.9
+
+* 修復部分設備閃退的問題
+* 修復設置頁可能顯示不全的問題
+
+### v2.0.5
+
+* 設置頁增加恢復默認按鈕,目前只用於同步系統時間
+
+### v2.0.4
+
+* 修復不能播放的問題
+* 包含國際頻道
+
+### v2.0.3
+
+* 修復不能播放的問題
+* 不包含國際頻道
+
+### v2.0.0
+
+* 解決卡頓問題
+* 解決網格樣式時,點擊空白處不退出的問題
+* 解決頻道列表樣式切換可能不生效的問題
+
+### v1.9.8(通用)
+
+* 優化在線升級
+* 優化可能狀態錯誤的問題
+
+### v1.9.6(通用)
+
+* 優化在線升級
+* 優化可能狀態錯誤的問題
+
+### v1.9.4(通用)
+
+* 修復默認時間不顯示問題
+* 設置頁居中
+* 頻道號和時間對齊
+
+### v1.9.2(通用)
+
+* 修復一個重試的錯誤
+
+### v1.9.0(通用)
+
+* 減少視頻播放失敗情況
+* 全面屏手機居中顯示
+
+### v1.8.8(通用)
+
+* 樣式優化
+
+### v1.8.6(通用)
+
+* 增加錯誤顯示
+* 節目預告優化
+* 頻道列表頁單擊切換頻道
+
+### v1.8.4(通用)
+
+* 解決部分情況下打開後黑屏問題
+* 延長頻道信息顯示時間,增加信息顯示長度
+* 調整頻道列表間距
+* 其他樣式優化
+
+### v1.8.2(通用)
+
+* 修復無法播放問題
+
### v1.8.0(通用)
-* 修复返回键无法退出问题
-* 设置中增加退出按钮
-* 修改非电视上的样式
-* 修复低版本闪退问题
+* 修復返回鍵無法退出問題
+* 設置中增加退出按鈕
+* 修改非電視上的樣式
+* 修復低版本閃退問題
### v1.7.8(通用)
-* 修复播放过程中的卡顿问题
-* 增加时间显示
-* 频道号优化
-* 遥控器左键打开频道列表
-* 遥控器右键打开设置菜单
-* 频道列表空白处点击隐藏频道列表
+* 修復播放過程中的卡頓問題
+* 增加時間顯示
+* 頻道號優化
+* 遙控器左鍵打開頻道列表
+* 遙控器右鍵打開設置菜單
+* 頻道列表空白處點擊隱藏頻道列表
### v1.7.6(通用)
-* 临时去掉部分频道,提高频道的可用性
-* 部分频道增加节目单
+* 臨時去掉部分頻道,提高頻道的可用性
+* 部分頻道增加節目單
-### v1.7.5(安卓5及以上专用)
+### v1.7.5(安卓5及以上專用)
-* 修复播放过程中的卡顿问题
-* 增加时间显示
-* 频道号优化
-* 设置中增加退出按钮
+* 修復播放過程中的卡頓問題
+* 增加時間顯示
+* 頻道號優化
+* 設置中增加退出按鈕
### v1.7.4(通用)
-* 修复368
+* 修復368
-### v1.7.3(安卓5及以上专用)
+### v1.7.3(安卓5及以上專用)
-* 临时去掉部分频道,提高频道的可用性
-* 部分频道增加节目单
-* 遥控器左键进入节目列表
-* 遥控器右键进入菜单
+* 臨時去掉部分頻道,提高頻道的可用性
+* 部分頻道增加節目單
+* 遙控器左鍵進入節目列表
+* 遙控器右鍵進入菜單
### v1.7.2(通用)
-* 支持节目列表网格样式和行样式切换,软件重启后生效
-* 节目列表样式变更
+* 支持節目列表網格樣式和行樣式切換,軟件重啟後生效
+* 節目列表樣式變更
-### v1.7.1(安卓5及以上专用)
+### v1.7.1(安卓5及以上專用)
-* 解决设置页更新闪退的问题
-* 凤凰卫视回归
-* 解决368问题
+* 解決設置頁更新閃退的問題
+* 鳳凰衛視回歸
+* 解決368問題
### v1.7.0(通用)
-* 网络请求优化
+* 網絡請求優化
-### v1.6.9(安卓5及以上专用)
+### v1.6.9(安卓5及以上專用)
-* 去掉港澳台和国际频道
-* 解决部分情况下3、6、8等频道无法播放的问题
-* 解决部分情况下启动后黑屏问题
+* 去掉港澳台和國際頻道
+* 解決部分情況下3、6、8等頻道無法播放的問題
+* 解決部分情況下啟動後黑屏問題
### v1.6.8(通用)
-* 修复部分设备崩溃的问题
-* 修复部分设备凤凰卫视无法播放的问题
+* 修復部分設備崩潰的問題
+* 修復部分設備鳳凰衛視無法播放的問題
-### v1.6.7(安卓5及以上专用)
+### v1.6.7(安卓5及以上專用)
-* 手机双击打开配置
-* 自动更新
+* 手機雙擊打開配置
+* 自動更新
### v1.6.6(通用)
-* 更新重庆卫视图标
-* 凤凰卫视增强画质
-* 凤凰卫视增加EPG
+* 更新重慶衛視圖標
+* 鳳凰衛視增強畫質
+* 鳳凰衛視增加EPG
-### v1.6.5(安卓5及以上专用)
+### v1.6.5(安卓5及以上專用)
-* 增加CETV1图标
-* 稳定性提升
+* 增加CETV1圖標
+* 穩定性提升
### v1.6.4(通用)
* 增加CETV1
-* 增加凤凰卫视
-* 默认关闭开机启动
+* 增加鳳凰衛視
+* 默認關閉開機啟動
-### v1.6.3(安卓5及以上专用)
+### v1.6.3(安卓5及以上專用)
* 增加CETV1
-* 凤凰卫视增强画质
-* 默认关闭开机启动
-* 延迟菜单自动关闭时间
-* 解决一些可能导致首次打开时黑屏的问题
+* 鳳凰衛視增強畫質
+* 默認關閉開機啟動
+* 延遲菜單自動關閉時間
+* 解決一些可能導致首次打開時黑屏的問題
### v1.6.2(通用)
-* 修复按键无效的问题
-* 新的频道列表样式
+* 修復按鍵無效的問題
+* 新的頻道列表樣式
-### v1.6.1(安卓5及以上专用)
+### v1.6.1(安卓5及以上專用)
-* 增加凤凰卫视
+* 增加鳳凰衛視
### v1.6.0(通用)
* 通用(春晚緊急修復)
-### v1.5.9(安卓5及以上专用)
+### v1.5.9(安卓5及以上專用)
-* 解决天猫魔盒闪退问题
+* 解決天貓魔盒閃退問題
### v1.5.8(通用)
-* 修复央视6画质差的问题
-* 增加兵团卫视
-* 播放失败重试
+* 修復央視6畫質差的問題
+* 增加兵團衛視
+* 播放失敗重試
-### v1.5.7(安卓5及以上专用)
+### v1.5.7(安卓5及以上專用)
-* 修复播放失败的问题
+* 修復播放失敗的問題
### v1.5.6(通用)
-* 解决部分设备系统时间不对导致播放失败的问题
+* 解決部分設備系統時間不對導致播放失敗的問題
-### v1.5.5(安卓5及以上专用)
+### v1.5.5(安卓5及以上專用)
-* 修复播放失败的问题
-* 修复APP恢复后频道号、频道列表不自动消失的问题
+* 修復播放失敗的問題
+* 修復APP恢復後頻道號、頻道列表不自動消失的問題
### v1.5.4(通用)
-* 修复播放失败的问题
+* 修復播放失敗的問題
-### v1.5.3(安卓5及以上专用)
+### v1.5.3(安卓5及以上專用)
-* 修复部分情况下APP切换后无法继续播放的问题
-* 优化重试逻辑
+* 修復部分情況下APP切換後無法繼續播放的問題
+* 優化重試邏輯
### v1.5.2(通用)
-* 修复APP恢复后频道号、频道列表不自动消失的问题
+* 修復APP恢復後頻道號、頻道列表不自動消失的問題
-### v1.5.1(安卓5及以上专用)
+### v1.5.1(安卓5及以上專用)
-* 性能优化
+* 性能優化
### v1.5.0(通用)
-* 修复部分情况下APP切换后无法继续播放的问题
+* 修復部分情況下APP切換後無法繼續播放的問題
-### v1.4.9(安卓5及以上专用)
+### v1.4.9(安卓5及以上專用)
* 同步v1.4.8
### v1.4.8(通用)
-* 频道号从1开始,CCTV5+为18
+* 頻道號從1開始,CCTV5+為18
* 提高CCTV6清晰度
-* 增加天津卫视、新疆卫视
+* 增加天津衛視、新疆衛視
-### v1.4.7(安卓5及以上专用)
+### v1.4.7(安卓5及以上專用)
-* 修复部分用户CCTV13播放过程中卡住的问题
-* 调整CCTV的频道顺序
+* 修復部分用戶CCTV13播放過程中卡住的問題
+* 調整CCTV的頻道順序
### v1.4.6(通用)
-* 10以下频道不再需要先按0
+* 10以下頻道不再需要先按0
-### v1.4.5(安卓5及以上专用)
+### v1.4.5(安卓5及以上專用)
-* 数字选台配置
+* 數字選台配置
### v1.4.4(通用)
-* 优化图标显示
-* 增加换台反转
+* 優化圖標顯示
+* 增加換台反轉
-### v1.4.3(安卓5及以上专用)
+### v1.4.3(安卓5及以上專用)
-* 支持频道反转配置
+* 支持頻道反轉配置
### v1.4.2(通用)
@@ -263,40 +267,40 @@
### v1.4.1
-* 解决部分用户无法打开菜单的问题
+* 解決部分用戶無法打開菜單的問題
### v1.4.0
-* 解决极个别高版本机型黑屏问题
+* 解決極個別高版本機型黑屏問題
### v1.3.9
-* 提高稳定性
-* 提高连接速度
+* 提高穩定性
+* 提高連接速度
### v1.3.4
-* 部分错误会提示用户
-* 菜单3秒钟后自动关闭
+* 部分錯誤會提示用戶
+* 菜單3秒鐘後自動關閉
### v1.3.3
-* 部分错误会提示用户
-* 菜单3秒钟后自动关闭
+* 部分錯誤會提示用戶
+* 菜單3秒鐘後自動關閉
### v1.3.2
-* 增加重试,减少因网络问题导致的播放失败
-* 优化横幅banner
+* 增加重試,減少因網絡問題導致的播放失敗
+* 優化橫幅banner
### v1.3.1
-* 增加CCTV 8K 超高清频道
-* 增加国际频道栏目
+* 增加CCTV 8K 超高清頻道
+* 增加國際頻道欄目
### v1.3.0
-* 处理368可能失败的情形
+* 處理368可能失敗的情形
### v1.2.9
@@ -308,32 +312,32 @@
### v1.2.7
-* 此版本是为了测试安卓6.0以下版本,如之前可以正常运行,请勿安装。
+* 此版本是為了測試安卓6.0以下版本,如之前可以正常運行,請勿安裝。
### v1.2.6
* 支持安卓4.2
-* 解决部分频道无法播放的问题
-* 修复切换时有时没有恢复播放的问题
-* 左右键不再切换源
-* 增大频道信息标题尺寸,缩小与节目信息的间隔
+* 解決部分頻道無法播放的問題
+* 修復切換時有時沒有恢復播放的問題
+* 左右鍵不再切換源
+* 增大頻道信息標題尺寸,縮小與節目信息的間隔
### v1.2.5
-* 美化频道信息显示
-* 优化节目单获取
+* 美化頻道信息顯示
+* 優化節目單獲取
### v1.2.4
-* 改变换台滑动方向,上一个频道下滑,下一个频道上滑
-* 软件退出时,退出播放器
-* 播放相同的频道,不再重复加载
-* 暂时移除部分频道
+* 改變換台滑動方向,上一個頻道下滑,下一個頻道上滑
+* 軟件退出時,退出播放器
+* 播放相同的頻道,不再重複加載
+* 暫時移除部分頻道
### v1.2.3
-* 固定视频比列为16:9
-* 隐藏全面屏底部的小横条
-* 移除移动专区
-* 修复一个闪退问题
-* 更换图标和应用名
\ No newline at end of file
+* 固定視頻比例為16:9
+* 隱藏全面屏底部的小橫條
+* 移除移動專區
+* 修復一個閃退問題
+* 更換圖標和應用名
\ No newline at end of file
diff --git a/README.md b/README.md
index bab6570..d63c5f7 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,6 @@
* 亮度调节
* 音量调节
* 軟解
-* 网格空白处退出
## 版权说明
diff --git a/app/build.gradle b/app/build.gradle
index 7166c44..b0d116a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -26,6 +26,7 @@ android {
cmake {
arguments "-DIS_SO_BUILD=${project.hasProperty('IS_SO_BUILD') ? project.IS_SO_BUILD : true}"
+// abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
@@ -128,6 +129,7 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
+ implementation("androidx.work:work-runtime-ktx:2.9.0")
implementation 'androidx.core:core-ktx:1.11.0-beta02'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.leanback:leanback:1.2.0-alpha02'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2fe0464..3b862ee 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,6 +10,7 @@
+
diff --git a/app/src/main/cpp/arm64-v8a/libnative.so b/app/src/main/cpp/arm64-v8a/libnative.so
index 1ea0926..b1167ae 100755
Binary files a/app/src/main/cpp/arm64-v8a/libnative.so and b/app/src/main/cpp/arm64-v8a/libnative.so differ
diff --git a/app/src/main/cpp/armeabi-v7a/libnative.so b/app/src/main/cpp/armeabi-v7a/libnative.so
index 7b731da..a2279b1 100755
Binary files a/app/src/main/cpp/armeabi-v7a/libnative.so and b/app/src/main/cpp/armeabi-v7a/libnative.so differ
diff --git a/app/src/main/cpp/x86/libcrypto.a b/app/src/main/cpp/x86/libcrypto.a
new file mode 100644
index 0000000..de1a167
Binary files /dev/null and b/app/src/main/cpp/x86/libcrypto.a differ
diff --git a/app/src/main/cpp/x86/libcrypto.so b/app/src/main/cpp/x86/libcrypto.so
new file mode 100755
index 0000000..5fe7ad9
Binary files /dev/null and b/app/src/main/cpp/x86/libcrypto.so differ
diff --git a/app/src/main/cpp/x86/libssl.a b/app/src/main/cpp/x86/libssl.a
new file mode 100644
index 0000000..721c5aa
Binary files /dev/null and b/app/src/main/cpp/x86/libssl.a differ
diff --git a/app/src/main/cpp/x86/libssl.so b/app/src/main/cpp/x86/libssl.so
new file mode 100755
index 0000000..88dab05
Binary files /dev/null and b/app/src/main/cpp/x86/libssl.so differ
diff --git a/app/src/main/cpp/x86_64/libcrypto.a b/app/src/main/cpp/x86_64/libcrypto.a
new file mode 100644
index 0000000..f0fa687
Binary files /dev/null and b/app/src/main/cpp/x86_64/libcrypto.a differ
diff --git a/app/src/main/cpp/x86_64/libcrypto.so b/app/src/main/cpp/x86_64/libcrypto.so
new file mode 100755
index 0000000..136532d
Binary files /dev/null and b/app/src/main/cpp/x86_64/libcrypto.so differ
diff --git a/app/src/main/cpp/x86_64/libssl.a b/app/src/main/cpp/x86_64/libssl.a
new file mode 100644
index 0000000..e8e43d3
Binary files /dev/null and b/app/src/main/cpp/x86_64/libssl.a differ
diff --git a/app/src/main/cpp/x86_64/libssl.so b/app/src/main/cpp/x86_64/libssl.so
new file mode 100755
index 0000000..be24c79
Binary files /dev/null and b/app/src/main/cpp/x86_64/libssl.so differ
diff --git a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt
index 6d5ecc0..77f3ede 100644
--- a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt
+++ b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt
@@ -1,26 +1,17 @@
package com.lizongying.mytv
-import android.app.DownloadManager
-import android.app.DownloadManager.Request
-import android.content.BroadcastReceiver
import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.database.Cursor
-import android.net.Uri
-import android.os.Build
-import android.os.Environment
-import android.os.Handler
-import android.os.Looper
import android.util.Log
import androidx.fragment.app.FragmentActivity
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.workDataOf
import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.requests.ReleaseRequest
import com.lizongying.mytv.requests.ReleaseResponse
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
-import java.io.File
class UpdateManager(
@@ -32,17 +23,15 @@ class UpdateManager(
private var releaseRequest = ReleaseRequest()
private var release: ReleaseResponse? = null
- private var downloadReceiver: DownloadReceiver? = null
-
fun checkAndUpdate() {
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) {
- if (release?.version_code!! > versionCode) {
+ val code = release?.version_code
+ if (code != null) {
+ if (code.toLong() > versionCode) {
text = "最新版本:${release?.version_name}"
update = true
} else {
@@ -61,170 +50,24 @@ class UpdateManager(
dialog.show((context as FragmentActivity).supportFragmentManager, TAG)
}
- private fun startDownload(release: ReleaseResponse) {
+ private fun startDownload(context: Context, release: ReleaseResponse) {
+ val versionName = release.version_name
val apkName = "my-tv"
val apkFileName = "$apkName-${release.version_name}.apk"
- val downloadManager =
- context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
- val request =
- Request(Uri.parse("${ApiClient.DOWNLOAD_HOST}${release.version_name}/$apkName-${release.version_name}.apk"))
- Log.i(
- TAG,
- "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("${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")
-
- // 获取下载任务的引用
- val downloadReference = downloadManager.enqueue(request)
-
- downloadReceiver = DownloadReceiver(context, apkFileName, downloadReference)
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- context.registerReceiver(
- downloadReceiver,
- IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),
- Context.RECEIVER_NOT_EXPORTED,
+ val downloadUrl =
+ "${ApiClient.DOWNLOAD_HOST}${release.version_name}/$apkName-${release.version_name}.apk"
+ Log.i(TAG, "downloadUrl: $downloadUrl")
+ val downloadRequest = OneTimeWorkRequestBuilder()
+ .setInputData(
+ workDataOf(
+ "VERSION_NAME" to versionName,
+ "APK_FILENAME" to apkFileName,
+ "DOWNLOAD_URL" to downloadUrl
+ )
)
- } else {
- context.registerReceiver(
- downloadReceiver,
- IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
- )
- }
+ .build()
- getDownloadProgress(context, downloadReference) { progress ->
- println("Download progress: $progress%")
- }
- }
-
- private fun getDownloadProgress(
- context: Context,
- downloadId: Long,
- progressListener: (Int) -> Unit
- ) {
- val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
- val handler = Handler(Looper.getMainLooper())
- val intervalMillis: Long = 1000
-
- handler.post(object : Runnable {
- override fun run() {
- Log.i(TAG, "search")
- val query = DownloadManager.Query().setFilterById(downloadId)
- val cursor: Cursor = downloadManager.query(query)
- cursor.use {
- if (it.moveToFirst()) {
- val bytesDownloadedIndex =
- it.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
- val bytesTotalIndex =
- it.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
-
- // 检查列名是否存在
- if (bytesDownloadedIndex != -1 && bytesTotalIndex != -1) {
- val bytesDownloaded = it.getInt(bytesDownloadedIndex)
- val bytesTotal = it.getInt(bytesTotalIndex)
-
- if (bytesTotal != -1) {
- val progress = (bytesDownloaded * 100L / bytesTotal).toInt()
- progressListener(progress)
- if (progress == 100) {
- return
- }
- }
- }
- }
- }
-
-// handler.postDelayed(this, intervalMillis)
- }
- })
- }
-
- private class DownloadReceiver(
- private val context: Context,
- private val apkFileName: String,
- private val downloadReference: Long
- ) : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
- Log.i(TAG, "reference $reference")
-
- if (reference == downloadReference) {
- 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 apkFile = File(
- context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
- apkFileName
- )
- 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!")
- }
- }
+ WorkManager.getInstance(context).enqueue(downloadRequest)
}
companion object {
@@ -233,16 +76,9 @@ class UpdateManager(
override fun onConfirm() {
Log.i(TAG, "onConfirm $release")
- release?.let { startDownload(it) }
+ release?.let { startDownload(context, it) }
}
override fun onCancel() {
}
-
- fun destroy() {
- if (downloadReceiver != null) {
- context.unregisterReceiver(downloadReceiver)
- Log.i(TAG, "destroy downloadReceiver")
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lizongying/mytv/UpdateWorker.kt b/app/src/main/java/com/lizongying/mytv/UpdateWorker.kt
new file mode 100644
index 0000000..72221ad
--- /dev/null
+++ b/app/src/main/java/com/lizongying/mytv/UpdateWorker.kt
@@ -0,0 +1,150 @@
+package com.lizongying.mytv
+
+import android.app.DownloadManager
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.util.Log
+import androidx.core.app.NotificationCompat
+import androidx.core.content.FileProvider
+import androidx.work.CoroutineWorker
+import androidx.work.WorkerParameters
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import java.io.File
+
+class UpdateWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
+
+ private lateinit var notificationManager: NotificationManager
+ private lateinit var notificationBuilder: NotificationCompat.Builder
+
+ override suspend fun doWork(): Result {
+ val downloadUrl = inputData.getString("DOWNLOAD_URL") ?: return Result.failure()
+ val apkFileName = inputData.getString("APK_FILENAME") ?: return Result.failure()
+ val versionName = inputData.getString("VERSION_NAME") ?: return Result.failure()
+
+ showNotification(applicationContext)
+
+ return withContext(Dispatchers.IO) {
+ try {
+ downloadAndInstall(applicationContext, downloadUrl, apkFileName, versionName)
+ Result.success()
+ } catch (e: Exception) {
+ Result.failure()
+ }
+ }
+ }
+
+ private fun showNotification(context: Context) {
+ notificationManager =
+ context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ notificationBuilder = NotificationCompat.Builder(context, "download_channel").apply {
+ setSmallIcon(android.R.drawable.stat_sys_download)
+ setContentTitle("Downloading Update")
+ setContentText("Download in progress")
+ priority = NotificationCompat.PRIORITY_LOW
+ setOngoing(true)
+ setProgress(100, 0, false)
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(
+ "download_channel",
+ "Download Updates",
+ NotificationManager.IMPORTANCE_LOW
+ )
+ notificationManager.createNotificationChannel(channel)
+ }
+
+ notificationManager.notify(1, notificationBuilder.build())
+ }
+
+ private fun downloadAndInstall(
+ context: Context,
+ downloadUrl: String,
+ apkFileName: String,
+ versionName: String
+ ) {
+ context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.mkdirs()
+ Log.i(TAG, "save dir ${Environment.DIRECTORY_DOWNLOADS}")
+ val request = DownloadManager.Request(Uri.parse(downloadUrl)).apply {
+ setTitle("${context.resources.getString(R.string.app_name)} $versionName Downloading")
+ setDescription("Downloading the latest version of the app")
+ setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, apkFileName)
+
+ setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
+// setAllowedOverRoaming(false)
+ setMimeType("application/vnd.android.package-archive")
+ }
+
+ val manager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
+ val downloadId = manager.enqueue(request)
+
+ var downloading = true
+ while (downloading) {
+ val query = DownloadManager.Query().setFilterById(downloadId)
+ val cursor = manager.query(query)
+ if (cursor.moveToFirst()) {
+ val bytesDownloaded =
+ cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
+ val bytesTotal =
+ cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
+
+ if (bytesTotal > 0) {
+ val progress = (bytesDownloaded * 100L / bytesTotal).toInt()
+ notificationBuilder.setProgress(100, progress, false)
+ notificationManager.notify(1, notificationBuilder.build())
+ }
+
+ when (cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))) {
+ DownloadManager.STATUS_SUCCESSFUL -> downloading = false
+ DownloadManager.STATUS_FAILED -> {
+ downloading = false
+ throw Exception("Download failed")
+ }
+ }
+ }
+ cursor.close()
+ }
+
+ notificationBuilder.setContentText("Download complete")
+ .setProgress(0, 0, false)
+ .setOngoing(false)
+ notificationManager.notify(1, notificationBuilder.build())
+
+ val apkFile = File(
+ context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
+ apkFileName
+ )
+
+ if (apkFile.exists()) {
+ val apkUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(context, context.packageName + ".fileprovider", apkFile)
+ .apply {
+ Intent.FLAG_GRANT_READ_URI_PERMISSION
+ }
+ } else {
+ Uri.parse("file://${apkFile.absolutePath}")
+// Uri.fromFile(apkFile)
+ }
+// 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!")
+ }
+ }
+
+ companion object {
+ private const val TAG = "UpdateWorker"
+ }
+}
diff --git a/version.json b/version.json
index cf2d8e8..8aa064e 100644
--- a/version.json
+++ b/version.json
@@ -1 +1 @@
-{"version_code": 33556736, "version_name": "v2.0.9"}
+{"version_code": 33619968, "version_name": "v2.1.0"}