mirror of
https://github.com/lizongying/my-tv.git
synced 2026-06-03 21:02:26 +08:00
fix ysp
This commit is contained in:
parent
bcfca9e28c
commit
cf8d7f00a8
378
HISTORY.md
378
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
|
||||
* 隐藏全面屏底部的小横条
|
||||
* 移除移动专区
|
||||
* 修复一个闪退问题
|
||||
* 更换图标和应用名
|
||||
* 固定視頻比例為16:9
|
||||
* 隱藏全面屏底部的小橫條
|
||||
* 移除移動專區
|
||||
* 修復一個閃退問題
|
||||
* 更換圖標和應用名
|
||||
@ -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'
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<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" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
app/src/main/cpp/x86/libcrypto.a
Normal file
BIN
app/src/main/cpp/x86/libcrypto.a
Normal file
Binary file not shown.
BIN
app/src/main/cpp/x86/libcrypto.so
Executable file
BIN
app/src/main/cpp/x86/libcrypto.so
Executable file
Binary file not shown.
BIN
app/src/main/cpp/x86/libssl.a
Normal file
BIN
app/src/main/cpp/x86/libssl.a
Normal file
Binary file not shown.
BIN
app/src/main/cpp/x86/libssl.so
Executable file
BIN
app/src/main/cpp/x86/libssl.so
Executable file
Binary file not shown.
BIN
app/src/main/cpp/x86_64/libcrypto.a
Normal file
BIN
app/src/main/cpp/x86_64/libcrypto.a
Normal file
Binary file not shown.
BIN
app/src/main/cpp/x86_64/libcrypto.so
Executable file
BIN
app/src/main/cpp/x86_64/libcrypto.so
Executable file
Binary file not shown.
BIN
app/src/main/cpp/x86_64/libssl.a
Normal file
BIN
app/src/main/cpp/x86_64/libssl.a
Normal file
Binary file not shown.
BIN
app/src/main/cpp/x86_64/libssl.so
Executable file
BIN
app/src/main/cpp/x86_64/libssl.so
Executable file
Binary file not shown.
@ -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<UpdateWorker>()
|
||||
.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")
|
||||
}
|
||||
}
|
||||
}
|
||||
150
app/src/main/java/com/lizongying/mytv/UpdateWorker.kt
Normal file
150
app/src/main/java/com/lizongying/mytv/UpdateWorker.kt
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
@ -1 +1 @@
|
||||
{"version_code": 33556736, "version_name": "v2.0.9"}
|
||||
{"version_code": 33619968, "version_name": "v2.1.0"}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user