diff --git a/HISTORY.md b/HISTORY.md index 2008e815..9c43951c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,16 @@ ## 更新日志 +### v1.7.2(通用) + +* 支持节目列表网格样式和行样式切换,软件重启后生效 +* 节目列表样式变更 + +### v1.7.1(安卓5及以上专用) + +* 解决设置页更新闪退的问题 +* 凤凰卫视回归 +* 解决368问题 + ### v1.7.0(通用) * 网络请求优化 diff --git a/app/src/main/java/com/lizongying/mytv/CardPresenter.kt b/app/src/main/java/com/lizongying/mytv/CardPresenter.kt index 6a5350db..7254be15 100644 --- a/app/src/main/java/com/lizongying/mytv/CardPresenter.kt +++ b/app/src/main/java/com/lizongying/mytv/CardPresenter.kt @@ -1,17 +1,17 @@ package com.lizongying.mytv +import android.content.Context import android.graphics.Color import android.view.ContextThemeWrapper import android.view.ViewGroup import android.widget.ImageView import androidx.leanback.widget.ImageCardView import androidx.leanback.widget.Presenter -import androidx.lifecycle.LifecycleOwner import com.bumptech.glide.Glide import com.lizongying.mytv.models.TVViewModel class CardPresenter( - private val owner: LifecycleOwner, + private val context: Context, ) : Presenter() { override fun onCreateViewHolder(parent: ViewGroup): ViewHolder { @@ -39,6 +39,20 @@ class CardPresenter( cardView.setBackgroundColor(Color.WHITE) cardView.setMainImageScaleType(ImageView.ScaleType.CENTER_INSIDE) +// cardView.setOnFocusChangeListener { v, hasFocus -> +// run { +// if (hasFocus) { +// if (v != null) { +// (v as ImageCardView).setInfoAreaBackgroundColor(context.resources.getColor(R.color.focus)) +// } +// } else { +// if (v != null) { +// (v as ImageCardView).setInfoAreaBackgroundColor(context.resources.getColor(R.color.ic_launcher_background)) +// } +// } +// } +// } + val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() } if (!epg.isNullOrEmpty()) { cardView.contentText = epg.last().title diff --git a/app/src/main/java/com/lizongying/mytv/ConfirmationDialogFragment.kt b/app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt similarity index 72% rename from app/src/main/java/com/lizongying/mytv/ConfirmationDialogFragment.kt rename to app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt index 2100510a..87d58be3 100644 --- a/app/src/main/java/com/lizongying/mytv/ConfirmationDialogFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/ConfirmationFragment.kt @@ -5,14 +5,16 @@ import android.app.Dialog import android.os.Bundle import androidx.fragment.app.DialogFragment -class ConfirmationDialogFragment(private val listener: ConfirmationDialogListener) : - DialogFragment() { +class ConfirmationFragment( + private val listener: ConfirmationListener, + private val message: String +) : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = AlertDialog.Builder(it) - builder.setTitle("确认") - .setMessage("确认更新吗?") + builder.setTitle("确定更新吗?") + .setMessage(message) .setPositiveButton( "确定" ) { _, _ -> @@ -23,12 +25,11 @@ class ConfirmationDialogFragment(private val listener: ConfirmationDialogListene ) { _, _ -> listener.onCancel() } - // 创建并返回 AlertDialog 对象 builder.create() } ?: throw IllegalStateException("Activity cannot be null") } - interface ConfirmationDialogListener { + interface ConfirmationListener { fun onConfirm() fun onCancel() } diff --git a/app/src/main/java/com/lizongying/mytv/MainActivity.kt b/app/src/main/java/com/lizongying/mytv/MainActivity.kt index 8099f422..630608fb 100644 --- a/app/src/main/java/com/lizongying/mytv/MainActivity.kt +++ b/app/src/main/java/com/lizongying/mytv/MainActivity.kt @@ -71,9 +71,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener { .add(R.id.main_browse_fragment, infoFragment) .add(R.id.main_browse_fragment, channelFragment) .add(R.id.main_browse_fragment, mainFragment) -// .add(R.id.main_browse_fragment, errorFragment) .hide(mainFragment) -// .hide(errorFragment) .commit() } gestureDetector = GestureDetector(this, GestureListener()) @@ -169,11 +167,15 @@ class MainActivity : FragmentActivity(), Request.RequestListener { handler.postDelayed(hideMain, delayHideMain) } - fun settingActive() { + fun settingDelayHide() { handler.removeCallbacks(hideSetting) handler.postDelayed(hideSetting, delayHideSetting) } + fun settingNeverHide() { + handler.removeCallbacks(hideSetting) + } + private val hideMain = Runnable { if (!mainFragment.isHidden) { supportFragmentManager.beginTransaction().hide(mainFragment).commit() @@ -268,7 +270,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener { Log.i(TAG, "settingFragment ${settingFragment.isVisible}") if (!settingFragment.isVisible) { settingFragment.show(supportFragmentManager, "setting") - settingActive() + settingDelayHide() } else { handler.removeCallbacks(hideSetting) settingFragment.dismiss() @@ -334,6 +336,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener { } override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + Log.i(TAG, "keyCode $keyCode, event $event") when (keyCode) { KeyEvent.KEYCODE_0 -> { showChannel("0") diff --git a/app/src/main/java/com/lizongying/mytv/MainFragment.kt b/app/src/main/java/com/lizongying/mytv/MainFragment.kt index 3fca2b7d..7fcdda81 100644 --- a/app/src/main/java/com/lizongying/mytv/MainFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/MainFragment.kt @@ -2,11 +2,13 @@ package com.lizongying.mytv import android.os.Bundle import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.leanback.app.BrowseSupportFragment import androidx.leanback.widget.ArrayObjectAdapter import androidx.leanback.widget.HeaderItem -import androidx.leanback.widget.ImageCardView import androidx.leanback.widget.ListRow import androidx.leanback.widget.ListRowPresenter import androidx.leanback.widget.ListRowPresenter.SelectItemViewHolderTask @@ -38,6 +40,29 @@ class MainFragment : BrowseSupportFragment() { headersState = HEADERS_DISABLED } +// override fun onCreateView( +// inflater: LayoutInflater, +// container: ViewGroup?, +// savedInstanceState: Bundle? +// ): View? { +// val rootView = super.onCreateView(inflater, container, savedInstanceState) +// rootView?.setOnClickListener { +// Log.i(TAG, "main on click") +// fragmentManager!!.beginTransaction().hide(this).commit() +// } +// mainFragment.view?.setOnClickListener { +// Log.i(TAG, "mainFragment on click") +// fragmentManager!!.beginTransaction().hide(this).commit() +// } +// getRowsSupportFragment().view?.setOnClickListener { +// Log.i(TAG, "getRowsSupportFragment on click") +// fragmentManager!!.beginTransaction().hide(this).commit() +// } +// +// +// return rootView +// } + override fun onStart() { Log.i(TAG, "onStart") super.onStart() @@ -122,7 +147,7 @@ class MainFragment : BrowseSupportFragment() { private fun loadRows() { rowsAdapter = ArrayObjectAdapter(ListRowPresenter()) - val cardPresenter = CardPresenter(viewLifecycleOwner) + val cardPresenter = CardPresenter(context!!) var idx: Long = 0 for ((k, v) in TVList.list) { @@ -133,8 +158,6 @@ class MainFragment : BrowseSupportFragment() { tvViewModel.setItemPosition(idx2) tvListViewModel.addTVViewModel(tvViewModel) listRowAdapter.add(tvViewModel) - - updateEPG(tvViewModel) } tvListViewModel.maxNum.add(v.size) val header = HeaderItem(idx, k) @@ -209,9 +232,6 @@ class MainFragment : BrowseSupportFragment() { itemViewHolder: Presenter.ViewHolder?, item: Any?, rowViewHolder: RowPresenter.ViewHolder, row: Row ) { -// if (itemViewHolder !=null) { -// (itemViewHolder.view as ImageCardView).setInfoAreaBackgroundColor(resources.getColor(R.color.focus)) -// } if (item is TVViewModel) { tvListViewModel.setItemPositionCurrent(item.getTV().id) (activity as MainActivity).mainActive() @@ -236,8 +256,11 @@ class MainFragment : BrowseSupportFragment() { } fun fragmentReady() { -// request.fetchPage() tvListViewModel.getTVViewModel(itemPosition)?.changed() + + tvListViewModel.tvListViewModel.value?.forEach { tvViewModel -> + updateEPG(tvViewModel) + } } fun play(itemPosition: Int) { diff --git a/app/src/main/java/com/lizongying/mytv/Request.kt b/app/src/main/java/com/lizongying/mytv/Request.kt index 903618ad..7da7d210 100644 --- a/app/src/main/java/com/lizongying/mytv/Request.kt +++ b/app/src/main/java/com/lizongying/mytv/Request.kt @@ -62,6 +62,8 @@ object Request { private var initRetryTimes = 0 private var initRetryMaxTimes = 0 + private var openid = "vu0-8lgGV2LW9QjDeucB9H12d_6HQWmTFgqCWg5o-VBQN4" + fun onCreate() { Log.i(TAG, "onCreate") fetchInfoV2() @@ -264,7 +266,7 @@ object Request { } } } else { - Log.e(TAG, "$title status error") + Log.e(TAG, "$title status error $data") if (tvModel.retryTimes < tvModel.retryMaxTimes) { tvModel.retryTimes++ if (tvModel.getTV().needToken) { @@ -319,13 +321,13 @@ object Request { tvModel.needGetToken = false tvModel.tokenYSPRetryTimes = 0 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) } else if (response.code() == 304) { tvModel.needGetToken = false tvModel.tokenYSPRetryTimes = 0 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) } else { Log.e(TAG, "info status error") @@ -358,7 +360,7 @@ object Request { }) } else { 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) } } @@ -376,13 +378,13 @@ object Request { tvModel.needGetToken = false tvModel.tokenYSPRetryTimes = 0 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) } else if (response.code() == 304) { tvModel.needGetToken = false tvModel.tokenYSPRetryTimes = 0 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) } else { Log.e(TAG, "info status error") @@ -415,7 +417,7 @@ object Request { }) } else { 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) } } @@ -495,10 +497,14 @@ object Request { .enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { + val o = response.body()?.o val t = response.body()?.t val f = response.body()?.f val e = response.body()?.e val c = response.body()?.c + if (!o.isNullOrEmpty()) { + openid = o + } if (!t.isNullOrEmpty()) { token = t Log.i(TAG, "token success $token") diff --git a/app/src/main/java/com/lizongying/mytv/SettingFragment.kt b/app/src/main/java/com/lizongying/mytv/SettingFragment.kt index cb6f9a59..f0f2392a 100644 --- a/app/src/main/java/com/lizongying/mytv/SettingFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/SettingFragment.kt @@ -34,7 +34,7 @@ class SettingFragment : DialogFragment() { isChecked = SP.channelReversal setOnCheckedChangeListener { _, isChecked -> SP.channelReversal = isChecked - (activity as MainActivity).settingActive() + (activity as MainActivity).settingDelayHide() } } @@ -42,7 +42,7 @@ class SettingFragment : DialogFragment() { isChecked = SP.channelNum setOnCheckedChangeListener { _, isChecked -> SP.channelNum = isChecked - (activity as MainActivity).settingActive() + (activity as MainActivity).settingDelayHide() } } @@ -50,23 +50,34 @@ class SettingFragment : DialogFragment() { isChecked = SP.bootStartup setOnCheckedChangeListener { _, isChecked -> SP.bootStartup = isChecked - (activity as MainActivity).settingActive() + (activity as MainActivity).settingDelayHide() } } updateManager = UpdateManager(context, this, context.appVersionCode) - binding.checkVersion.setOnClickListener(OnClickListenerCheckVersion(updateManager)) + binding.checkVersion.setOnClickListener( + OnClickListenerCheckVersion( + activity as MainActivity, + updateManager + ) + ) return binding.root } 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 { override fun onClick(view: View?) { + mainActivity.settingDelayHide() updateManager.checkAndUpdate() } } diff --git a/app/src/main/java/com/lizongying/mytv/TVList.kt b/app/src/main/java/com/lizongying/mytv/TVList.kt index e0a3bf36..bb643758 100644 --- a/app/src/main/java/com/lizongying/mytv/TVList.kt +++ b/app/src/main/java/com/lizongying/mytv/TVList.kt @@ -960,7 +960,7 @@ object TVList { } } val array = arrayOf("央视", "地方") - list = list.filterKeys { it in array } +// list = list.filterKeys { it in array } return list } } \ No newline at end of file diff --git a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt index 4f84dace..d2833388 100644 --- a/app/src/main/java/com/lizongying/mytv/UpdateManager.kt +++ b/app/src/main/java/com/lizongying/mytv/UpdateManager.kt @@ -30,7 +30,7 @@ class UpdateManager( private var settingFragment: SettingFragment, private var versionCode: Long ) : - ConfirmationDialogFragment.ConfirmationDialogListener { + ConfirmationFragment.ConfirmationListener { private var myRequest = MyRequest() private var release: ReleaseV2? = null @@ -47,12 +47,10 @@ class UpdateManager( release = myRequest.getRelease() Log.i(TAG, "versionCode $versionCode ${release?.c}") if (release?.c != null) { - if (release?.c!! >= versionCode) { - text = "最新版本:${release?.n}" - val dialog = ConfirmationDialogFragment(this@UpdateManager) - dialog.show(settingFragment.fragmentManager, "ConfirmationDialogFragment") + text = if (release?.c!! > versionCode) { + "最新版本:${release?.n}\n${release?.d ?: ""}" } else { - text = "已是最新版本,不需要更新" + "已是最新版本,不需要更新" } } } catch (e: Exception) { @@ -63,10 +61,11 @@ class UpdateManager( } private fun updateUI(text: String) { - settingFragment.setVersionName(text) + val dialog = ConfirmationFragment(this@UpdateManager, text) + dialog.show(settingFragment.fragmentManager, TAG) } - fun haveStoragePermission(): Boolean { + private fun haveStoragePermission(): Boolean { if (Build.VERSION.SDK_INT >= 23) { if (checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) === PermissionChecker.PERMISSION_GRANTED @@ -102,7 +101,7 @@ class UpdateManager( Environment.DIRECTORY_DOWNLOADS, apkFileName ) - request.setTitle("New Version Download") + request.setTitle("${settingFragment.resources.getString(R.string.app_name)} ${release.n}") request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) request.setAllowedOverRoaming(false) request.setMimeType("application/vnd.android.package-archive") 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 182f17a9..ac6da94f 100644 --- a/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt +++ b/app/src/main/java/com/lizongying/mytv/api/ApiClient.kt @@ -128,9 +128,12 @@ class ApiClient { val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, trustAllCerts, java.security.SecureRandom()) + val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("10.0.2.2", 8888)) + val builder = OkHttpClient.Builder() .sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager) .hostnameVerifier { _, _ -> true } +// .proxy(proxy) .dns(DnsCache()) return enableTls12OnPreLollipop(builder).build() diff --git a/app/src/main/java/com/lizongying/mytv/api/Info.kt b/app/src/main/java/com/lizongying/mytv/api/Info.kt index 4a2e381e..9fd7c4c4 100644 --- a/app/src/main/java/com/lizongying/mytv/api/Info.kt +++ b/app/src/main/java/com/lizongying/mytv/api/Info.kt @@ -16,6 +16,7 @@ data class Token( ) data class InfoV2( + val o: String?, val f: String?, val t: String?, val e: Int?, @@ -25,6 +26,7 @@ data class InfoV2( data class ReleaseV2( val n: String?, val u: String?, + val d: String?, val c: Int?, ) diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml new file mode 100644 index 00000000..55344e51 --- /dev/null +++ b/app/src/main/res/values/ids.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file