diff --git a/README.md b/README.md index 9b87925..a5be109 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,15 @@ ## 更新日志 +### v1.5.8(通用版) + +* 修复央视6画质差的问题 +* 增加兵团卫视 +* 播放失败重试 + ### v1.5.6(通用版) * 解决部分设备系统时间不对导致播放失败的问题 -* ### v1.5.2(通用版) diff --git a/app/src/main/java/com/lizongying/mytv/CardAdapter.kt b/app/src/main/java/com/lizongying/mytv/CardAdapter.kt index 204c3a0..059e9dc 100644 --- a/app/src/main/java/com/lizongying/mytv/CardAdapter.kt +++ b/app/src/main/java/com/lizongying/mytv/CardAdapter.kt @@ -80,6 +80,11 @@ class CardAdapter(private val owner: LifecycleOwner, private var tvListViewModel .centerInside() .into(cardView.mainImageView) + "兵团卫视" -> Glide.with(viewHolder.view.context) + .load(R.drawable.bingtuan) + .centerInside() + .into(cardView.mainImageView) + else -> Glide.with(viewHolder.view.context) .load(tvViewModel.logo.value) .centerInside() diff --git a/app/src/main/java/com/lizongying/mytv/CardPresenter.kt b/app/src/main/java/com/lizongying/mytv/CardPresenter.kt index 099a918..cd6dbf4 100644 --- a/app/src/main/java/com/lizongying/mytv/CardPresenter.kt +++ b/app/src/main/java/com/lizongying/mytv/CardPresenter.kt @@ -47,6 +47,11 @@ class CardPresenter( .centerInside() .into(cardView.mainImageView) + "兵团卫视" -> Glide.with(viewHolder.view.context) + .load(R.drawable.bingtuan) + .centerInside() + .into(cardView.mainImageView) + else -> Glide.with(viewHolder.view.context) .load(tvViewModel.logo.value) .centerInside() diff --git a/app/src/main/java/com/lizongying/mytv/ConfirmationDialogFragment.kt b/app/src/main/java/com/lizongying/mytv/ConfirmationDialogFragment.kt new file mode 100644 index 0000000..2100510 --- /dev/null +++ b/app/src/main/java/com/lizongying/mytv/ConfirmationDialogFragment.kt @@ -0,0 +1,36 @@ +package com.lizongying.mytv + +import android.app.AlertDialog +import android.app.Dialog +import android.os.Bundle +import androidx.fragment.app.DialogFragment + +class ConfirmationDialogFragment(private val listener: ConfirmationDialogListener) : + DialogFragment() { + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return activity?.let { + val builder = AlertDialog.Builder(it) + builder.setTitle("确认") + .setMessage("确认更新吗?") + .setPositiveButton( + "确定" + ) { _, _ -> + listener.onConfirm() + } + .setNegativeButton( + "取消" + ) { _, _ -> + listener.onCancel() + } + // 创建并返回 AlertDialog 对象 + builder.create() + } ?: throw IllegalStateException("Activity cannot be null") + } + + interface ConfirmationDialogListener { + fun onConfirm() + fun onCancel() + } +} + diff --git a/app/src/main/java/com/lizongying/mytv/InfoFragment.kt b/app/src/main/java/com/lizongying/mytv/InfoFragment.kt index 7da7dcc..258a9af 100644 --- a/app/src/main/java/com/lizongying/mytv/InfoFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/InfoFragment.kt @@ -43,6 +43,10 @@ class InfoFragment : Fragment() { .load(R.drawable.xinjiang) .into(binding.infoLogo) + "兵团卫视" -> Glide.with(this) + .load(R.drawable.bingtuan) + .into(binding.infoLogo) + else -> Glide.with(this) .load(tvViewModel.logo.value) .into(binding.infoLogo) diff --git a/app/src/main/java/com/lizongying/mytv/MainActivity.kt b/app/src/main/java/com/lizongying/mytv/MainActivity.kt index e4f0c81..270babf 100644 --- a/app/src/main/java/com/lizongying/mytv/MainActivity.kt +++ b/app/src/main/java/com/lizongying/mytv/MainActivity.kt @@ -84,8 +84,14 @@ class MainActivity : FragmentActivity() { channelReversal = sharedPref.getBoolean(CHANNEL_REVERSAL, channelReversal) channelNum = sharedPref.getBoolean(CHANNEL_NUM, channelNum) - versionName = getPackageInfo().versionName - settingFragment = SettingFragment(versionName, channelReversal, channelNum) + val packageInfo = getPackageInfo() + versionName = packageInfo.versionName + val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + packageInfo.longVersionCode + } else { + packageInfo.versionCode.toLong() + } + settingFragment = SettingFragment(versionName, versionCode, channelReversal, channelNum) } fun showInfoFragment(tvViewModel: TVViewModel) { diff --git a/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt b/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt index 80c5a87..d3031f3 100644 --- a/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt @@ -62,6 +62,7 @@ class PlayerFragment : Fragment() { super.onPlayerError(error) Log.e(TAG, "PlaybackException $error") + tvViewModel?.changed() } }) } diff --git a/app/src/main/java/com/lizongying/mytv/Request.kt b/app/src/main/java/com/lizongying/mytv/Request.kt index 58905f4..7e2b522 100644 --- a/app/src/main/java/com/lizongying/mytv/Request.kt +++ b/app/src/main/java/com/lizongying/mytv/Request.kt @@ -43,54 +43,6 @@ class Request { private val input = """{"mver":"1","subver":"1.2","host":"www.yangshipin.cn/#/tv/home?pid=","referer":"","canvas":"YSPANGLE(Apple,ANGLEMetalRenderer:AppleM1Pro,UnspecifiedVersion)"}""".toByteArray() - private var mapping = mapOf( - "CCTV4K" to "CCTV4K 超高清", - "CCTV1" to "CCTV1 综合", - "CCTV2" to "CCTV2 财经", - "CCTV4" to "CCTV4 中文国际", - "CCTV5" to "CCTV5 体育", - "CCTV5+" to "CCTV5+ 体育赛事", - "CCTV7" to "CCTV7 国防军事", - "CCTV9" to "CCTV9 记录", - "CCTV10" to "CCTV10 科教", - "CCTV11" to "CCTV11 戏曲", - "CCTV12" to "CCTV12 社会与法", - "CCTV13" to "CCTV13 新闻", - "CCTV14" to "CCTV14 少儿", - "CCTV15" to "CCTV15 音乐", - "CCTV16-HD" to "CCTV16 奥林匹克", - "CCTV17" to "CCTV17 农业农村", - "CGTN" to "CGTN", - "CGTN法语频道" to "CGTN 法语频道", - "CGTN俄语频道" to "CGTN 俄语频道", - "CGTN阿拉伯语频道" to "CGTN 阿拉伯语频道", - "CGTN西班牙语频道" to "CGTN 西班牙语频道", - "CGTN外语纪录频道" to "CGTN 纪录频道", - "东方卫视" to "东方卫视", - "湖南卫视" to "湖南卫视", - "湖北卫视" to "湖北卫视", - "辽宁卫视" to "辽宁卫视", - "江苏卫视" to "江苏卫视", - "江西卫视" to "江西卫视", - "山东卫视" to "山东卫视", - "广东卫视" to "广东卫视", - "广西卫视" to "广西卫视", - "重庆卫视" to "重庆卫视", - "河南卫视" to "河南卫视", - "河北卫视" to "河北卫视", - "贵州卫视" to "贵州卫视", - "北京卫视" to "北京卫视", - "黑龙江卫视" to "黑龙江卫视", - "浙江卫视" to "浙江卫视", - "安徽卫视" to "安徽卫视", - "深圳卫视" to "深圳卫视", - "四川卫视" to "四川卫视", - "福建东南卫视" to "东南卫视", - "海南卫视" to "海南卫视", - "天津卫视" to "天津卫视", - "新疆卫视" to "新疆卫视", - ) - init { handler.post(tokenRunnable) } diff --git a/app/src/main/java/com/lizongying/mytv/SettingFragment.kt b/app/src/main/java/com/lizongying/mytv/SettingFragment.kt index 94c0e94..f773d18 100644 --- a/app/src/main/java/com/lizongying/mytv/SettingFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/SettingFragment.kt @@ -1,22 +1,28 @@ package com.lizongying.mytv +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.annotation.RequiresApi import androidx.fragment.app.DialogFragment import com.lizongying.mytv.databinding.DialogBinding -class SettingFragment(private val versionName: String, - private val channelReversal: Boolean, - private val channelNum: Boolean, - ) : +class SettingFragment( + private val versionName: String, + private val versionCode: Long, + private val channelReversal: Boolean, + private val channelNum: Boolean, +) : DialogFragment() { private var _binding: DialogBinding? = null private val binding get() = _binding!! + private lateinit var updateManager: UpdateManager + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setStyle(STYLE_NO_TITLE, 0) @@ -43,14 +49,33 @@ class SettingFragment(private val versionName: String, (activity as MainActivity).saveChannelNum(isChecked) } + updateManager = UpdateManager(context, this, versionCode) + _binding?.checkVersion?.setOnClickListener(OnClickListenerCheckVersion(updateManager)) + return binding.root } + fun setVersionName(versionName: String) { + binding.versionName.text = versionName + } + + internal class OnClickListenerCheckVersion(private val updateManager: UpdateManager) : + View.OnClickListener { + override fun onClick(view: View?) { + updateManager.checkAndUpdate() + } + } + override fun onDestroyView() { super.onDestroyView() _binding = null } + override fun onDestroy() { + super.onDestroy() +// updateManager.destroy() + } + companion object { const val TAG = "SettingFragment" } diff --git a/app/src/main/java/com/lizongying/mytv/TVList.kt b/app/src/main/java/com/lizongying/mytv/TVList.kt index 4ec27fd..bdf8435 100644 --- a/app/src/main/java/com/lizongying/mytv/TVList.kt +++ b/app/src/main/java/com/lizongying/mytv/TVList.kt @@ -84,8 +84,8 @@ object TVList { 0, "央视频道", "https://resources.yangshipin.cn/assets/oms/image/202306/741515efda91f03f455df8a7da4ee11fa9329139c276435cf0a9e2af398d5bf2.png?imageMogr2/format/webp", - "600001802", - "2022574301", + "600108442", + "2013693901", "600001802", true, mustToken = true @@ -852,10 +852,24 @@ object TVList { true, mustToken = false ), + TV( + 56, + "兵团卫视", + "兵团卫视", + listOf(), + 0, + "地方频道", + "", + "600170344", + "2022606701", + "", + true, + mustToken = false + ), ), "国际频道" to listOf( TV( - 56, + 57, "CGTN", "CGTN", listOf("http://live.cgtn.com/1000/prog_index.m3u8"), @@ -869,7 +883,7 @@ object TVList { mustToken = false ), TV( - 57, + 58, "CGTN 法语频道", "CGTN法语频道", listOf("https://livefr.cgtn.com/1000f/prog_index.m3u8"), @@ -883,7 +897,7 @@ object TVList { mustToken = false ), TV( - 58, + 59, "CGTN 俄语频道", "CGTN俄语频道", listOf("http://liveru.cgtn.com/1000r/prog_index.m3u8"), @@ -897,7 +911,7 @@ object TVList { mustToken = false ), TV( - 59, + 60, "CGTN 阿拉伯语频道", "CGTN阿拉伯语频道", listOf("http://livear.cgtn.com/1000a/prog_index.m3u8"), @@ -911,7 +925,7 @@ object TVList { mustToken = false ), TV( - 60, + 61, "CGTN 西班牙语频道", "CGTN西班牙语频道", listOf( @@ -928,7 +942,7 @@ object TVList { mustToken = false ), TV( - 61, + 62, "CGTN 纪录频道", "CGTN外语纪录频道", listOf("https://livedoc.cgtn.com/500d/prog_index.m3u8"), diff --git a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt index 2bb5361..a18b538 100644 --- a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt +++ b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt @@ -10,7 +10,7 @@ import android.net.Uri import android.os.Build import android.os.Environment import android.util.Log -import androidx.annotation.RequiresApi +import android.widget.Toast import com.lizongying.mytv.api.Release import com.lizongying.mytv.requests.MyRequest import kotlinx.coroutines.CoroutineScope @@ -19,34 +19,50 @@ import kotlinx.coroutines.launch import java.io.File -class UpdateManager(private var context: Context?) { +class UpdateManager( + private var context: Context?, + private var settingFragment: SettingFragment, + private var versionCode: Long +) : + ConfirmationDialogFragment.ConfirmationDialogListener { private var myRequest = MyRequest() + private var release: Release? = null + + private var downloadReceiver: DownloadReceiver? = null - @RequiresApi(Build.VERSION_CODES.O) fun checkAndUpdate() { CoroutineScope(Dispatchers.Main).launch { try { - val release = myRequest.getRelease() - // 在主线程中更新 UI + release = myRequest.getRelease() updateUI(release) - if (release?.data?.versionCode!! > 0) { - startDownload(release) + Log.i(TAG, "versionCode $versionCode ${release?.data?.versionCode}") + if (release != null) { + if (release?.data?.versionCode!! >= versionCode) { + val dialog = ConfirmationDialogFragment(this@UpdateManager) + dialog.show(settingFragment.fragmentManager, "ConfirmationDialogFragment") + } else { + Toast.makeText(context, "不需要更新", Toast.LENGTH_LONG) + .show() + } } } catch (e: Exception) { - // 处理异常情况 Log.e(TAG, "Error occurred: ${e.message}", e) } } } private fun updateUI(release: Release?) { + if (release?.data?.versionName.isNullOrEmpty()) { + settingFragment.setVersionName("版本获取失败") + } else { + settingFragment.setVersionName("最新版本:${release?.data?.versionName!!}") + } } - @RequiresApi(Build.VERSION_CODES.O) private fun startDownload(release: Release) { val apkFileName = "my-tv-${release.data.versionName}.apk" - + Log.i(TAG, "apkFileName $apkFileName") val downloadManager = context!!.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val request = Request(Uri.parse(release.data.downloadUrl)) @@ -57,13 +73,21 @@ class UpdateManager(private var context: Context?) { // 获取下载任务的引用 val downloadReference = downloadManager.enqueue(request) - // 注册广播接收器,监听下载完成事件 - context!!.registerReceiver( - DownloadReceiver(context!!, apkFileName, downloadReference), - IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), Context.RECEIVER_NOT_EXPORTED - ) - } + 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, + ) + } else { + context!!.registerReceiver( + downloadReceiver, + IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) + ) + } + } private class DownloadReceiver( private val context: Context, @@ -72,6 +96,9 @@ class UpdateManager(private var context: Context?) { ) : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) + Log.i(TAG, "reference $reference") + val progress = intent.getIntExtra("progress", 0) + Log.i(TAG, "progress $progress") // 检查是否是我们发起的下载 if (reference == downloadReference) { @@ -94,8 +121,23 @@ class UpdateManager(private var context: Context?) { } } - companion object { private const val TAG = "UpdateManager" } + + override fun onConfirm() { + Log.i(TAG, "onConfirm $release") + release?.let { startDownload(it) } + } + + override fun onCancel() { + } + + + fun destroy() { + if (downloadReceiver != null) { + context!!.unregisterReceiver(downloadReceiver) + Log.i(TAG, "destroy downloadReceiver") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt b/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt index 945dcdd..25ce453 100644 --- a/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt +++ b/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt @@ -13,9 +13,11 @@ import javax.net.ssl.X509TrustManager class ApiClient { private val yspUrl = "https://player-api.yangshipin.cn/" private val myUrl = "https://lyrics.run/" + private val devUrl = "http://10.0.2.2:8081/" private val protoUrl = "https://capi.yangshipin.cn/" private val traceUrl = "https://btrace.yangshipin.cn/" + private var okHttpClient = getUnsafeOkHttpClient() val yspApiService: YSPApiService by lazy { @@ -34,9 +36,9 @@ class ApiClient { .build().create(YSPTokenService::class.java) } - val ReleaseService by lazy { + val releaseService: ReleaseService by lazy { Retrofit.Builder() - .baseUrl(myUrl) + .baseUrl(devUrl) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build().create(ReleaseService::class.java) diff --git a/app/src/main/java/com/lizongying/mytv/requests/MyRequest.kt b/app/src/main/java/com/lizongying/mytv/requests/MyRequest.kt index 4aed67f..412c504 100644 --- a/app/src/main/java/com/lizongying/mytv/requests/MyRequest.kt +++ b/app/src/main/java/com/lizongying/mytv/requests/MyRequest.kt @@ -11,7 +11,7 @@ import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine class MyRequest { - private var releaseService = ApiClient().ReleaseService + private var releaseService = ApiClient().releaseService suspend fun getRelease(): Release? { return withContext(Dispatchers.IO) { diff --git a/app/src/main/res/drawable/bingtuan.png b/app/src/main/res/drawable/bingtuan.png new file mode 100644 index 0000000..4a40962 Binary files /dev/null and b/app/src/main/res/drawable/bingtuan.png differ diff --git a/app/src/main/res/layout/dialog.xml b/app/src/main/res/layout/dialog.xml index 75c8c46..22c04d2 100644 --- a/app/src/main/res/layout/dialog.xml +++ b/app/src/main/res/layout/dialog.xml @@ -27,7 +27,31 @@ android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/" - > + /> + +