This commit is contained in:
Li ZongYing
2024-03-29 17:04:11 +08:00
parent 49e96d18f4
commit bb88e754a5
26 changed files with 502 additions and 456 deletions
+229
View File
@@ -0,0 +1,229 @@
## 更新日志
### v1.7.2(通用)
* 支持节目列表网格样式和行样式切换,软件重启后生效
* 节目列表样式变更
### v1.7.1(安卓5及以上专用)
* 解决设置页更新闪退的问题
* 凤凰卫视回归
* 解决368问题
### v1.7.0(通用)
* 网络请求优化
### v1.6.9(安卓5及以上专用)
* 去掉港澳台和国际频道
* 解决部分情况下3、6、8等频道无法播放的问题
* 解决部分情况下启动后黑屏问题
### v1.6.8(通用)
* 修复部分设备崩溃的问题
* 修复部分设备凤凰卫视无法播放的问题
### v1.6.7(安卓5及以上专用)
* 手机双击打开配置
* 自动更新
### v1.6.6(通用)
* 更新重庆卫视图标
* 凤凰卫视增强画质
* 凤凰卫视增加EPG
### v1.6.5(安卓5及以上专用)
* 增加CETV1图标
* 稳定性提升
### v1.6.4(通用)
* 增加CETV1
* 增加凤凰卫视
* 默认关闭开机启动
### v1.6.3(安卓5及以上专用)
* 增加CETV1
* 凤凰卫视增强画质
* 默认关闭开机启动
* 延迟菜单自动关闭时间
* 解决一些可能导致首次打开时黑屏的问题
### v1.6.2(通用)
* 修复按键无效的问题
* 新的频道列表样式
### v1.6.1(安卓5及以上专用)
* 增加凤凰卫视
### v1.6.0(通用)
* 通用(春晚緊急修復)
### v1.5.9(安卓5及以上专用)
* 解决天猫魔盒闪退问题
### v1.5.8(通用)
* 修复央视6画质差的问题
* 增加兵团卫视
* 播放失败重试
### v1.5.7(安卓5及以上专用)
* 修复播放失败的问题
### v1.5.6(通用)
* 解决部分设备系统时间不对导致播放失败的问题
### v1.5.5(安卓5及以上专用)
* 修复播放失败的问题
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.4(通用)
* 修复播放失败的问题
### 以下已不可用
### v1.5.3(安卓5及以上专用)
* 修复部分情况下APP切换后无法继续播放的问题
* 优化重试逻辑
### v1.5.2(通用)
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.1(安卓5及以上专用)
* 性能优化
### v1.5.0(通用)
* 修复部分情况下APP切换后无法继续播放的问题
### v1.4.9(安卓5及以上专用)
* 同步v1.4.8
### v1.4.8(通用)
* 频道号从1开始,CCTV5+为18
* 提高CCTV6清晰度
* 增加天津卫视、新疆卫视
### v1.4.7(安卓5及以上专用)
* 修复部分用户CCTV13播放过程中卡住的问题
* 调整CCTV的频道顺序
### v1.4.6(通用)
* 10以下频道不再需要先按0
### v1.4.5(安卓5及以上专用)
* 数字选台配置
### v1.4.4(通用)
* 优化图标显示
* 增加换台反转
### v1.4.3(安卓5及以上专用)
* 支持频道反转配置
### v1.4.2(通用)
* 支持安卓4
### v1.4.1
* 解决部分用户无法打开菜单的问题
### v1.4.0
* 解决极个别高版本机型黑屏问题
### v1.3.9
* 提高稳定性
* 提高连接速度
### v1.3.4
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.3
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.2
* 增加重试,减少因网络问题导致的播放失败
* 优化横幅banner
### v1.3.1
* 增加CCTV 8K 超高清频道
* 增加国际频道栏目
### v1.3.0
* 处理368可能失败的情形
### v1.2.9
* 支持3、6、8
### v1.2.8
* 兼容16:10等分辨率
### v1.2.7
* 此版本是为了测试安卓6.0以下版本,如之前可以正常运行,请勿安装。
### v1.2.6
* 支持安卓4.2
* 解决部分频道无法播放的问题
* 修复切换时有时没有恢复播放的问题
* 左右键不再切换源
* 增大频道信息标题尺寸,缩小与节目信息的间隔
### v1.2.5
* 美化频道信息显示
* 优化节目单获取
### v1.2.4
* 改变换台滑动方向,上一个频道下滑,下一个频道上滑
* 软件退出时,退出播放器
* 播放相同的频道,不再重复加载
* 暂时移除部分频道
### v1.2.3
* 固定视频比列为16:9
* 隐藏全面屏底部的小横条
* 移除移动专区
* 修复一个闪退问题
* 更换图标和应用名
+11 -209
View File
@@ -4,214 +4,9 @@
## 使用 ## 使用
下载安装 [releases](https://github.com/lizongying/my-tv/releases/) 下载安装:
[github](https://github.com/lizongying/my-tv/releases/)
更多地址 [my-tv](https://lyrics.run/my-tv.html) [gitee](https://gitee.com/lizongying/my-tv/releases/)
![image](./screenshots/img_3.png)
![image](./screenshots/img_2.png)
![image](./screenshots/img_1.png)
## 更新日志
### v1.6.6(通用)
* 更新重庆卫视图标
* 凤凰卫视增强画质
* 凤凰卫视增加EPG
### v1.6.5(安卓5及以上专用)
* 增加CETV1图标
* 稳定性提升
### v1.6.4(通用)
* 增加CETV1
* 增加凤凰卫视
* 默认关闭开机启动
### v1.6.3(安卓5及以上专用)
* 增加CETV1
* 凤凰卫视增强画质
* 默认关闭开机启动
* 延迟菜单自动关闭时间
* 解决一些可能导致首次打开时黑屏的问题
### v1.6.2(通用)
* 修复按键无效的问题
* 新的频道列表样式
### v1.6.1(安卓5及以上专用)
* 增加凤凰卫视
### v1.6.0(通用)
* 通用(春晚緊急修復)
### v1.5.9(安卓5及以上专用)
* 解决天猫魔盒闪退问题
### v1.5.8(通用)
* 修复央视6画质差的问题
* 增加兵团卫视
* 播放失败重试
### v1.5.7(安卓5及以上专用)
* 修复播放失败的问题
### v1.5.6(通用)
* 解决部分设备系统时间不对导致播放失败的问题
### v1.5.5(安卓5及以上专用)
* 修复播放失败的问题
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.4(通用)
* 修复播放失败的问题
### 以下已不可用
### v1.5.3(安卓5及以上专用)
* 修复部分情况下APP切换后无法继续播放的问题
* 优化重试逻辑
### v1.5.2(通用)
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.1(安卓5及以上专用)
* 性能优化
### v1.5.0(通用)
* 修复部分情况下APP切换后无法继续播放的问题
### v1.4.9(安卓5及以上专用)
* 同步v1.4.8
### v1.4.8(通用)
* 频道号从1开始,CCTV5+为18
* 提高CCTV6清晰度
* 增加天津卫视、新疆卫视
### v1.4.7(安卓5及以上专用)
* 修复部分用户CCTV13播放过程中卡住的问题
* 调整CCTV的频道顺序
### v1.4.6(通用)
* 10以下频道不再需要先按0
### v1.4.5(安卓5及以上专用)
* 数字选台配置
### v1.4.4(通用)
* 优化图标显示
* 增加换台反转
### v1.4.3(安卓5及以上专用)
* 支持频道反转配置
### v1.4.2(通用)
* 支持安卓4
### v1.4.1
* 解决部分用户无法打开菜单的问题
### v1.4.0
* 解决极个别高版本机型黑屏问题
### v1.3.9
* 提高稳定性
* 提高连接速度
### v1.3.4
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.3
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.2
* 增加重试,减少因网络问题导致的播放失败
* 优化横幅banner
### v1.3.1
* 增加CCTV 8K 超高清频道
* 增加国际频道栏目
### v1.3.0
* 处理368可能失败的情形
### v1.2.9
* 支持3、6、8
### v1.2.8
* 兼容16:10等分辨率
### v1.2.7
* 此版本是为了测试安卓6.0以下版本,如之前可以正常运行,请勿安装。
### v1.2.6
* 支持安卓4.2
* 解决部分频道无法播放的问题
* 修复切换时有时没有恢复播放的问题
* 左右键不再切换源
* 增大频道信息标题尺寸,缩小与节目信息的间隔
### v1.2.5
* 美化频道信息显示
* 优化节目单获取
### v1.2.4
* 改变换台滑动方向,上一个频道下滑,下一个频道上滑
* 软件退出时,退出播放器
* 播放相同的频道,不再重复加载
* 暂时移除部分频道
### v1.2.3
* 固定视频比列为16:9
* 隐藏全面屏底部的小横条
* 移除移动专区
* 修复一个闪退问题
* 更换图标和应用名
## 其他
小米电视可以使用小米电视助手进行安装 小米电视可以使用小米电视助手进行安装
@@ -221,11 +16,18 @@
adb install my-tv.apk adb install my-tv.apk
``` ```
![image](./screenshots/img_3.png)
![image](./screenshots/img_2.png)
![image](./screenshots/img_1.png)
## 更新日志
[更新日志](./HISTORY.md)
## TODO ## TODO
* 音量不同 * 音量不同
* 大湾区卫视、广东4k超高清、广东珠江、三沙卫视 * 大湾区卫视、广东4k超高清、广东珠江、三沙卫视
* CETV教育频道
* CHC高清三个电影频道 * CHC高清三个电影频道
* 地方频道 * 地方频道
* 收藏夹 * 收藏夹
+8
View File
@@ -7,6 +7,8 @@
android:name="android.software.leanback" android:name="android.software.leanback"
android:required="true" /> android:required="true" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<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.RECEIVE_BOOT_COMPLETED" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -38,6 +40,12 @@
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".NetworkChangeReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<provider <provider
android:name=".InitializerProvider" android:name=".InitializerProvider"
android:authorities="${applicationId}.InitializerProvider" android:authorities="${applicationId}.InitializerProvider"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

@@ -91,10 +91,10 @@ class CardAdapter(
false false
} }
cardView.titleText = tvViewModel.title.value cardView.titleText = tvViewModel.getTV().title
Glide.with(viewHolder.view.context) Glide.with(viewHolder.view.context)
.load(tvViewModel.logo.value) .load(tvViewModel.getTV().logo)
.centerInside() .centerInside()
.into(cardView.mainImageView) .into(cardView.mainImageView)
@@ -30,7 +30,7 @@ class ChannelFragment : Fragment() {
fun show(tvViewModel: TVViewModel) { fun show(tvViewModel: TVViewModel) {
handler.removeCallbacks(hideRunnable) handler.removeCallbacks(hideRunnable)
handler.removeCallbacks(playRunnable) handler.removeCallbacks(playRunnable)
binding.channelContent.text = (tvViewModel.id.value?.plus(1)).toString() binding.channelContent.text = (tvViewModel.getTV().id.plus(1)).toString()
view?.visibility = View.VISIBLE view?.visibility = View.VISIBLE
handler.postDelayed(hideRunnable, delay) handler.postDelayed(hideRunnable, delay)
} }
@@ -5,14 +5,16 @@ import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
class ConfirmationDialogFragment(private val listener: ConfirmationDialogListener) : class ConfirmationFragment(
DialogFragment() { private val listener: ConfirmationListener,
private val message: String
) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let { return activity?.let {
val builder = AlertDialog.Builder(it) val builder = AlertDialog.Builder(it)
builder.setTitle("确认") builder.setTitle("确定更新吗?")
.setMessage("确认更新吗?") .setMessage(message)
.setPositiveButton( .setPositiveButton(
"确定" "确定"
) { _, _ -> ) { _, _ ->
@@ -23,12 +25,11 @@ class ConfirmationDialogFragment(private val listener: ConfirmationDialogListene
) { _, _ -> ) { _, _ ->
listener.onCancel() listener.onCancel()
} }
// 创建并返回 AlertDialog 对象
builder.create() builder.create()
} ?: throw IllegalStateException("Activity cannot be null") } ?: throw IllegalStateException("Activity cannot be null")
} }
interface ConfirmationDialogListener { interface ConfirmationListener {
fun onConfirm() fun onConfirm()
fun onCancel() fun onCancel()
} }
@@ -7,6 +7,8 @@ import android.content.pm.PackageInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.Signature import android.content.pm.Signature
import android.content.pm.SigningInfo import android.content.pm.SigningInfo
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import java.security.MessageDigest import java.security.MessageDigest
@@ -71,6 +73,25 @@ val Context.appSignature: String
return hashSignature(sign) return hashSignature(sign)
} }
val Context.isNetworkConnected: Boolean
get() {
val connectivityManager =
this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities != null &&
(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
} else {
val networkInfo = connectivityManager.activeNetworkInfo
return networkInfo != null && networkInfo.isConnectedOrConnecting
}
}
private fun hashSignature(signature: Signature): String { private fun hashSignature(signature: Signature): String {
return try { return try {
val md = MessageDigest.getInstance("MD5") val md = MessageDigest.getInstance("MD5")
@@ -29,13 +29,13 @@ class InfoFragment : Fragment() {
} }
fun show(tvViewModel: TVViewModel) { fun show(tvViewModel: TVViewModel) {
binding.textView.text = tvViewModel.title.value binding.textView.text = tvViewModel.getTV().title
Glide.with(this) Glide.with(this)
.load(tvViewModel.logo.value) .load(tvViewModel.getTV().logo)
.into(binding.infoLogo) .into(binding.infoLogo)
Log.i(TAG, "${tvViewModel.title.value} ${tvViewModel.epg.value}") Log.i(TAG, "${tvViewModel.getTV().title} ${tvViewModel.epg.value}")
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() } val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) { if (!epg.isNullOrEmpty()) {
binding.infoDesc.text = epg.last().title binding.infoDesc.text = epg.last().title
@@ -1,5 +1,9 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@@ -7,11 +11,17 @@ import android.util.Log
import android.view.GestureDetector import android.view.GestureDetector
import android.view.KeyEvent import android.view.KeyEvent
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View
import android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION import android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.lizongying.mytv.models.TVViewModel import com.lizongying.mytv.models.TVViewModel
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
class MainActivity : FragmentActivity(), Request.RequestListener { class MainActivity : FragmentActivity(), Request.RequestListener {
@@ -31,9 +41,20 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
private val delayHideMain: Long = 10000 private val delayHideMain: Long = 10000
private val delayHideSetting: Long = 10000 private val delayHideSetting: Long = 10000
init {
lifecycleScope.launch(Dispatchers.IO) {
val utilsJob = async(start = CoroutineStart.LAZY) { Utils.init() }
utilsJob.start()
// utilsJob.await()
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
Log.i(TAG, "onCreate") Log.i(TAG, "onCreate")
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
Request.onCreate() Request.onCreate()
@@ -53,6 +74,26 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
.commit() .commit()
} }
gestureDetector = GestureDetector(this, GestureListener()) gestureDetector = GestureDetector(this, GestureListener())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val connectivityManager =
getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.registerDefaultNetworkCallback(object :
ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.i(TAG, "net ${Build.VERSION.SDK_INT}")
if (this@MainActivity.isNetworkConnected) {
Log.i(TAG, "net isNetworkConnected")
ready++
}
}
})
} else {
Log.i(TAG, "net ${Build.VERSION.SDK_INT}")
ready++
}
} }
fun showInfoFragment(tvViewModel: TVViewModel) { fun showInfoFragment(tvViewModel: TVViewModel) {
@@ -120,11 +161,15 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
handler.postDelayed(hideMain, delayHideMain) handler.postDelayed(hideMain, delayHideMain)
} }
fun settingActive() { fun settingDelayHide() {
handler.removeCallbacks(hideSetting) handler.removeCallbacks(hideSetting)
handler.postDelayed(hideSetting, delayHideSetting) handler.postDelayed(hideSetting, delayHideSetting)
} }
fun settingNeverHide() {
handler.removeCallbacks(hideSetting)
}
private val hideMain = Runnable { private val hideMain = Runnable {
if (!mainFragment.isHidden) { if (!mainFragment.isHidden) {
supportFragmentManager.beginTransaction().hide(mainFragment).commit() supportFragmentManager.beginTransaction().hide(mainFragment).commit()
@@ -146,7 +191,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
fun fragmentReady() { fun fragmentReady() {
ready++ ready++
Log.i(TAG, "ready $ready") Log.i(TAG, "ready $ready")
if (ready == 5) { if (ready == 6) {
mainFragment.fragmentReady() mainFragment.fragmentReady()
} }
} }
@@ -166,6 +211,11 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
return true return true
} }
override fun onDoubleTap(e: MotionEvent): Boolean {
showSetting()
return true
}
override fun onFling( override fun onFling(
e1: MotionEvent?, e1: MotionEvent?,
e2: MotionEvent, e2: MotionEvent,
@@ -207,7 +257,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
Log.i(TAG, "settingFragment ${settingFragment.isVisible}") Log.i(TAG, "settingFragment ${settingFragment.isVisible}")
if (!settingFragment.isVisible) { if (!settingFragment.isVisible) {
settingFragment.show(supportFragmentManager, "setting") settingFragment.show(supportFragmentManager, "setting")
settingActive() settingDelayHide()
} else { } else {
handler.removeCallbacks(hideSetting) handler.removeCallbacks(hideSetting)
settingFragment.dismiss() settingFragment.dismiss()
@@ -449,7 +499,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
Request.onDestroy() Request.onDestroy()
} }
override fun onRequestFinished() { override fun onRequestFinished(message: String?) {
fragmentReady() fragmentReady()
} }
@@ -122,7 +122,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
tvListViewModel.tvListViewModel.value?.forEach { tvViewModel -> tvListViewModel.tvListViewModel.value?.forEach { tvViewModel ->
tvViewModel.errInfo.observe(viewLifecycleOwner) { _ -> tvViewModel.errInfo.observe(viewLifecycleOwner) { _ ->
if (tvViewModel.errInfo.value != null if (tvViewModel.errInfo.value != null
&& tvViewModel.id.value == itemPosition && tvViewModel.getTV().id == itemPosition
) { ) {
Toast.makeText(context, tvViewModel.errInfo.value, Toast.LENGTH_SHORT) Toast.makeText(context, tvViewModel.errInfo.value, Toast.LENGTH_SHORT)
.show() .show()
@@ -132,18 +132,18 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
// not first time && channel not change // not first time && channel not change
if (tvViewModel.ready.value != null if (tvViewModel.ready.value != null
&& tvViewModel.id.value == itemPosition && tvViewModel.getTV().id == itemPosition
&& check(tvViewModel) && check(tvViewModel)
) { ) {
Log.i(TAG, "ready ${tvViewModel.title.value}") Log.i(TAG, "ready ${tvViewModel.getTV().title}")
(activity as? MainActivity)?.play(tvViewModel) (activity as? MainActivity)?.play(tvViewModel)
} }
} }
tvViewModel.change.observe(viewLifecycleOwner) { _ -> tvViewModel.change.observe(viewLifecycleOwner) { _ ->
if (tvViewModel.change.value != null) { if (tvViewModel.change.value != null) {
val title = tvViewModel.title.value val title = tvViewModel.getTV().title
Log.i(TAG, "switch $title") Log.i(TAG, "switch $title")
if (tvViewModel.pid.value != "") { if (tvViewModel.getTV().pid != "") {
Log.i(TAG, "request $title") Log.i(TAG, "request $title")
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
tvViewModel.let { Request.fetchData(it) } tvViewModel.let { Request.fetchData(it) }
@@ -191,7 +191,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
} }
override fun onItemHasFocus(tvViewModel: TVViewModel) { override fun onItemHasFocus(tvViewModel: TVViewModel) {
tvListViewModel.setItemPositionCurrent(tvViewModel.id.value!!) tvListViewModel.setItemPositionCurrent(tvViewModel.getTV().id)
val row = tvViewModel.getRowPosition() val row = tvViewModel.getRowPosition()
@@ -211,8 +211,8 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
return return
} }
if (itemPosition != tvViewModel.id.value!!) { if (itemPosition != tvViewModel.getTV().id) {
itemPosition = tvViewModel.id.value!! itemPosition = tvViewModel.getTV().id
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed() tvListViewModel.getTVViewModel(itemPosition)?.changed()
} }
@@ -245,7 +245,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
} }
fun check(tvViewModel: TVViewModel): Boolean { fun check(tvViewModel: TVViewModel): Boolean {
val title = tvViewModel.title.value val title = tvViewModel.getTV().title
val videoUrl = tvViewModel.videoIndex.value?.let { tvViewModel.videoUrl.value?.get(it) } val videoUrl = tvViewModel.videoIndex.value?.let { tvViewModel.videoUrl.value?.get(it) }
if (videoUrl == null || videoUrl == "") { if (videoUrl == null || videoUrl == "") {
Log.e(TAG, "$title videoUrl is empty") Log.e(TAG, "$title videoUrl is empty")
@@ -0,0 +1,16 @@
package com.lizongying.mytv
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
class NetworkChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
val isConnected = context?.isNetworkConnected
if (isConnected == true) {
}
}
}
}
@@ -57,7 +57,9 @@ object Request {
private var listener: RequestListener? = null private var listener: RequestListener? = null
private var initRetryTimes = 0 private var initRetryTimes = 0
private var initRetryMaxTimes = 1 private var initRetryMaxTimes = 0
private var openid = "vu0-8lgGV2LW9QjDeucB9H12d_6HQWmTFgqCWg5o-VBQN4"
fun onCreate() { fun onCreate() {
Log.i(TAG, "onCreate") Log.i(TAG, "onCreate")
@@ -86,7 +88,7 @@ object Request {
private fun fetchAuth(tvModel: TVViewModel, cookie: String) { private fun fetchAuth(tvModel: TVViewModel, cookie: String) {
cancelCall() cancelCall()
val title = tvModel.title.value val title = tvModel.getTV().title
val data = YSP.getAuthData(tvModel) val data = YSP.getAuthData(tvModel)
val request = AuthRequest(data) val request = AuthRequest(data)
@@ -166,7 +168,7 @@ object Request {
handler.removeCallbacks(btraceRunnable) handler.removeCallbacks(btraceRunnable)
} }
val title = tvModel.title.value val title = tvModel.getTV().title
tvModel.seq = 0 tvModel.seq = 0
val data = YSP.switch(tvModel) val data = YSP.switch(tvModel)
@@ -254,7 +256,7 @@ object Request {
} }
} }
} else { } else {
Log.e(TAG, "$title status error") Log.e(TAG, "$title status error $data")
if (tvModel.retryTimes < tvModel.retryMaxTimes) { if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++ tvModel.retryTimes++
if (tvModel.getTV().needToken) { if (tvModel.getTV().needToken) {
@@ -309,13 +311,13 @@ object Request {
tvModel.needGetToken = false tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0 tvModel.tokenYSPRetryTimes = 0
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=$openid; vusession=$token"
fetchAuth(tvModel, cookie) fetchAuth(tvModel, cookie)
} else if (response.code() == 304) { } else if (response.code() == 304) {
tvModel.needGetToken = false tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0 tvModel.tokenYSPRetryTimes = 0
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie) fetchVideo(tvModel, cookie)
} else { } else {
Log.e(TAG, "info status error") Log.e(TAG, "info status error")
@@ -348,7 +350,7 @@ object Request {
}) })
} else { } else {
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=$openid; vusession=$token"
fetchAuth(tvModel, cookie) fetchAuth(tvModel, cookie)
} }
} }
@@ -366,13 +368,13 @@ object Request {
tvModel.needGetToken = false tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0 tvModel.tokenYSPRetryTimes = 0
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie) fetchVideo(tvModel, cookie)
} else if (response.code() == 304) { } else if (response.code() == 304) {
tvModel.needGetToken = false tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0 tvModel.tokenYSPRetryTimes = 0
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie) fetchVideo(tvModel, cookie)
} else { } else {
Log.e(TAG, "info status error") Log.e(TAG, "info status error")
@@ -405,7 +407,7 @@ object Request {
}) })
} else { } else {
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie) fetchVideo(tvModel, cookie)
} }
} }
@@ -413,7 +415,7 @@ object Request {
private fun fetchFAuth(tvModel: TVViewModel) { private fun fetchFAuth(tvModel: TVViewModel) {
cancelCall() cancelCall()
val title = tvModel.title.value val title = tvModel.getTV().title
var qa = "HD" var qa = "HD"
if (tokenFH != "") { if (tokenFH != "") {
@@ -455,6 +457,9 @@ object Request {
} }
if (tvModel.getTV().needToken) { if (tvModel.getTV().needToken) {
if (token == "") {
tvModel.needGetToken = true
}
if (needAuth) { if (needAuth) {
fetchAuth(tvModel) fetchAuth(tvModel)
} else { } else {
@@ -462,7 +467,7 @@ object Request {
} }
} else { } else {
val cookie = val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205" "versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; updateProtocol=1; deviceModel=120"
if (needAuth) { if (needAuth) {
fetchAuth(tvModel, cookie) fetchAuth(tvModel, cookie)
} else { } else {
@@ -482,10 +487,14 @@ object Request {
.enqueue(object : Callback<InfoV2> { .enqueue(object : Callback<InfoV2> {
override fun onResponse(call: Call<InfoV2>, response: Response<InfoV2>) { override fun onResponse(call: Call<InfoV2>, response: Response<InfoV2>) {
if (response.isSuccessful) { if (response.isSuccessful) {
val o = response.body()?.o
val t = response.body()?.t val t = response.body()?.t
val f = response.body()?.f val f = response.body()?.f
val e = response.body()?.e val e = response.body()?.e
val c = response.body()?.c val c = response.body()?.c
if (!o.isNullOrEmpty()) {
openid = o
}
if (!t.isNullOrEmpty()) { if (!t.isNullOrEmpty()) {
token = t token = t
Log.i(TAG, "token success $token") Log.i(TAG, "token success $token")
@@ -516,7 +525,7 @@ object Request {
Utils.setBetween(c * 1000L) Utils.setBetween(c * 1000L)
Log.i(TAG, "current time $c") Log.i(TAG, "current time $c")
} }
listener?.onRequestFinished() listener?.onRequestFinished(null)
} else { } else {
Log.e(TAG, "token status error") Log.e(TAG, "token status error")
handler.postDelayed( handler.postDelayed(
@@ -527,7 +536,7 @@ object Request {
initRetryTimes++ initRetryTimes++
fetchInfoV2() fetchInfoV2()
} else { } else {
listener?.onRequestFinished() listener?.onRequestFinished("状态错误")
} }
} }
} }
@@ -543,7 +552,7 @@ object Request {
initRetryTimes++ initRetryTimes++
fetchInfoV2() fetchInfoV2()
} else { } else {
listener?.onRequestFinished() listener?.onRequestFinished("网络错误")
} }
} }
}) })
@@ -605,11 +614,11 @@ object Request {
} }
fun fetchBtrace(tvModel: TVViewModel) { fun fetchBtrace(tvModel: TVViewModel) {
val title = tvModel.title.value val title = tvModel.getTV().title
val guid = YSP.getGuid() val guid = YSP.getGuid()
val pid = tvModel.pid.value!! val pid = tvModel.getTV().pid
val sid = tvModel.sid.value!! val sid = tvModel.getTV().sid
yspBtraceService.kvcollect( yspBtraceService.kvcollect(
c_timestamp = YSP.generateGuid(), c_timestamp = YSP.generateGuid(),
guid = guid, guid = guid,
@@ -675,8 +684,8 @@ object Request {
} }
fun fetchYEPG(tvViewModel: TVViewModel) { fun fetchYEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.title.value val title = tvViewModel.getTV().title
yspProtoService.getProgram(tvViewModel.programId.value!!, getDateFormat("yyyyMMdd")) yspProtoService.getProgram(tvViewModel.getTV().programId, getDateFormat("yyyyMMdd"))
.enqueue(object : Callback<epgProgramModel.Response> { .enqueue(object : Callback<epgProgramModel.Response> {
override fun onResponse( override fun onResponse(
call: Call<epgProgramModel.Response>, call: Call<epgProgramModel.Response>,
@@ -700,8 +709,8 @@ object Request {
} }
fun fetchFEPG(tvViewModel: TVViewModel) { fun fetchFEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.title.value val title = tvViewModel.getTV().title
fAuthService.getEPG(tvViewModel.pid.value!!, getDateFormat("yyyyMMdd")) fAuthService.getEPG(tvViewModel.getTV().pid, getDateFormat("yyyyMMdd"))
.enqueue(object : Callback<List<FEPG>> { .enqueue(object : Callback<List<FEPG>> {
override fun onResponse( override fun onResponse(
call: Call<List<FEPG>>, call: Call<List<FEPG>>,
@@ -738,7 +747,7 @@ object Request {
} }
interface RequestListener { interface RequestListener {
fun onRequestFinished() fun onRequestFinished(message: String?)
} }
fun setRequestListener(listener: RequestListener) { fun setRequestListener(listener: RequestListener) {
@@ -5,12 +5,12 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.lizongying.mytv.databinding.DialogBinding import com.lizongying.mytv.databinding.SettingBinding
class SettingFragment : DialogFragment() { class SettingFragment : DialogFragment() {
private var _binding: DialogBinding? = null private var _binding: SettingBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var updateManager: UpdateManager private lateinit var updateManager: UpdateManager
@@ -26,15 +26,15 @@ class SettingFragment : DialogFragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
val context = requireContext() // It‘s safe to get context here. val context = requireContext() // It‘s safe to get context here.
_binding = DialogBinding.inflate(inflater, container, false) _binding = SettingBinding.inflate(inflater, container, false)
binding.version.text = binding.versionName.text = "当前版本: v${context.appVersionName}"
"当前版本: ${context.appVersionName}\n获取最新: https://github.com/lizongying/my-tv/releases/" binding.version.text = "https://github.com/lizongying/my-tv"
binding.switchChannelReversal.run { binding.switchChannelReversal.run {
isChecked = SP.channelReversal isChecked = SP.channelReversal
setOnCheckedChangeListener { _, isChecked -> setOnCheckedChangeListener { _, isChecked ->
SP.channelReversal = isChecked SP.channelReversal = isChecked
(activity as MainActivity).settingActive() (activity as MainActivity).settingDelayHide()
} }
} }
@@ -42,7 +42,7 @@ class SettingFragment : DialogFragment() {
isChecked = SP.channelNum isChecked = SP.channelNum
setOnCheckedChangeListener { _, isChecked -> setOnCheckedChangeListener { _, isChecked ->
SP.channelNum = isChecked SP.channelNum = isChecked
(activity as MainActivity).settingActive() (activity as MainActivity).settingDelayHide()
} }
} }
@@ -50,7 +50,7 @@ class SettingFragment : DialogFragment() {
isChecked = SP.bootStartup isChecked = SP.bootStartup
setOnCheckedChangeListener { _, isChecked -> setOnCheckedChangeListener { _, isChecked ->
SP.bootStartup = isChecked SP.bootStartup = isChecked
(activity as MainActivity).settingActive() (activity as MainActivity).settingDelayHide()
} }
} }
@@ -58,23 +58,34 @@ class SettingFragment : DialogFragment() {
isChecked = SP.grid isChecked = SP.grid
setOnCheckedChangeListener { _, isChecked -> setOnCheckedChangeListener { _, isChecked ->
SP.grid = isChecked SP.grid = isChecked
(activity as MainActivity).settingActive() (activity as MainActivity).settingDelayHide()
} }
} }
updateManager = UpdateManager(context, this, context.appVersionCode) updateManager = UpdateManager(context, this, context.appVersionCode)
binding.checkVersion.setOnClickListener(OnClickListenerCheckVersion(updateManager)) binding.checkVersion.setOnClickListener(
OnClickListenerCheckVersion(
activity as MainActivity,
updateManager
)
)
return binding.root return binding.root
} }
fun setVersionName(versionName: String) { fun setVersionName(versionName: String) {
binding.versionName.text = versionName if (_binding != null) {
binding.versionName.text = versionName
}
} }
internal class OnClickListenerCheckVersion(private val updateManager: UpdateManager) : internal class OnClickListenerCheckVersion(
private val mainActivity: MainActivity,
private val updateManager: UpdateManager
) :
View.OnClickListener { View.OnClickListener {
override fun onClick(view: View?) { override fun onClick(view: View?) {
mainActivity.settingDelayHide()
updateManager.checkAndUpdate() updateManager.checkAndUpdate()
} }
} }
@@ -84,11 +95,6 @@ class SettingFragment : DialogFragment() {
_binding = null _binding = null
} }
override fun onDestroy() {
super.onDestroy()
// updateManager.destroy()
}
companion object { companion object {
const val TAG = "SettingFragment" const val TAG = "SettingFragment"
} }
@@ -7,7 +7,6 @@ data class TV(
var title: String, var title: String,
var alias: String = "", var alias: String = "",
var videoUrl: List<String>, var videoUrl: List<String>,
var videoIndex: Int = 0,
var channel: String = "", var channel: String = "",
var logo: Any = "", var logo: Any = "",
var pid: String = "", var pid: String = "",
@@ -23,7 +22,6 @@ data class TV(
"id=" + id + "id=" + id +
", title='" + title + '\'' + ", title='" + title + '\'' +
", videoUrl='" + videoUrl + '\'' + ", videoUrl='" + videoUrl + '\'' +
", videoIndex='" + videoIndex + '\'' +
", logo='" + logo + '\'' + ", logo='" + logo + '\'' +
", pid='" + pid + '\'' + ", pid='" + pid + '\'' +
", sid='" + sid + '\'' + ", sid='" + sid + '\'' +
@@ -13,7 +13,6 @@ object TVList {
"CCTV1 综合", "CCTV1 综合",
"CCTV1", "CCTV1",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226231/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226231/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/d57905b93540bd15f0c48230dbbbff7ee0d645ff539e38866e2d15c8b9f7dfcd.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/d57905b93540bd15f0c48230dbbbff7ee0d645ff539e38866e2d15c8b9f7dfcd.png?imageMogr2/format/webp",
"600001859", "600001859",
@@ -27,7 +26,6 @@ object TVList {
"CCTV2 财经", "CCTV2 财经",
"CCTV2", "CCTV2",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226195/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226195/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/20115388de0207131af17eac86c33049b95d69eaff064e55653a1b941810a006.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/20115388de0207131af17eac86c33049b95d69eaff064e55653a1b941810a006.png?imageMogr2/format/webp",
"600001800", "600001800",
@@ -41,7 +39,6 @@ object TVList {
"CCTV3 综艺", "CCTV3 综艺",
"CCTV3", "CCTV3",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226397/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226397/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/7b7a65c712450da3deb6ca66fbacf4f9aee00d3f20bd80eafb5ada01ec63eb3a.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/7b7a65c712450da3deb6ca66fbacf4f9aee00d3f20bd80eafb5ada01ec63eb3a.png?imageMogr2/format/webp",
"600001801", "600001801",
@@ -58,7 +55,6 @@ object TVList {
"http://39.134.24.161/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226191/index.m3u8", "http://39.134.24.161/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226191/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226191/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226191/index.m3u8"
), ),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/f357e58fdbcc076a3d65e1f958c942b2e14f14342c60736ceed98b092d35356a.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/f357e58fdbcc076a3d65e1f958c942b2e14f14342c60736ceed98b092d35356a.png?imageMogr2/format/webp",
"600001814", "600001814",
@@ -72,7 +68,6 @@ object TVList {
"CCTV5 体育", "CCTV5 体育",
"CCTV5", "CCTV5",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226395/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226395/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/0a6a7138952675983a3d854df7688557b286d59aa06166edae51506f9204d655.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/0a6a7138952675983a3d854df7688557b286d59aa06166edae51506f9204d655.png?imageMogr2/format/webp",
"600001818", "600001818",
@@ -86,7 +81,6 @@ object TVList {
"CCTV6 电影", "CCTV6 电影",
"CCTV6", "CCTV6",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226393/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226393/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/741515efda91f03f455df8a7da4ee11fa9329139c276435cf0a9e2af398d5bf2.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/741515efda91f03f455df8a7da4ee11fa9329139c276435cf0a9e2af398d5bf2.png?imageMogr2/format/webp",
"600108442", "600108442",
@@ -100,7 +94,6 @@ object TVList {
"CCTV7 国防军事", "CCTV7 国防军事",
"CCTV7", "CCTV7",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226192/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226192/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/b29af94e295ebdf646cefb68122c429b9cd921f498ca20d2d8070252536f9ff9.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/b29af94e295ebdf646cefb68122c429b9cd921f498ca20d2d8070252536f9ff9.png?imageMogr2/format/webp",
"600004092", "600004092",
@@ -114,7 +107,6 @@ object TVList {
"CCTV8 电视剧", "CCTV8 电视剧",
"CCTV8", "CCTV8",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226391/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226391/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/ad51de94426a0ba039e6dd6a8534ea98ecc813a6176bde87b4f18cc34d6d7590.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/ad51de94426a0ba039e6dd6a8534ea98ecc813a6176bde87b4f18cc34d6d7590.png?imageMogr2/format/webp",
"600001803", "600001803",
@@ -128,7 +120,6 @@ object TVList {
"CCTV9 纪录", "CCTV9 纪录",
"CCTV9", "CCTV9",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226197/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226197/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/2ed1b4deeca179d5db806bb941790f82eb92a1b7299c1c38fe027f95a5caee5e.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/2ed1b4deeca179d5db806bb941790f82eb92a1b7299c1c38fe027f95a5caee5e.png?imageMogr2/format/webp",
"600004078", "600004078",
@@ -142,7 +133,6 @@ object TVList {
"CCTV10 科教", "CCTV10 科教",
"CCTV10", "CCTV10",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226189/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226189/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/aa6157ec65188cd41826e5a2f088c3d6d153205f5f6428258d12c59999e221aa.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/aa6157ec65188cd41826e5a2f088c3d6d153205f5f6428258d12c59999e221aa.png?imageMogr2/format/webp",
"600001805", "600001805",
@@ -156,7 +146,6 @@ object TVList {
"CCTV11 戏曲", "CCTV11 戏曲",
"CCTV11", "CCTV11",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226240/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226240/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/ed12ed7c7a1034dae4350011fe039284c5d5a836506b28c9e32e3c75299625c0.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/ed12ed7c7a1034dae4350011fe039284c5d5a836506b28c9e32e3c75299625c0.png?imageMogr2/format/webp",
"600001806", "600001806",
@@ -170,7 +159,6 @@ object TVList {
"CCTV12 社会与法", "CCTV12 社会与法",
"CCTV12", "CCTV12",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226190/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226190/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/484083cffaa40df7e659565e8cb4d1cc740158a185512114167aa21fa0c59240.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/484083cffaa40df7e659565e8cb4d1cc740158a185512114167aa21fa0c59240.png?imageMogr2/format/webp",
"600001807", "600001807",
@@ -184,10 +172,8 @@ object TVList {
"CCTV13 新闻", "CCTV13 新闻",
"CCTV13", "CCTV13",
listOf( listOf(
"https://live-play.cctvnews.cctv.com/cctv/merge_cctv13.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226233/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226233/index.m3u8"
), ),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/266da7b43c03e2312186b4a999e0f060e8f15b10d2cc2c9aa32171819254cf1a.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/266da7b43c03e2312186b4a999e0f060e8f15b10d2cc2c9aa32171819254cf1a.png?imageMogr2/format/webp",
"600001811", "600001811",
@@ -201,7 +187,6 @@ object TVList {
"CCTV14 少儿", "CCTV14 少儿",
"CCTV14", "CCTV14",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226193/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226193/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/af6b603896938dc346fbb16abfc63c12cba54b0ec9d18770a15d347d115f12d5.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/af6b603896938dc346fbb16abfc63c12cba54b0ec9d18770a15d347d115f12d5.png?imageMogr2/format/webp",
"600001809", "600001809",
@@ -215,7 +200,6 @@ object TVList {
"CCTV15 音乐", "CCTV15 音乐",
"CCTV15", "CCTV15",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225785/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225785/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/2ceee92188ef684efe0d8b90839c4f3ad450d179dc64d59beff417059453af47.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/2ceee92188ef684efe0d8b90839c4f3ad450d179dc64d59beff417059453af47.png?imageMogr2/format/webp",
"600001815", "600001815",
@@ -232,7 +216,6 @@ object TVList {
"http://39.134.24.162/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8", "http://39.134.24.162/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8"
), ),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/53793fa7bacd3a93ff6dc5d2758418985e1f952a316c335d663b572d8bdcd74d.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/53793fa7bacd3a93ff6dc5d2758418985e1f952a316c335d663b572d8bdcd74d.png?imageMogr2/format/webp",
"600098637", "600098637",
@@ -246,7 +229,6 @@ object TVList {
"CCTV17 农业农村", "CCTV17 农业农村",
"CCTV17", "CCTV17",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226198/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226198/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/ddef563072f8bad2bea5b9e52674cb7b4ed50efb20c26e61994dfbdf05c1e3c0.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/ddef563072f8bad2bea5b9e52674cb7b4ed50efb20c26e61994dfbdf05c1e3c0.png?imageMogr2/format/webp",
"600001810", "600001810",
@@ -260,7 +242,6 @@ object TVList {
"CCTV5+ 体育赛事", "CCTV5+ 体育赛事",
"CCTV5+", "CCTV5+",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226221/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226221/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/649ad76a90bfef55b05db9fe52e006487280f619089099d5dc971e387fc6eff0.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/649ad76a90bfef55b05db9fe52e006487280f619089099d5dc971e387fc6eff0.png?imageMogr2/format/webp",
"600001817", "600001817",
@@ -274,7 +255,6 @@ object TVList {
"CCTV4K 超高清", "CCTV4K 超高清",
"CCTV4K", "CCTV4K",
listOf(), listOf(),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/3e9d06fd7244d950df5838750f1c6ac3456e172b51caca2c16d2282125b111e8.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/3e9d06fd7244d950df5838750f1c6ac3456e172b51caca2c16d2282125b111e8.png?imageMogr2/format/webp",
"600002264", "600002264",
@@ -288,7 +268,6 @@ object TVList {
"CCTV8K 超高清", "CCTV8K 超高清",
"CCTV8K", "CCTV8K",
listOf(), listOf(),
0,
"央视", "央视",
R.drawable.cctv8k, R.drawable.cctv8k,
"600156816", "600156816",
@@ -302,7 +281,6 @@ object TVList {
"风云剧场", "风云剧场",
"CCTV风云剧场频道", "CCTV风云剧场频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226950/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226950/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/4d549e53e6d0f632d5a633d1945280797b153e588f919221a07faa869812cc89.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/4d549e53e6d0f632d5a633d1945280797b153e588f919221a07faa869812cc89.png?imageMogr2/format/webp",
"600099658", "600099658",
@@ -316,7 +294,6 @@ object TVList {
"第一剧场", "第一剧场",
"CCTV第一剧场频道", "CCTV第一剧场频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226959/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226959/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/a556bd7d93ce65e18f243a8892b5604f4faa994a4897315914216a710a706208.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/a556bd7d93ce65e18f243a8892b5604f4faa994a4897315914216a710a706208.png?imageMogr2/format/webp",
"600099655", "600099655",
@@ -330,7 +307,6 @@ object TVList {
"怀旧剧场", "怀旧剧场",
"CCTV怀旧剧场频道", "CCTV怀旧剧场频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226972/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226972/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/5661bd04fecdb6e899f801147a22ab5d3a475bf2b62e30aec2c0023190ebc9b1.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/5661bd04fecdb6e899f801147a22ab5d3a475bf2b62e30aec2c0023190ebc9b1.png?imageMogr2/format/webp",
"600099620", "600099620",
@@ -344,7 +320,6 @@ object TVList {
"世界地理", "世界地理",
"CCTV世界地理频道", "CCTV世界地理频道",
listOf(), listOf(),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/bb3c6c9e145d698137f5bb64a582021a01b51344b929003630eb769ea65832a9.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/bb3c6c9e145d698137f5bb64a582021a01b51344b929003630eb769ea65832a9.png?imageMogr2/format/webp",
"600099637", "600099637",
@@ -358,7 +333,6 @@ object TVList {
"风云音乐", "风云音乐",
"CCTV风云音乐频道", "CCTV风云音乐频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226953/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226953/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/bbf1d024c5228b8dd128b0e3cb1717d173fab4ee84c3a4c8a57b1a215362ca3b.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/bbf1d024c5228b8dd128b0e3cb1717d173fab4ee84c3a4c8a57b1a215362ca3b.png?imageMogr2/format/webp",
"600099660", "600099660",
@@ -372,7 +346,6 @@ object TVList {
"兵器科技", "兵器科技",
"CCTV兵器科技频道", "CCTV兵器科技频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226975/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226975/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/4c6b6a6d3839889f34d33db3c2f80233b26b74d3489b393487635f8704e70796.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/4c6b6a6d3839889f34d33db3c2f80233b26b74d3489b393487635f8704e70796.png?imageMogr2/format/webp",
"600099649", "600099649",
@@ -386,7 +359,6 @@ object TVList {
"风云足球", "风云足球",
"CCTV风云足球频道", "CCTV风云足球频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226984/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226984/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/cd1e2bb52b06a991de168733e5ff0f1d85adc8042d40c8f393f723543e5dd08a.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/cd1e2bb52b06a991de168733e5ff0f1d85adc8042d40c8f393f723543e5dd08a.png?imageMogr2/format/webp",
"600099636", "600099636",
@@ -400,7 +372,6 @@ object TVList {
"高尔夫网球", "高尔夫网球",
"CCTV高尔夫·网球频道", "CCTV高尔夫·网球频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226978/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226978/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/cdd1b31ede7a5ad049ed53d9a072422f829e72dd062ed2c19e077fdd01699071.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/cdd1b31ede7a5ad049ed53d9a072422f829e72dd062ed2c19e077fdd01699071.png?imageMogr2/format/webp",
"600099659", "600099659",
@@ -414,7 +385,6 @@ object TVList {
"女性时尚", "女性时尚",
"CCTV女性时尚频道", "CCTV女性时尚频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226969/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226969/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/fa28955ce8b2539d728bf4c6a13a46ff57ad76eae46627f7bcfb1ed8a613d3fc.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/fa28955ce8b2539d728bf4c6a13a46ff57ad76eae46627f7bcfb1ed8a613d3fc.png?imageMogr2/format/webp",
"600099650", "600099650",
@@ -428,7 +398,6 @@ object TVList {
"央视文化精品", "央视文化精品",
"CCTV央视文化精品频道", "CCTV央视文化精品频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226981/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226981/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/14ac5ce40482cacd3d4b37435222bfe86af2b452a2f04ecbfc1d13d76edd7c57.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/14ac5ce40482cacd3d4b37435222bfe86af2b452a2f04ecbfc1d13d76edd7c57.png?imageMogr2/format/webp",
"600099653", "600099653",
@@ -442,7 +411,6 @@ object TVList {
"央视台球", "央视台球",
"CCTV央视台球频道", "CCTV央视台球频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226956/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226956/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/10e14a92478011aa6c3c8562e62127f3b1908e29fcd78e4b2b24b9e6d3ec2fbc.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/10e14a92478011aa6c3c8562e62127f3b1908e29fcd78e4b2b24b9e6d3ec2fbc.png?imageMogr2/format/webp",
"600099652", "600099652",
@@ -456,7 +424,6 @@ object TVList {
"电视指南", "电视指南",
"CCTV电视指南频道", "CCTV电视指南频道",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226987/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226987/index.m3u8"),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/244d72c0eb1615ed7d51c2f5db5a67f306aa3f58c05bc2d34de3aa7e956dc8c9.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/244d72c0eb1615ed7d51c2f5db5a67f306aa3f58c05bc2d34de3aa7e956dc8c9.png?imageMogr2/format/webp",
"600099656", "600099656",
@@ -470,7 +437,6 @@ object TVList {
"卫生健康", "卫生健康",
"CCTV卫生健康频道", "CCTV卫生健康频道",
listOf(), listOf(),
0,
"央视", "央视",
"https://resources.yangshipin.cn/assets/oms/image/202306/54a6863656fdfd8f803be193ddf22441c5000a108833889816fd2d8911715ce8.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/54a6863656fdfd8f803be193ddf22441c5000a108833889816fd2d8911715ce8.png?imageMogr2/format/webp",
"600099651", "600099651",
@@ -486,7 +452,6 @@ object TVList {
"东方卫视", "东方卫视",
"东方卫视", "东方卫视",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226217/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226217/index.m3u8"),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/9bd372ca292a82ce3aa08772b07efc4af1f85c21d1f268ea33440c49e9a0a488.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/9bd372ca292a82ce3aa08772b07efc4af1f85c21d1f268ea33440c49e9a0a488.png?imageMogr2/format/webp",
"600002483", "600002483",
@@ -503,7 +468,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226307/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226307/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226211/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226211/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/4120e89d3079d08aa17d382f69a2308ec70839b278367763c34a34666c75cb88.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/4120e89d3079d08aa17d382f69a2308ec70839b278367763c34a34666c75cb88.png?imageMogr2/format/webp",
"600002475", "600002475",
@@ -520,7 +484,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226477/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226477/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226194/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226194/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/7a6be5a2bb1dc53a945c016ff1f525dc4a84c51db371c15c89aa55404b0ba784.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/7a6be5a2bb1dc53a945c016ff1f525dc4a84c51db371c15c89aa55404b0ba784.png?imageMogr2/format/webp",
"600002508", "600002508",
@@ -537,7 +500,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226546/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226546/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226201/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226201/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/ac4ed6058a87c101ae7147ebc38905d0cae047fb73fd277ee5049b84f52bda36.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/ac4ed6058a87c101ae7147ebc38905d0cae047fb73fd277ee5049b84f52bda36.png?imageMogr2/format/webp",
"600002505", "600002505",
@@ -554,7 +516,6 @@ object TVList {
"http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226200/index.m3u8", "http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226200/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226200/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226200/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/380ad685c0c1d5b2c902246b8d2df6d3f9b45e2837abcfe493075bbded597a31.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/380ad685c0c1d5b2c902246b8d2df6d3f9b45e2837abcfe493075bbded597a31.png?imageMogr2/format/webp",
"600002521", "600002521",
@@ -571,7 +532,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226344/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226344/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225764/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225764/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/3c760d0d00463855890e8a1864ea4a6b6dd66b90c29b4ac714a4b17c16519871.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/3c760d0d00463855890e8a1864ea4a6b6dd66b90c29b4ac714a4b17c16519871.png?imageMogr2/format/webp",
"600002503", "600002503",
@@ -585,7 +545,6 @@ object TVList {
"山东卫视", "山东卫视",
"山东卫视", "山东卫视",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226209/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226209/index.m3u8"),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/22d403f07a7cf5410b3ad3ddb65a11aa229a32475fac213f5344c9f0ec330ca1.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/22d403f07a7cf5410b3ad3ddb65a11aa229a32475fac213f5344c9f0ec330ca1.png?imageMogr2/format/webp",
"600002513", "600002513",
@@ -599,7 +558,6 @@ object TVList {
"广东卫视", "广东卫视",
"广东卫视", "广东卫视",
listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226216/index.m3u8"), listOf("http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226216/index.m3u8"),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/28886880a4dc0f06fb7e0a528a1def0591d61a65870e29176ede0cc92033bbfd.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/28886880a4dc0f06fb7e0a528a1def0591d61a65870e29176ede0cc92033bbfd.png?imageMogr2/format/webp",
"600002485", "600002485",
@@ -616,7 +574,6 @@ object TVList {
"http://live.gxrb.com.cn/tv/gxtvlive03/index.m3u8", "http://live.gxrb.com.cn/tv/gxtvlive03/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225770/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225770/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/54b7e97cb816bb223fe05f3fc44da2c7820eb66e8550c19d23100f2c414ecc38.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/54b7e97cb816bb223fe05f3fc44da2c7820eb66e8550c19d23100f2c414ecc38.png?imageMogr2/format/webp",
"600002509", "600002509",
@@ -633,7 +590,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226409/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226409/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226202/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226202/index.m3u8"
), ),
0,
"地方", "地方",
R.drawable.chongqing, R.drawable.chongqing,
"600002531", "600002531",
@@ -650,7 +606,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226480/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226480/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225767/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225767/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/74925962148a6d31c85808b6cd4e444c2a54bab393d2c5fc85e960b50e22fa86.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/74925962148a6d31c85808b6cd4e444c2a54bab393d2c5fc85e960b50e22fa86.png?imageMogr2/format/webp",
"600002525", "600002525",
@@ -667,7 +622,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226406/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226406/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225750/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225750/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/d545becdc81c60197b08c7f47380705e4665ed3fe55efc8b855e486f6e655378.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/d545becdc81c60197b08c7f47380705e4665ed3fe55efc8b855e486f6e655378.png?imageMogr2/format/webp",
"600002493", "600002493",
@@ -684,7 +638,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226474/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226474/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225793/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225793/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/4eb45f4781d33d872af027dc01c941559aab55667dd99cc5c22bef7037807b13.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/4eb45f4781d33d872af027dc01c941559aab55667dd99cc5c22bef7037807b13.png?imageMogr2/format/webp",
"600002490", "600002490",
@@ -701,7 +654,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221225728/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221225728/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226222/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226222/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/f4f23633c578beea49a3841d88d3490100f029ee349059fa532869db889872c5.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/f4f23633c578beea49a3841d88d3490100f029ee349059fa532869db889872c5.png?imageMogr2/format/webp",
"600002309", "600002309",
@@ -718,7 +670,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226327/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226327/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226215/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226215/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/d8273ae9be698ce2db21f5b886ecac95a73429593f93713c60ed8c12c38bf0d3.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/d8273ae9be698ce2db21f5b886ecac95a73429593f93713c60ed8c12c38bf0d3.png?imageMogr2/format/webp",
"600002498", "600002498",
@@ -735,7 +686,6 @@ object TVList {
"http://hw-m-l.cztv.com/channels/lantian/channel01/1080p.m3u8", "http://hw-m-l.cztv.com/channels/lantian/channel01/1080p.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226199/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226199/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/a66c836bd98ba3e41a2e9a570d4b9c50dedc6839e9de333e2e78212ad505f37e.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/a66c836bd98ba3e41a2e9a570d4b9c50dedc6839e9de333e2e78212ad505f37e.png?imageMogr2/format/webp",
"600002520", "600002520",
@@ -752,7 +702,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226391/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226391/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226203/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226203/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/f35fa04b51b1ee4984b03578b65403570868ebca03c6c01e11b097f999a58d9b.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/f35fa04b51b1ee4984b03578b65403570868ebca03c6c01e11b097f999a58d9b.png?imageMogr2/format/webp",
"600002532", "600002532",
@@ -769,7 +718,6 @@ object TVList {
"http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226205/index.m3u8", "http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226205/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226205/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226205/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/d59fec04c902e3581c617136d02d4b9b8c4cbe64272781ddd3525e80c823edb7.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/d59fec04c902e3581c617136d02d4b9b8c4cbe64272781ddd3525e80c823edb7.png?imageMogr2/format/webp",
"600002481", "600002481",
@@ -786,7 +734,6 @@ object TVList {
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225768/index.m3u8", "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225768/index.m3u8",
"http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225768/index.m3u8" "http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225768/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/3276a414ae0eaa0f116f2045cd913367967d0c7c1e978e8621ac3879436c6ed7.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/3276a414ae0eaa0f116f2045cd913367967d0c7c1e978e8621ac3879436c6ed7.png?imageMogr2/format/webp",
"600002516", "600002516",
@@ -803,7 +750,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226341/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226341/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225766/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225766/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/3208fe6564a293c21b711333fb3edb05bb5b406cff840573c9a8d839680a1579.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/3208fe6564a293c21b711333fb3edb05bb5b406cff840573c9a8d839680a1579.png?imageMogr2/format/webp",
"600002484", "600002484",
@@ -820,7 +766,6 @@ object TVList {
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226465/index.m3u8", "http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226465/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225769/index.m3u8" "http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225769/index.m3u8"
), ),
0,
"地方", "地方",
"https://resources.yangshipin.cn/assets/oms/image/202306/6e060391fde0469801fc3d84dbf204b4f8d650d251f17d7595a6964c0bb99e81.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/6e060391fde0469801fc3d84dbf204b4f8d650d251f17d7595a6964c0bb99e81.png?imageMogr2/format/webp",
"600002506", "600002506",
@@ -834,7 +779,6 @@ object TVList {
"天津卫视", "天津卫视",
"天津卫视", "天津卫视",
listOf(), listOf(),
0,
"地方", "地方",
R.drawable.tianjin, R.drawable.tianjin,
"600152137", "600152137",
@@ -848,7 +792,6 @@ object TVList {
"新疆卫视", "新疆卫视",
"新疆卫视", "新疆卫视",
listOf(), listOf(),
0,
"地方", "地方",
R.drawable.xinjiang, R.drawable.xinjiang,
"600152138", "600152138",
@@ -862,7 +805,6 @@ object TVList {
"兵团卫视", "兵团卫视",
"兵团卫视", "兵团卫视",
listOf(), listOf(),
0,
"地方", "地方",
R.drawable.bingtuan, R.drawable.bingtuan,
"600170344", "600170344",
@@ -876,7 +818,6 @@ object TVList {
"CETV1", "CETV1",
"CETV1", "CETV1",
listOf(), listOf(),
0,
"地方", "地方",
R.drawable.cetv1, R.drawable.cetv1,
"600171827", "600171827",
@@ -892,7 +833,6 @@ object TVList {
"凤凰卫视资讯台", "凤凰卫视资讯台",
"", "",
listOf(), listOf(),
0,
"港澳台", "港澳台",
"http://c1.fengshows-cdn.com/a/2021_22/79dcc3a9da358a3.png", "http://c1.fengshows-cdn.com/a/2021_22/79dcc3a9da358a3.png",
"7c96b084-60e1-40a9-89c5-682b994fb680", "7c96b084-60e1-40a9-89c5-682b994fb680",
@@ -906,7 +846,6 @@ object TVList {
"凤凰卫视中文台", "凤凰卫视中文台",
"", "",
listOf(), listOf(),
0,
"港澳台", "港澳台",
"http://c1.fengshows-cdn.com/a/2021_22/ede3d9e09be28e5.png", "http://c1.fengshows-cdn.com/a/2021_22/ede3d9e09be28e5.png",
"f7f48462-9b13-485b-8101-7b54716411ec", "f7f48462-9b13-485b-8101-7b54716411ec",
@@ -920,7 +859,6 @@ object TVList {
"凤凰卫视香港台", "凤凰卫视香港台",
"", "",
listOf(), listOf(),
0,
"港澳台", "港澳台",
"http://c1.fengshows-cdn.com/a/2021_23/325d941090bee17.png", "http://c1.fengshows-cdn.com/a/2021_23/325d941090bee17.png",
"15e02d92-1698-416c-af2f-3e9a872b4d78", "15e02d92-1698-416c-af2f-3e9a872b4d78",
@@ -936,7 +874,6 @@ object TVList {
"CGTN", "CGTN",
"CGTN", "CGTN",
listOf("http://live.cgtn.com/1000/prog_index.m3u8"), listOf("http://live.cgtn.com/1000/prog_index.m3u8"),
0,
"国际", "国际",
"https://resources.yangshipin.cn/assets/oms/image/202306/a72dff758ca1c17cd0ecc8cedc11b893d208f409d5e6302faa0e9d298848abc3.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/a72dff758ca1c17cd0ecc8cedc11b893d208f409d5e6302faa0e9d298848abc3.png?imageMogr2/format/webp",
"600014550", "600014550",
@@ -950,7 +887,6 @@ object TVList {
"CGTN 法语频道", "CGTN 法语频道",
"CGTN法语频道", "CGTN法语频道",
listOf("https://livefr.cgtn.com/1000f/prog_index.m3u8"), listOf("https://livefr.cgtn.com/1000f/prog_index.m3u8"),
0,
"国际", "国际",
"https://resources.yangshipin.cn/assets/oms/image/202306/a8d0046a47433d952bf6ed17062deb8bd2184ba9aec0f7781df6bf9487a3ffcf.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/a8d0046a47433d952bf6ed17062deb8bd2184ba9aec0f7781df6bf9487a3ffcf.png?imageMogr2/format/webp",
"600084704", "600084704",
@@ -964,7 +900,6 @@ object TVList {
"CGTN 俄语频道", "CGTN 俄语频道",
"CGTN俄语频道", "CGTN俄语频道",
listOf("http://liveru.cgtn.com/1000r/prog_index.m3u8"), listOf("http://liveru.cgtn.com/1000r/prog_index.m3u8"),
0,
"国际", "国际",
"https://resources.yangshipin.cn/assets/oms/image/202306/bf0a820893cbaf20dd0333e27042e1ef9c8806e5b602b6a8c95af399db0bc77a.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/bf0a820893cbaf20dd0333e27042e1ef9c8806e5b602b6a8c95af399db0bc77a.png?imageMogr2/format/webp",
"600084758", "600084758",
@@ -978,7 +913,6 @@ object TVList {
"CGTN 阿拉伯语频道", "CGTN 阿拉伯语频道",
"CGTN阿拉伯语频道", "CGTN阿拉伯语频道",
listOf("http://livear.cgtn.com/1000a/prog_index.m3u8"), listOf("http://livear.cgtn.com/1000a/prog_index.m3u8"),
0,
"国际", "国际",
"https://resources.yangshipin.cn/assets/oms/image/202306/2e44e2aa3e7a1cedf07fd0ae59fe69e86a60a2632660a006e3e9e7397b2d107e.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202306/2e44e2aa3e7a1cedf07fd0ae59fe69e86a60a2632660a006e3e9e7397b2d107e.png?imageMogr2/format/webp",
"600084782", "600084782",
@@ -995,7 +929,6 @@ object TVList {
"http://livees.cgtn.com/500e/prog_index.m3u8", "http://livees.cgtn.com/500e/prog_index.m3u8",
"http://livees.cgtn.com/1000e/prog_index.m3u8" "http://livees.cgtn.com/1000e/prog_index.m3u8"
), ),
0,
"国际", "国际",
"https://resources.yangshipin.cn/assets/oms/image/202309/7c337e3dbe64402ec7e4678a619a4a6d95144e42f35161181ff78e143b7cf67a.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202309/7c337e3dbe64402ec7e4678a619a4a6d95144e42f35161181ff78e143b7cf67a.png?imageMogr2/format/webp",
"600084744", "600084744",
@@ -1009,7 +942,6 @@ object TVList {
"CGTN 纪录频道", "CGTN 纪录频道",
"CGTN外语纪录频道", "CGTN外语纪录频道",
listOf("https://livedoc.cgtn.com/500d/prog_index.m3u8"), listOf("https://livedoc.cgtn.com/500d/prog_index.m3u8"),
0,
"国际", "国际",
"https://resources.yangshipin.cn/assets/oms/image/202309/74d3ac436a7e374879578de1d87a941fbf566d39d5632b027c5097891ed32bd5.png?imageMogr2/format/webp", "https://resources.yangshipin.cn/assets/oms/image/202309/74d3ac436a7e374879578de1d87a941fbf566d39d5632b027c5097891ed32bd5.png?imageMogr2/format/webp",
"600084781", "600084781",
@@ -1,5 +1,6 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.app.Activity
import android.app.DownloadManager import android.app.DownloadManager
import android.app.DownloadManager.Request import android.app.DownloadManager.Request
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
@@ -13,8 +14,10 @@ import android.os.Environment
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import android.widget.Toast import androidx.core.app.ActivityCompat
import com.lizongying.mytv.api.Release import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.checkSelfPermission
import com.lizongying.mytv.api.ReleaseV2
import com.lizongying.mytv.requests.MyRequest import com.lizongying.mytv.requests.MyRequest
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -27,52 +30,81 @@ class UpdateManager(
private var settingFragment: SettingFragment, private var settingFragment: SettingFragment,
private var versionCode: Long private var versionCode: Long
) : ) :
ConfirmationDialogFragment.ConfirmationDialogListener { ConfirmationFragment.ConfirmationListener {
private var myRequest = MyRequest() private var myRequest = MyRequest()
private var release: Release? = null private var release: ReleaseV2? = null
private var downloadReceiver: DownloadReceiver? = null private var downloadReceiver: DownloadReceiver? = null
fun checkAndUpdate() { fun checkAndUpdate() {
if (!haveStoragePermission()) {
return
}
CoroutineScope(Dispatchers.Main).launch { CoroutineScope(Dispatchers.Main).launch {
var text = "版本获取失败"
try { try {
release = myRequest.getRelease() release = myRequest.getRelease()
updateUI(release) Log.i(TAG, "versionCode $versionCode ${release?.c}")
Log.i(TAG, "versionCode $versionCode ${release?.data?.versionCode}") if (release?.c != null) {
if (release != null) { text = if (release?.c!! > versionCode) {
if (release?.data?.versionCode!! >= versionCode) { "最新版本:${release?.n}\n${release?.d ?: ""}"
val dialog = ConfirmationDialogFragment(this@UpdateManager)
dialog.show(settingFragment.fragmentManager, "ConfirmationDialogFragment")
} else { } else {
Toast.makeText(context, "不需要更新", Toast.LENGTH_LONG) "已是最新版本,不需要更新"
.show()
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Error occurred: ${e.message}", e) Log.e(TAG, "Error occurred: ${e.message}", e)
} }
updateUI(text)
} }
} }
private fun updateUI(release: Release?) { private fun updateUI(text: String) {
if (release?.data?.versionName.isNullOrEmpty()) { val dialog = ConfirmationFragment(this@UpdateManager, text)
settingFragment.setVersionName("版本获取失败") dialog.show(settingFragment.fragmentManager, TAG)
} else { }
settingFragment.setVersionName("最新版本:${release?.data?.versionName!!}")
private fun haveStoragePermission(): Boolean {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
=== PermissionChecker.PERMISSION_GRANTED
) {
Log.e("Permission error", "You have permission")
return true
} else {
Log.e("Permission error", "You have asked for permission")
ActivityCompat.requestPermissions(
context as Activity, arrayOf(
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
), 1
)
return false
}
} else { //you don't need to worry about these stuff below api level 23
Log.e("Permission error", "You already have the permission")
return true
} }
} }
private fun startDownload(release: Release) {
val apkFileName = "my-tv-${release.data.versionName}.apk" private fun startDownload(release: ReleaseV2) {
val apkFileName = "my-tv-${release.n}.apk"
Log.i(TAG, "apkFileName $apkFileName") Log.i(TAG, "apkFileName $apkFileName")
val downloadManager = val downloadManager =
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val request = Request(Uri.parse(release.data.downloadUrl)) val request = Request(Uri.parse(release.u))
Log.i(TAG, "url ${Uri.parse(release.data.downloadUrl)}") Log.i(TAG, "url ${Uri.parse(release.u)}")
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkFileName) context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.mkdirs()
request.setTitle("New Version Download") request.setDestinationInExternalFilesDir(
context,
Environment.DIRECTORY_DOWNLOADS,
apkFileName
)
request.setTitle("${settingFragment.resources.getString(R.string.app_name)} ${release.n}")
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setAllowedOverRoaming(false)
request.setMimeType("application/vnd.android.package-archive")
// 获取下载任务的引用 // 获取下载任务的引用
val downloadReference = downloadManager.enqueue(request) val downloadReference = downloadManager.enqueue(request)
@@ -97,7 +129,11 @@ class UpdateManager(
} }
} }
private fun getDownloadProgress(context: Context, downloadId: Long, progressListener: (Int) -> Unit) { private fun getDownloadProgress(
context: Context,
downloadId: Long,
progressListener: (Int) -> Unit
) {
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val handler = Handler(Looper.getMainLooper()) val handler = Handler(Looper.getMainLooper())
val intervalMillis: Long = 1000 val intervalMillis: Long = 1000
@@ -179,7 +215,6 @@ class UpdateManager(
override fun onCancel() { override fun onCancel() {
} }
fun destroy() { fun destroy() {
if (downloadReceiver != null) { if (downloadReceiver != null) {
context.unregisterReceiver(downloadReceiver) context.unregisterReceiver(downloadReceiver)
@@ -17,7 +17,6 @@ import javax.net.ssl.X509TrustManager
class ApiClient { class ApiClient {
private val yspUrl = "https://player-api.yangshipin.cn/" private val yspUrl = "https://player-api.yangshipin.cn/"
private val myUrl = "https://lyrics.run/" private val myUrl = "https://lyrics.run/"
private val devUrl = "http://10.0.2.2:8081/"
private val protoUrl = "https://capi.yangshipin.cn/" private val protoUrl = "https://capi.yangshipin.cn/"
private val traceUrl = "https://btrace.yangshipin.cn/" private val traceUrl = "https://btrace.yangshipin.cn/"
private val fUrl = "https://m.fengshows.com/" private val fUrl = "https://m.fengshows.com/"
@@ -16,24 +16,19 @@ data class Token(
) )
data class InfoV2( data class InfoV2(
val o: String?,
val f: String?, val f: String?,
val t: String?, val t: String?,
val e: Int?, val e: Int?,
val c: Int?, val c: Int?,
) )
data class Release( data class ReleaseV2(
val code: Int?, val n: String?,
val msg: String?, val u: String?,
val data: Data, val d: String?,
) { val c: Int?,
data class Data( )
val versionName: String,
val versionCode: Int,
val downloadUrl: String,
val updateTime: Int,
)
}
data class TimeResponse( data class TimeResponse(
val data: Time val data: Time
@@ -2,10 +2,11 @@ package com.lizongying.mytv.api
import retrofit2.Call import retrofit2.Call
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Path
interface ReleaseService { interface ReleaseService {
@GET("my-tv/v1/release") @GET("my-tv/v2/release/{name}")
fun getRelease( fun getRelease(
): Call<Release> @Path("name") date: String = "2",
): Call<ReleaseV2>
} }
@@ -63,8 +63,8 @@ object YSP {
} }
fun switch(tvModel: TVViewModel): String { fun switch(tvModel: TVViewModel): String {
livepid = tvModel.pid.value!! livepid = tvModel.getTV().pid
cnlid = tvModel.sid.value!! cnlid = tvModel.getTV().sid
defn = "fhd" defn = "fhd"
randStr = getRand() randStr = getRand()
@@ -82,7 +82,7 @@ object YSP {
} }
fun getAuthData(tvModel: TVViewModel): String { fun getAuthData(tvModel: TVViewModel): String {
livepid = tvModel.pid.value!! livepid = tvModel.getTV().pid
randStr = getRand() randStr = getRand()
@@ -1,15 +1,9 @@
package com.lizongying.mytv.models package com.lizongying.mytv.models
import android.net.Uri
import android.util.Log import android.util.Log
import androidx.annotation.OptIn
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.media3.common.MediaItem
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.exoplayer.hls.HlsMediaSource
import com.lizongying.mytv.TV import com.lizongying.mytv.TV
import com.lizongying.mytv.api.FEPG import com.lizongying.mytv.api.FEPG
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.programModel.Program import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.programModel.Program
@@ -26,7 +20,7 @@ class TVViewModel(private var tv: TV) : ViewModel() {
var tokenYSPRetryTimes = 0 var tokenYSPRetryTimes = 0
var tokenYSPRetryMaxTimes = 0 var tokenYSPRetryMaxTimes = 0
var tokenFHRetryTimes = 0 var tokenFHRetryTimes = 0
var tokenFHRetryMaxTimes = 2 var tokenFHRetryMaxTimes = 8
var needGetToken = false var needGetToken = false
@@ -34,22 +28,10 @@ class TVViewModel(private var tv: TV) : ViewModel() {
val errInfo: LiveData<String> val errInfo: LiveData<String>
get() = _errInfo get() = _errInfo
private val _programId = MutableLiveData<String>()
val programId: LiveData<String>
get() = _programId
private var _epg = MutableLiveData<MutableList<EPG>>() private var _epg = MutableLiveData<MutableList<EPG>>()
val epg: LiveData<MutableList<EPG>> val epg: LiveData<MutableList<EPG>>
get() = _epg get() = _epg
private val _id = MutableLiveData<Int>()
val id: LiveData<Int>
get() = _id
private val _title = MutableLiveData<String>()
val title: LiveData<String>
get() = _title
private val _videoUrl = MutableLiveData<List<String>>() private val _videoUrl = MutableLiveData<List<String>>()
val videoUrl: LiveData<List<String>> val videoUrl: LiveData<List<String>>
get() = _videoUrl get() = _videoUrl
@@ -58,18 +40,6 @@ class TVViewModel(private var tv: TV) : ViewModel() {
val videoIndex: LiveData<Int> val videoIndex: LiveData<Int>
get() = _videoIndex get() = _videoIndex
private val _logo = MutableLiveData<Any>()
val logo: LiveData<Any>
get() = _logo
private val _pid = MutableLiveData<String>()
val pid: LiveData<String>
get() = _pid
private val _sid = MutableLiveData<String>()
val sid: LiveData<String>
get() = _sid
private val _change = MutableLiveData<Boolean>() private val _change = MutableLiveData<Boolean>()
val change: LiveData<Boolean> val change: LiveData<Boolean>
get() = _change get() = _change
@@ -90,9 +60,8 @@ class TVViewModel(private var tv: TV) : ViewModel() {
} else { } else {
tv.videoUrl = tv.videoUrl + listOf(url) tv.videoUrl = tv.videoUrl + listOf(url)
} }
tv.videoIndex = tv.videoUrl.lastIndex
_videoUrl.value = tv.videoUrl _videoUrl.value = tv.videoUrl
_videoIndex.value = tv.videoIndex _videoIndex.value = tv.videoUrl.lastIndex
} }
fun firstSource() { fun firstSource() {
@@ -117,14 +86,8 @@ class TVViewModel(private var tv: TV) : ViewModel() {
} }
init { init {
_id.value = tv.id
_title.value = tv.title
_videoUrl.value = tv.videoUrl _videoUrl.value = tv.videoUrl
_videoIndex.value = tv.videoIndex _videoIndex.value = tv.videoUrl.lastIndex
_logo.value = tv.logo
_programId.value = tv.programId
_pid.value = tv.pid
_sid.value = tv.sid
} }
fun getRowPosition(): Int { fun getRowPosition(): Int {
@@ -147,10 +110,6 @@ class TVViewModel(private var tv: TV) : ViewModel() {
_errInfo.value = info _errInfo.value = info
} }
fun update(t: TV) {
tv = t
}
fun getTV(): TV { fun getTV(): TV {
return tv return tv
} }
@@ -173,21 +132,6 @@ class TVViewModel(private var tv: TV) : ViewModel() {
_epg.value = p.map { EPG(it.title, formatFTime(it.event_time)) }.toMutableList() _epg.value = p.map { EPG(it.title, formatFTime(it.event_time)) }.toMutableList()
} }
/**
* (playerView?.player as ExoPlayer).setMediaSource(tvViewModel.buildSource())
*/
@OptIn(UnstableApi::class)
fun buildSource(): HlsMediaSource {
val httpDataSource = DefaultHttpDataSource.Factory()
// mHeaders?.let { httpDataSource.setDefaultRequestProperties(it) }
return HlsMediaSource.Factory(httpDataSource).createMediaSource(
MediaItem.fromUri(
Uri.parse(getVideoUrlCurrent())
)
)
}
fun getVideoUrlCurrent(): String { fun getVideoUrlCurrent(): String {
return _videoUrl.value!![_videoIndex.value!!] return _videoUrl.value!![_videoIndex.value!!]
} }
@@ -1,7 +1,7 @@
package com.lizongying.mytv.requests package com.lizongying.mytv.requests
import com.lizongying.mytv.api.ApiClient import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.api.Release import com.lizongying.mytv.api.ReleaseV2
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import retrofit2.Call import retrofit2.Call
@@ -13,17 +13,17 @@ import kotlin.coroutines.suspendCoroutine
class MyRequest { class MyRequest {
private var releaseService = ApiClient().releaseService private var releaseService = ApiClient().releaseService
suspend fun getRelease(): Release? { suspend fun getRelease(): ReleaseV2? {
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
fetchRelease() fetchRelease()
} }
} }
private suspend fun fetchRelease(): Release? { private suspend fun fetchRelease(): ReleaseV2? {
return suspendCoroutine { continuation -> return suspendCoroutine { continuation ->
releaseService.getRelease() releaseService.getRelease()
.enqueue(object : Callback<Release> { .enqueue(object : Callback<ReleaseV2> {
override fun onResponse(call: Call<Release>, response: Response<Release>) { override fun onResponse(call: Call<ReleaseV2>, response: Response<ReleaseV2>) {
if (response.isSuccessful) { if (response.isSuccessful) {
continuation.resume(response.body()) continuation.resume(response.body())
} else { } else {
@@ -31,7 +31,7 @@ class MyRequest {
} }
} }
override fun onFailure(call: Call<Release>, t: Throwable) { override fun onFailure(call: Call<ReleaseV2>, t: Throwable) {
continuation.resume(null) continuation.resume(null)
} }
}) })
+2 -2
View File
@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '8.2.2' apply false id 'com.android.application' version '8.3.0' apply false
id 'com.android.library' version '8.2.2' apply false id 'com.android.library' version '8.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.9.22' apply false id 'org.jetbrains.kotlin.android' version '1.9.22' apply false
} }
+1 -1
View File
@@ -1,6 +1,6 @@
#Fri Dec 01 13:53:24 HKT 2023 #Fri Dec 01 13:53:24 HKT 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-rc-1-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME