From 006da737378a53ee2495ed2e58181493bb94879f Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 17 Apr 2020 17:44:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=8E=86=E5=8F=B2=E7=89=88=E6=9C=AC=E5=8A=9F=E8=83=BD?= =?UTF-8?q?(=E9=83=A8=E5=88=86UI=E7=BB=86=E8=8A=82=E5=BE=85=E5=AE=8C?= =?UTF-8?q?=E5=96=84)=20https://gitlab.ghzs.com/pm/halo-app-issues/issues/?= =?UTF-8?q?832?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 4 + .../com/gh/common/constant/Constants.java | 2 + .../com/gh/common/util/DownloadObserver.kt | 8 +- .../com/gh/common/util/EntranceUtils.java | 1 + .../java/com/gh/common/util/GameUtils.java | 47 +++++- .../java/com/gh/common/util/InstallUtils.java | 4 +- .../java/com/gh/gamecenter/MainActivity.java | 16 +- .../com/gh/gamecenter/entity/ApkEntity.kt | 10 +- .../com/gh/gamecenter/entity/GameInstall.kt | 2 + .../com/gh/gamecenter/eventbus/EBPackage.java | 11 +- .../gamecenter/gamedetail/desc/DescAdapter.kt | 4 +- .../history/HistoryApkListActivity.kt | 28 ++++ .../history/HistoryApkListAdapter.kt | 149 ++++++++++++++++++ .../history/HistoryApkListFragment.kt | 86 ++++++++++ .../history/HistoryApkListViewModel.kt | 53 +++++++ .../gh/gamecenter/manager/PackagesManager.kt | 21 +++ .../receiver/InstallAndUninstallReceiver.java | 10 +- .../retrofit/service/ApiService.java | 7 + .../detail/VideoDetailContainerFragment.kt | 3 + .../res/drawable/divider_history_apks.xml | 6 + .../res/layout/fragment_history_apk_list.xml | 33 ++++ app/src/main/res/layout/item_history_apk.xml | 77 +++++++++ app/src/main/res/values/colors.xml | 2 + app/src/main/res/values/strings.xml | 2 + libraries/LGLibrary | 2 +- 25 files changed, 570 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListActivity.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListAdapter.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListFragment.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListViewModel.kt create mode 100644 app/src/main/res/drawable/divider_history_apks.xml create mode 100644 app/src/main/res/layout/fragment_history_apk_list.xml create mode 100644 app/src/main/res/layout/item_history_apk.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index da9865ec99..ad01ca7571 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -115,6 +115,10 @@ android:name="com.gh.gamecenter.ShellActivity" android:screenOrientation="portrait" /> + + diff --git a/app/src/main/java/com/gh/common/constant/Constants.java b/app/src/main/java/com/gh/common/constant/Constants.java index 4d26d76515..c1df526751 100644 --- a/app/src/main/java/com/gh/common/constant/Constants.java +++ b/app/src/main/java/com/gh/common/constant/Constants.java @@ -29,6 +29,8 @@ public class Constants { public static final String EB_QUIT_LOGIN = "quit_login"; + public static final String GAME_ID_DIVIDER = ":"; // 用于避免历史下载掺和到普通下载状态的 ID 修饰符 + // 最近显示的弹窗信息 public static final String SP_LAST_OPENING_ID = "last_opening_dialog_id"; public static final String SP_LAST_OPENING_TIME = "last_opening_dialog_time"; diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 8ff787cc83..36f57b1922 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -42,6 +42,8 @@ object DownloadObserver { fun initObserver() { val dataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { + val gameId = downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER) + if (downloadEntity.status != DownloadStatus.downloading) { LogUtils.uploadDownloadEvent(downloadEntity) } @@ -70,7 +72,7 @@ object DownloadObserver { SuggestionActivity.startSuggestionActivity(AppManager.getInstance().currentActivity(), SuggestType.gameQuestion, "notfound", StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"), - SimpleGameEntity(downloadEntity.gameId, downloadEntity.name, "")) + SimpleGameEntity(gameId, downloadEntity.name, "")) }, null) return } else if (DownloadStatus.neterror == downloadEntity.status || DownloadStatus.timeout == downloadEntity.status) { @@ -126,7 +128,7 @@ object DownloadObserver { } // 统计下载完成 - uploadData(downloadEntity.gameId, downloadEntity.platform) + uploadData(gameId, downloadEntity.platform) } // 下载过程分析统计 @@ -201,7 +203,7 @@ object DownloadObserver { } ExposureUtils.logADownloadCompleteExposureEvent( - GameEntity(downloadEntity.gameId, downloadEntity.name), + GameEntity(downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER), downloadEntity.name), downloadEntity.platform, downloadEntity.exposureTrace, type) diff --git a/app/src/main/java/com/gh/common/util/EntranceUtils.java b/app/src/main/java/com/gh/common/util/EntranceUtils.java index 7cbd78e8f1..bf1de3083f 100644 --- a/app/src/main/java/com/gh/common/util/EntranceUtils.java +++ b/app/src/main/java/com/gh/common/util/EntranceUtils.java @@ -86,6 +86,7 @@ public class EntranceUtils { public static final String KEY_OLDERUSER = "isOldUser"; public static final String KEY_SEARCHKEY = "searchKey"; public static final String KEY_HINT = "hint"; + public static final String KEY_GAME = "game"; public static final String KEY_GAME_ICON_URL = "gameIconUrl"; public static final String KEY_SHARECONTENT = "shareContent"; public static final String KEY_SUGGESTTYPE = "suggestType"; diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 302ea66ff5..9361f82f09 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -5,8 +5,6 @@ import android.graphics.Color; import android.text.TextUtils; import android.widget.TextView; -import androidx.core.content.ContextCompat; - import com.gh.common.constant.Config; import com.gh.download.DownloadManager; import com.gh.gamecenter.R; @@ -21,6 +19,8 @@ import com.lightgame.download.DownloadStatus; import java.util.List; +import androidx.core.content.ContextCompat; + public class GameUtils { @@ -133,6 +133,49 @@ public class GameUtils { } } + /** + * 获取简单的下载按钮文案,只需要知道是否已下载,是否已安装 + */ + public static String getSimpleDownloadBtnText(Context context, GameEntity gameEntity) { + int doneCount = 0; // 下载完成数量 + int installCount = 0; // 已安装数量 + + DownloadEntity downloadEntity; + Object gh_id; + apkFor: + for (ApkEntity apkEntity : gameEntity.getApk()) { + // filter by packageName + SettingsEntity settings = Config.getSettings(); + if (settings != null && gameEntity.getApk().size() > 1) { + for (String pkgName : settings.getGameDownloadBlackList()) { + if (pkgName.equals(apkEntity.getPackageName())) { + continue apkFor; + } + } + } + + downloadEntity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.getUrl()); + if (downloadEntity != null) { + if (downloadEntity.getStatus().equals(DownloadStatus.done)) { + doneCount++; + } + } + if (PackagesManager.INSTANCE.isInstalled(apkEntity.getPackageName())) { + gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id"); + if (gh_id == null || gh_id.equals(gameEntity.getId())) { + installCount++; + } + } + } + if (doneCount != 0) { + return context.getString(R.string.install); + } else if (installCount != 0) { + return context.getString(R.string.launch); + } else { + return context.getString(R.string.download); + } + } + /** * 获取GameUpdateEntity */ diff --git a/app/src/main/java/com/gh/common/util/InstallUtils.java b/app/src/main/java/com/gh/common/util/InstallUtils.java index e604429479..71994718b6 100644 --- a/app/src/main/java/com/gh/common/util/InstallUtils.java +++ b/app/src/main/java/com/gh/common/util/InstallUtils.java @@ -68,7 +68,7 @@ public class InstallUtils { if (!TextUtils.isEmpty(installVersion) && downloadEntity != null && installVersion.equals(downloadEntity.getVersionName())) { if (!downloadEntity.isPluggable() || PackageUtils.isSignature(context, packageName)) { - EventBus.getDefault().post(new EBPackage("安装", packageName)); + EventBus.getDefault().post(new EBPackage("安装", packageName, installVersion)); } } } @@ -85,7 +85,7 @@ public class InstallUtils { keys.add(packageName); } else if (!list.contains(packageName)) { keys.add(packageName); - EventBus.getDefault().post(new EBPackage("卸载", packageName)); + EventBus.getDefault().post(new EBPackage("卸载", packageName, "")); } } for (String key : keys) { diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index a678807026..0f2116a0f3 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -694,15 +694,23 @@ public class MainActivity extends BaseActivity { @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(EBPackage busFour) { final String packageName = busFour.getPackageName(); + final String versionName = busFour.getVersionName(); String gameId = ""; DownloadEntity mDownloadEntity = null; for (DownloadEntity downloadEntity : DownloadManager.getInstance(getApplicationContext()).getAll()) { - //todo 根据包名获取DownloadEntity? 假如存在相同包名的下载任务,有可能会删除错误 if (packageName.equals(downloadEntity.getPackageName())) { mDownloadEntity = downloadEntity; - gameId = mDownloadEntity.getGameId(); - break; + gameId = mDownloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER); + if (TextUtils.isEmpty(busFour.getVersionName())) { + // 没有版本号的事件直接选用第一个找到的 downloadEntity + break; + } else { + // 有版本号的事件直接尽量找到版本一致的 downloadEntity + if (versionName.equals(downloadEntity.getVersionName())) { + break; + } + } } } @@ -748,7 +756,7 @@ public class MainActivity extends BaseActivity { public void onResponse(List response) { for (GameDigestEntity gameDigestEntity : response) { if (!TextUtils.isEmpty(gameDigestEntity.getId())) { // 关注游戏 - if (finalDownloadEntity != null && gameDigestEntity.getId().equals(finalDownloadEntity.getGameId())) { + if (finalDownloadEntity != null && gameDigestEntity.getId().equals(finalDownloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER))) { ConcernUtils.INSTANCE.postConcernGameId(MainActivity.this, gameDigestEntity.getId(), null, false); } } diff --git a/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt index fff172dd3e..58a37f47e8 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt @@ -29,7 +29,15 @@ data class ApkEntity(@SerializedName("package") @SerializedName("platform_icon") val platformIcon: String = "", @SerializedName("download_instruction") - val downloadInstruction: String = "") : Parcelable { + val downloadInstruction: String = "", + + // 以下是历史版本用的字段,其它地方可能会没有 + @SerializedName("update_time") + var updateTime: Long = 0, + @SerializedName("update_des") + var updateDesc: String = "", + @SerializedName("download_status") + var downloadStatus: String = "") : Parcelable { fun getPlatform(): String? { if (TextUtils.isEmpty(platform)) { return "官方版" diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt index 65c75556e3..d9c0b112d6 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt @@ -12,6 +12,7 @@ data class GameInstall( var icon: String? = "", var isSignature: Boolean = false, var installTime: Long = 0, + var version: String = "", var tag: Any? = null) { companion object { @@ -23,6 +24,7 @@ data class GameInstall( gameInstall.id = game.id gameInstall.name = game.name gameInstall.icon = game.icon + gameInstall.version = PackageUtils.getVersionByPackage(installedPkgName) gameInstall.packageName = installedPkgName return gameInstall } diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java index be7b5d63d4..79b5736e40 100644 --- a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java +++ b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java @@ -4,10 +4,12 @@ public class EBPackage { private String type; private String packageName; + private String versionName; - public EBPackage(String type, String packageName) { + public EBPackage(String type, String packageName, String versionName) { this.type = type; this.packageName = packageName; + this.versionName = versionName; } public String getType() { @@ -26,4 +28,11 @@ public class EBPackage { this.packageName = packageName; } + public String getVersionName() { + return versionName; + } + + public void setVersionName(String versionName) { + this.versionName = versionName; + } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt index 53cc771f8f..9fc2def5c0 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt @@ -32,6 +32,7 @@ import com.gh.gamecenter.gamedetail.GameDetailFragment import com.gh.gamecenter.gamedetail.entity.DetailEntity import com.gh.gamecenter.gamedetail.entity.GameInfo import com.gh.gamecenter.gamedetail.entity.UpdateContent +import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity import com.gh.gamecenter.home.amway.LeftPagerSnapHelper import com.gh.gamecenter.suggest.SuggestType import com.lightgame.adapter.BaseRecyclerAdapter @@ -448,7 +449,8 @@ class DescAdapter(context: Context, private fun bindUpdateContentViewHolder(holder: GameUpdateContentViewHolder, updateContent: UpdateContent?) { holder.binding.contentTv.text = updateContent?.updateDes ?: "" holder.binding.historyVersionTv.setOnClickListener { - ToastUtils.showToast("历史版本") + val intent = HistoryApkListActivity.getIntent(mContext, mViewModel.game ?: GameEntity(), mEntrance, "更新内容") + mContext.startActivity(intent) } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListActivity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListActivity.kt new file mode 100644 index 0000000000..e2693f0d93 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListActivity.kt @@ -0,0 +1,28 @@ +package com.gh.gamecenter.gamedetail.history + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.gh.base.BaseActivity +import com.gh.common.util.EntranceUtils +import com.gh.gamecenter.NormalActivity +import com.gh.gamecenter.R +import com.gh.gamecenter.entity.GameEntity + +class HistoryApkListActivity : NormalActivity() { + + companion object { + fun getIntent(context: Context, gameEntity: GameEntity, entrance: String, path: String): Intent { + val bundle = Bundle() + bundle.putString(EntranceUtils.KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path)) + bundle.putParcelable(EntranceUtils.KEY_GAME, gameEntity) + return getTargetIntent(context, HistoryApkListActivity::class.java, HistoryApkListFragment::class.java, bundle) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setNavigationTitle(R.string.title_history_apk) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListAdapter.kt new file mode 100644 index 0000000000..196b9b95cf --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListAdapter.kt @@ -0,0 +1,149 @@ +package com.gh.gamecenter.gamedetail.history + +import android.content.Context +import android.graphics.Color +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.g00fy2.versioncompare.Version +import com.gh.common.constant.ItemViewType +import com.gh.common.util.* +import com.gh.download.DownloadManager +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.viewholder.FooterViewHolder +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.databinding.ItemHistoryApkBinding +import com.gh.gamecenter.entity.ApkEntity +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.manager.PackagesManager +import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus +import com.lightgame.utils.Utils + +class HistoryApkListAdapter(context: Context, private var mViewModel: HistoryApkListViewModel) : ListAdapter(context) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val view: View + return when (viewType) { + ItemViewType.ITEM_FOOTER -> { + view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false) + FooterViewHolder(view) + } + ItemViewType.ITEM_BODY -> { + view = mLayoutInflater.inflate(R.layout.item_history_apk, parent, false) + HistoryApkViewHolder(ItemHistoryApkBinding.bind(view)) + } + else -> throw NullPointerException() + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + when (holder) { + is HistoryApkViewHolder -> { + val gameEntity = mEntityList[position] + val apkEntity = gameEntity.getApk().first() + + holder.binding.apk = apkEntity + holder.binding.releaseDateTv.text = TimeUtils.getFormatTime(apkEntity.updateTime * 1000, "yyyy.MM.dd") + holder.binding.downloadBtn.run { + DownloadItemUtils.setOnClickListener( + holder.binding.root.context, + this, + gameEntity, + 0, + this@HistoryApkListAdapter, + "历史版本", + "", + null, + object : EmptyCallback { + override fun onCallback() { + showDowngradeToastIfNeed(apkEntity, holder.binding.downloadBtn.text) + } + }) + + if (apkEntity.downloadStatus == "off") { + visibility = View.INVISIBLE + } else if (gameEntity.getApk().size == 1) { + visibility = View.VISIBLE + setDownloadBtnStatus(mContext, gameEntity, this) + val downloadEntity = DownloadManager.getInstance(mContext).getDownloadEntityByUrl(apkEntity.url) + if (downloadEntity != null) { + if (downloadEntity.status == DownloadStatus.done) { + if (PackagesManager.isInstalledWithSpecificVersion(downloadEntity.packageName, downloadEntity.versionName)) { + setText(R.string.launch) + } else { + setText(R.string.install) + } + } else { + if (downloadEntity.status == DownloadStatus.waiting) { + setText(R.string.waiting) + } else { + setText(R.string.downloading) + } + } + } else { + if (PackagesManager.isInstalledWithSpecificVersion(apkEntity.packageName, apkEntity.version + ?: "")) { + setText(R.string.launch) + } + } + } + } + } +// is FooterViewHolder -> { +// holder.initItemPadding() +// holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint) +// } + } + } + + private fun showDowngradeToastIfNeed(apkEntity: ApkEntity, btnText: CharSequence) { + if (btnText == "安装" || btnText == "下载") { + if (PackageUtils.isInstalled(mContext, apkEntity.packageName)) { + val installedVersion = PackageUtils.getVersionByPackage(apkEntity.packageName) + if (Version(installedVersion).isHigherThan(Version(apkEntity.version))) { + Utils.toast(mContext, "您已安装较高版本,若要安装历史版本需先卸载再安装~") + } + } + } + } + + override fun getItemViewType(position: Int): Int { + return ItemViewType.ITEM_BODY +// return if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY + } + + override fun getItemCount(): Int { + return if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size +// return if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT + } + + private fun setDownloadBtnStatus(context: Context, gameEntity: GameEntity, downloadBtn: TextView) { + val status = GameUtils.getSimpleDownloadBtnText(context, gameEntity) + downloadBtn.text = status + if ("启动" == status) { + downloadBtn.setBackgroundResource(R.drawable.detail_download_open_style) + downloadBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font)) + } else { + downloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style) + downloadBtn.setTextColor(Color.WHITE) + } + } + + fun notifyItemByDownload(downloadEntity: DownloadEntity?) { + if (downloadEntity == null) { + notifyDataSetChanged() + } else { + for (position in mEntityList.indices) { + val gameEntity = mEntityList[position] + if (downloadEntity.gameId == gameEntity.id) { + notifyItemChanged(position) + } + } + } + } + + class HistoryApkViewHolder(var binding: ItemHistoryApkBinding) : RecyclerView.ViewHolder(binding.root) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListFragment.kt new file mode 100644 index 0000000000..531ce2a8f7 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListFragment.kt @@ -0,0 +1,86 @@ +package com.gh.gamecenter.gamedetail.history + +import android.graphics.drawable.InsetDrawable +import android.os.Bundle +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.* +import com.gh.download.DownloadManager +import com.gh.gamecenter.R +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.eventbus.EBPackage +import com.halo.assistant.HaloApp +import com.lightgame.download.DataWatcher +import com.lightgame.download.DownloadEntity +import kotlinx.android.synthetic.main.fragment_history_apk_list.* +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode + +class HistoryApkListFragment : ListFragment() { + + private var mAdapter: HistoryApkListAdapter? = null + private var mViewModel: HistoryApkListViewModel? = null + + private val dataWatcher = object : DataWatcher() { + override fun onDataChanged(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + mViewModel?.showDowngradeHint?.observeNonNull(this) { + tipsContainer.goneIf(!it) + } + } + + override fun onResume() { + super.onResume() + DownloadManager.getInstance(context).addObserver(dataWatcher) + } + + override fun onPause() { + super.onPause() + DownloadManager.getInstance(context).removeObserver(dataWatcher) + } + + override fun getItemDecoration(): RecyclerView.ItemDecoration { + val insetDivider = InsetDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.divider_history_apks), DisplayUtils.dip2px(20F), 0, DisplayUtils.dip2px(20F), 0) + val itemDecoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) + itemDecoration.setDrawable(insetDivider) + return itemDecoration + } + + override fun getLayoutId(): Int { + return R.layout.fragment_history_apk_list + } + + override fun provideListViewModel(): HistoryApkListViewModel { + if (mViewModel == null) { + val factory = HistoryApkListViewModel.Factory( + HaloApp.getInstance().application, + arguments?.getParcelable(EntranceUtils.KEY_GAME) ?: GameEntity()) + mViewModel = viewModelProvider(factory) + } + + return mViewModel!! + } + + override fun provideListAdapter(): ListAdapter<*> { + if (mAdapter == null) { + mAdapter = HistoryApkListAdapter(requireContext(), mViewModel!!) + } + return mAdapter!! + } + + //安装、卸载事件 + @Subscribe(threadMode = ThreadMode.MAIN) + fun onEventMainThread(busFour: EBPackage) { + mAdapter?.notifyDataSetChanged() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListViewModel.kt new file mode 100644 index 0000000000..cfd25f2a7c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/history/HistoryApkListViewModel.kt @@ -0,0 +1,53 @@ +package com.gh.gamecenter.gamedetail.history + +import android.app.Application +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.gh.common.constant.Constants +import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.entity.ApkEntity +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.retrofit.RetrofitManager +import io.reactivex.Observable +import io.reactivex.Single + +class HistoryApkListViewModel(application: Application, var game: GameEntity) + : ListViewModel(application) { + + val showDowngradeHint = MutableLiveData() + + override fun provideDataObservable(page: Int): Observable>? { + return null + } + + override fun provideDataSingle(page: Int): Single> { + return RetrofitManager.getInstance(getApplication()).api.getHistoryApks(game.id, page) + } + + override fun mergeResultLiveData() { + mResultLiveData.addSource(mListLiveData) { + val gameList = arrayListOf() + for (apk in it) { + gameList.add(game.clone().apply { + // 改变 id 避免其它地方根据原有 game id 变更状态 + this.isReservable = false + this.id = game.id + Constants.GAME_ID_DIVIDER + apk.version + this.setApk(arrayListOf(apk)) + }) + } + if (gameList.isNotEmpty() && gameList.first().getApk().first().downloadStatus != "off") { + showDowngradeHint.postValue(true) + } + mResultLiveData.postValue(gameList) + } + } + + class Factory(private val mApplication: Application, + private val game: GameEntity) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return HistoryApkListViewModel(mApplication, game) as T + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt b/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt index 2f2482c14e..2c3f5a2237 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt +++ b/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt @@ -107,6 +107,27 @@ object PackagesManager { return installedPkgList.contains(packageName) } + /** + * 根据包名版本号判断是否已安装相应版本的应用 + * + * @param packageName 包名 + * @param versionName 版本号 + * @return true 已安装 false 未安装 + */ + @JvmStatic + fun isInstalledWithSpecificVersion(packageName: String?, versionName: String): Boolean { + if (TextUtils.isEmpty(packageName)) { + return false + } + + return if (installedPkgList.contains(packageName)) { + val installData = getInstalledData(packageName) + installData?.version == versionName + } else { + false + } + } + /** * 根据包名 获取已安装的信息 * diff --git a/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java b/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java index 4a9d9a2f80..abd36fae78 100644 --- a/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java +++ b/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java @@ -7,6 +7,7 @@ import android.content.Intent; import com.gh.common.util.DataUtils; import com.gh.common.util.InstallUtils; import com.gh.common.util.PackageHelper; +import com.gh.common.util.PackageUtils; import com.gh.gamecenter.eventbus.EBPackage; import com.lightgame.utils.Utils; @@ -30,7 +31,9 @@ public class InstallAndUninstallReceiver extends BroadcastReceiver { Utils.log("安装了:" + packageName + "包名的程序"); InstallUtils.getInstance(context).removeInstall(packageName); PackageHelper.refreshLocalPackageList(); - EventBus.getDefault().post(new EBPackage("安装", packageName)); + + String versionName = PackageUtils.getVersionByPackage(packageName); + EventBus.getDefault().post(new EBPackage("安装", packageName, versionName)); } // 接收卸载广播 @@ -40,7 +43,7 @@ public class InstallAndUninstallReceiver extends BroadcastReceiver { Utils.log("卸载了:" + packageName + "包名的程序"); InstallUtils.getInstance(context).removeUninstall(packageName); PackageHelper.refreshLocalPackageList(); - EventBus.getDefault().post(new EBPackage("卸载", packageName)); + EventBus.getDefault().post(new EBPackage("卸载", packageName, "")); } // 接收替换广播 @@ -51,7 +54,8 @@ public class InstallAndUninstallReceiver extends BroadcastReceiver { if (packageName.equals(context.getPackageName())) { DataUtils.onEvent(context, "软件更新", "更新完成"); } - EventBus.getDefault().post(new EBPackage("替换", packageName)); + String versionName = PackageUtils.getVersionByPackage(packageName); + EventBus.getDefault().post(new EBPackage("替换", packageName, versionName)); } } diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 634b1ef89e..e6f86ed184 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -3,6 +3,7 @@ package com.gh.gamecenter.retrofit.service; import com.gh.gamecenter.entity.AddonsUnreadEntity; import com.gh.gamecenter.entity.AliasEntity; import com.gh.gamecenter.entity.AmwayCommentEntity; +import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.AppEntity; import com.gh.gamecenter.entity.BadgeEntity; import com.gh.gamecenter.entity.CategoryEntity; @@ -2298,6 +2299,12 @@ public interface ApiService { @POST("users/{user_id}/me") Single getUserRelatedInfoByPost(@Path("user_id") String userId, @Body RequestBody body); + /** + * 获取游戏历史包列表 + */ + @GET("games/{game_id}/history_apks") + Single> getHistoryApks(@Path("game_id") String gameId, @Query("page") int page); + /** * 获取游戏设备弹窗列表 */ diff --git a/app/src/main/java/com/gh/gamecenter/video/detail/VideoDetailContainerFragment.kt b/app/src/main/java/com/gh/gamecenter/video/detail/VideoDetailContainerFragment.kt index d62127b524..babfa4b572 100644 --- a/app/src/main/java/com/gh/gamecenter/video/detail/VideoDetailContainerFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/video/detail/VideoDetailContainerFragment.kt @@ -185,6 +185,9 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener { } private fun initListener() { + // 根据闪退反馈,离开页面一段时间以后,有时候这里的 recyclerview 会为空 + if (recyclerview == null) return + recyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) diff --git a/app/src/main/res/drawable/divider_history_apks.xml b/app/src/main/res/drawable/divider_history_apks.xml new file mode 100644 index 0000000000..bf5adc03e7 --- /dev/null +++ b/app/src/main/res/drawable/divider_history_apks.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_history_apk_list.xml b/app/src/main/res/layout/fragment_history_apk_list.xml new file mode 100644 index 0000000000..27a83679ee --- /dev/null +++ b/app/src/main/res/layout/fragment_history_apk_list.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_history_apk.xml b/app/src/main/res/layout/item_history_apk.xml new file mode 100644 index 0000000000..0dbd1ba101 --- /dev/null +++ b/app/src/main/res/layout/item_history_apk.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 1bb9648400..2eca760504 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -101,6 +101,7 @@ #d6d5ff #f8f8f8 #e5e5e5 + #ECF6FF #80000000 #404040 #ededed @@ -135,6 +136,7 @@ #FF700F #181927 #e6f3ff + #1383EB #1F89EC #EEF5FB #C1BFC9 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce7ab77119..0dee3ae06d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -251,6 +251,7 @@ 意见反馈 %s - 求版本 游戏上传 + 历史版本 我的游戏评论 资讯 @@ -642,6 +643,7 @@ 请勿上传色情、反动等违规视频,上传视频即表示您已阅读并同意 《光环助手用户协议》 与 《视频上传服务准则》 + tips:新旧版不能共存,安装历史版本需要先卸载您已安装的较高版本 游戏*]]> 标题*]]> diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 11e48b1285..3b2b38cebd 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 11e48b1285c4eae8a03b9b7c869946f5dde539bb +Subproject commit 3b2b38cebd0e03d9178d0ea7bbc11827747461c2