diff --git a/app/src/main/java/com/gh/gamecenter/InstallActivity.java b/app/src/main/java/com/gh/gamecenter/InstallActivity.java index d6c673388c..2195ca70b7 100644 --- a/app/src/main/java/com/gh/gamecenter/InstallActivity.java +++ b/app/src/main/java/com/gh/gamecenter/InstallActivity.java @@ -1,5 +1,6 @@ package com.gh.gamecenter; +import android.arch.lifecycle.ViewModelProviders; import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -22,9 +23,9 @@ import com.gh.download.DownloadManager; import com.gh.gamecenter.adapter.InstallFragmentAdapter; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.eventbus.EBDownloadStatus; -import com.gh.gamecenter.eventbus.EBPackage; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.eventbus.EBSkip; +import com.gh.gamecenter.install.PackageViewModel; import com.lightgame.download.DataWatcher; import com.lightgame.download.DownloadEntity; @@ -55,7 +56,8 @@ public class InstallActivity extends BaseActivity implements InstallFragmentAdap TextView mNoDataSkipHint; @BindView(reuse_nodata_skip_tv_btn) TextView mNoDataSkipBtn; - + + private PackageViewModel mPackageViewModel; private InstallFragmentAdapter mAdapter; private boolean isEverpause = false; @@ -100,12 +102,9 @@ public class InstallActivity extends BaseActivity implements InstallFragmentAdap mNoDataSkip.setVisibility(View.GONE); mNoDataSkipHint.setText("暂无游戏"); mNoDataSkipBtn.setText("查看精品推荐"); - mNoDataSkipBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 0)); - finish(); - } + mNoDataSkipBtn.setOnClickListener(v -> { + EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 0)); + finish(); }); mInstallRv.setLayoutManager(new LinearLayoutManager(this)); @@ -113,6 +112,10 @@ public class InstallActivity extends BaseActivity implements InstallFragmentAdap mAdapter = new InstallFragmentAdapter(this); mInstallRv.addItemDecoration(new VerticalItemDecoration(this, 1, true)); mInstallRv.setAdapter(mAdapter); + + mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class); + mPackageViewModel.getGameInstalledLiveData().observe(this, + gameInstalls -> mAdapter.initData(mPackageViewModel.filterSameApk(gameInstalls))); } @Override @@ -170,17 +173,6 @@ public class InstallActivity extends BaseActivity implements InstallFragmentAdap } } - //安装、卸载事件 - @Subscribe(threadMode = ThreadMode.MAIN) - public void onEventMainThread(EBPackage busFour) { - if ("安装".equals(busFour.getType()) || "卸载".equals(busFour.getType())) { - mInstallRv.setVisibility(View.VISIBLE); - mNoDataSkip.setVisibility(View.GONE); - mAdapter = new InstallFragmentAdapter(this); - mInstallRv.setAdapter(mAdapter); - } - } - //下载被删除事件 @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(EBDownloadStatus status) { diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index 071877e376..0567841cb3 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -2,6 +2,7 @@ package com.gh.gamecenter; import android.app.Dialog; import android.app.NotificationManager; +import android.arch.lifecycle.ViewModelProviders; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -72,6 +73,7 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.eventbus.EBShowDialog; import com.gh.gamecenter.eventbus.EBSkip; import com.gh.gamecenter.fragment.MainWrapperFragment; +import com.gh.gamecenter.install.PackageViewModel; import com.gh.gamecenter.manager.DataCollectionManager; import com.gh.gamecenter.manager.FilterManager; import com.gh.gamecenter.manager.GameManager; @@ -145,6 +147,8 @@ public class MainActivity extends BaseActivity { public final static String SHOULD_INIT_IM = "should_init_im"; public final static String SWITCH_TO_COMMUNITY = "switch_to_community"; + private PackageViewModel mPackageViewModel; + private MainWrapperFragment mMainWrapperFragment; private SharedPreferences sp; @@ -751,7 +755,8 @@ public class MainActivity extends BaseActivity { DownloadManager.getInstance(this).addObserver(dataWatcher); // 检查是否有权限读取应用列表 - checkPermission(); +// checkPermission(); + mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class); final String message = Config.getExceptionMsg(this); if (!TextUtils.isEmpty(message)) { @@ -1061,6 +1066,8 @@ public class MainActivity extends BaseActivity { } if ("安装".equals(busFour.getType())) { + mPackageViewModel.addInstalledGame(packageName); + // 删除下载完成 弹窗 NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nManager.cancel(packageName.hashCode()); @@ -1127,6 +1134,7 @@ public class MainActivity extends BaseActivity { } if ("卸载".equals(busFour.getType())) { + mPackageViewModel.addUninstalledGame(packageName); // 删除map中数据 PackageManager.INSTANCE.removeInstalled(packageName); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/InstallFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/adapter/InstallFragmentAdapter.java index ea28dda881..90e59378a2 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/InstallFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/InstallFragmentAdapter.java @@ -23,7 +23,6 @@ import com.gh.common.util.GameViewUtils; import com.gh.common.util.ImageUtils; import com.gh.common.util.PackageUtils; import com.gh.common.util.PlatformUtils; -import com.gh.common.util.TrafficUtils; import com.gh.common.view.SwipeLayout; import com.gh.download.DownloadManager; import com.gh.gamecenter.GameDetailActivity; @@ -32,13 +31,11 @@ import com.gh.gamecenter.KcSelectGameActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.adapter.viewholder.FooterViewHolder; import com.gh.gamecenter.adapter.viewholder.GameNormalSwipeViewHolder; -import com.gh.gamecenter.db.info.InstallInfo; import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.entity.GameInfoEntity; import com.gh.gamecenter.kuaichuan.FileInfo; import com.gh.gamecenter.manager.GameManager; -import com.gh.gamecenter.manager.InstallManager; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.halo.assistant.HaloApp; @@ -49,7 +46,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Map; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -70,6 +66,7 @@ public class InstallFragmentAdapter extends BaseRecyclerAdapter { private ArrayList gameList; private ArrayList sortedList; + private ArrayList installedList; //下载用到的map private ArrayMap> locationMap; @@ -100,10 +97,14 @@ public class InstallFragmentAdapter extends BaseRecyclerAdapter { showKcHint = sp.getBoolean("showKcHint", true); maxWidth = mContext.getResources().getDisplayMetrics().widthPixels; + } - InstallManager cManager = new InstallManager(mContext); - List runnableGame = cManager.getAllInstall(); - if (runnableGame.isEmpty()) { + public void initData(ArrayList list) { + sortedList.clear(); + gameList.clear(); + this.installedList = list; + + if (installedList.isEmpty()) { mActivity.loadEmpty(); } else { HaloApp.getInstance().getMainExecutor().execute(new Runnable() { @@ -130,40 +131,20 @@ public class InstallFragmentAdapter extends BaseRecyclerAdapter { //初始化 private void init() { - - ArrayList list = new ArrayList<>(); ArrayList signatureList = new ArrayList<>(); // 是我们签名的游戏 ArrayList unsignatureList = new ArrayList<>(); // 不是我们签名的游戏 ArrayList noopenList = new ArrayList<>(); // 未打开过的游戏 ArrayList oftenuseList = new ArrayList<>(); // 已经打开过的游戏 - TrafficUtils trafficUtils = TrafficUtils.getInstance(mContext); - - InstallManager cManager = new InstallManager(mContext); - List runnableGame = cManager.getAllInstall(); - for (InstallInfo concernEntity : runnableGame) { - for (Map.Entry entry : concernEntity.getPackageNames().entrySet()) { - if (entry.getValue()) { - GameInfoEntity info = new GameInfoEntity(); - info.setId(concernEntity.getId()); - info.setPackageName(entry.getKey()); - info.setTraffic(trafficUtils.getTraffice(entry.getKey())); - info.setSignature(PackageUtils.isSignature(mContext, entry.getKey())); - info.setInstallTime(PackageUtils.getInstalledTime(mContext, entry.getKey())); - list.add(info); - } - } - } - ArrayMap> map = new ArrayMap<>(); ArrayList mList; - for (int i = 0, size = list.size(); i < size; i++) { - mList = map.get(list.get(i).getPackageName()); + for (int i = 0, size = installedList.size(); i < size; i++) { + mList = map.get(installedList.get(i).getPackageName()); if (mList == null) { mList = new ArrayList<>(); - map.put(list.get(i).getPackageName(), mList); + map.put(installedList.get(i).getPackageName(), mList); } - mList.add(list.get(i)); + mList.add(installedList.get(i)); } Comparator comparator = new Comparator() { @Override diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt new file mode 100644 index 0000000000..05518c1a94 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt @@ -0,0 +1,26 @@ +package com.gh.gamecenter.entity + +import com.google.gson.annotations.SerializedName + +data class GameInstall( + @SerializedName("_id") + var id: String? = "", + var packageMap: MutableMap = HashMap(), // key: pkgName value: isInstall + var name: String? = "", + var icon: String? = "") { + + companion object { + fun transformGameInstall(game: GameEntity, installedPkgName: String): GameInstall { + val packageMap = HashMap() + for (apkEntity in game.getApk()) { + packageMap[apkEntity.packageName!!] = apkEntity.packageName == installedPkgName + } + val gameInstall = GameInstall() + gameInstall.id = game.id + gameInstall.name = game.name + gameInstall.icon = game.icon + gameInstall.packageMap = packageMap + return gameInstall + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt index 94eb5efb88..b508de33e6 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt @@ -29,6 +29,31 @@ data class GameUpdateEntity( } return false } + + fun transformGameEntity(): GameEntity { + val gameEntity = GameEntity() + gameEntity.id = id + gameEntity.name = name + gameEntity.icon = icon + gameEntity.setTag(tag) + gameEntity.brief = brief + gameEntity.isPluggable = true + + val apkEntity = ApkEntity() + apkEntity.url = url + apkEntity.packageName = packageName + apkEntity.size = size + apkEntity.version = version + apkEntity.ghVersion = ghVersion + apkEntity.setPlatform(platform!!) + apkEntity.etag = etag + apkEntity.plugin = plugin + + val apk = java.util.ArrayList() + apk.add(apkEntity) + gameEntity.setApk(apk) + return gameEntity + } } enum class PluginLocation { diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt index 94c28c4b18..598bf23e72 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt @@ -166,9 +166,10 @@ class GameFragment : NormalFragment() { fun onEventMainThread(status: EBDownloadStatus) { if ("delete" == status.status) { mListAdapter?.notifyItemAndRemoveDownload(status) - } else if ("plugin" == status.status) { - mViewModel?.initPlugin() } +// else if ("plugin" == status.status) { +// mViewModel?.initPlugin() +// } } //安装、卸载事件 diff --git a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt index e6d923e1be..ce0262cae8 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt @@ -1,10 +1,7 @@ package com.gh.gamecenter.game import android.app.Application -import android.arch.lifecycle.AndroidViewModel -import android.arch.lifecycle.MutableLiveData -import android.arch.lifecycle.ViewModel -import android.arch.lifecycle.ViewModelProvider +import android.arch.lifecycle.* import android.preference.PreferenceManager import android.support.v4.util.ArrayMap import android.text.TextUtils @@ -17,7 +14,7 @@ import com.gh.gamecenter.baselist.LoadStatus import com.gh.gamecenter.entity.* import com.gh.gamecenter.game.data.GameItemData import com.gh.gamecenter.game.data.GameSubjectData -import com.gh.gamecenter.manager.PackageManager +import com.gh.gamecenter.install.PackageRepository import com.gh.gamecenter.retrofit.BiResponse import com.gh.gamecenter.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager @@ -43,7 +40,7 @@ class GameViewModel(application: Application, blockData: SubjectRecommendEntity? var subjectDigestList = ArrayList() // 专题入口 var smartSubject: SubjectEntity? = null // 插件化 - var itemDataList: MutableLiveData> = MutableLiveData() + var itemDataList: MediatorLiveData> = MediatorLiveData() val loadStatus = MutableLiveData() val openingDialog = MutableLiveData() @@ -59,6 +56,11 @@ class GameViewModel(application: Application, blockData: SubjectRecommendEntity? init { + if (blockData == null) { + itemDataList.addSource(PackageRepository.gameUpdateLiveData) { + initPlugin(it) + } + } initData() } @@ -74,45 +76,17 @@ class GameViewModel(application: Application, blockData: SubjectRecommendEntity? getSmartColumn() } - fun initPlugin() { - if (blockData != null) return + private fun initPlugin(updateList: List?) { + if (updateList == null) return - val updateList = PackageManager.getUpdateList() val list = ArrayList() - var gameUpdateEntity: GameUpdateEntity - var i = 0 - val size = updateList.size - while (i < size) { - gameUpdateEntity = updateList[i] - if (gameUpdateEntity.isPluggable && gameUpdateEntity.isShowPlugin(PluginLocation.only_index)) { - val gameEntity = GameEntity() - gameEntity.id = gameUpdateEntity.id - gameEntity.name = gameUpdateEntity.name - gameEntity.icon = gameUpdateEntity.icon - gameEntity.setTag(gameUpdateEntity.tag) - gameEntity.brief = gameUpdateEntity.brief - gameEntity.isPluggable = true - - val apkEntity = ApkEntity() - apkEntity.url = gameUpdateEntity.url - apkEntity.packageName = gameUpdateEntity.packageName - apkEntity.size = gameUpdateEntity.size - apkEntity.version = gameUpdateEntity.version - apkEntity.ghVersion = gameUpdateEntity.ghVersion - apkEntity.setPlatform(gameUpdateEntity.platform!!) - apkEntity.etag = gameUpdateEntity.etag - apkEntity.plugin = gameUpdateEntity.plugin - - val apk = java.util.ArrayList() - apk.add(apkEntity) - gameEntity.setApk(apk) - - list.add(gameEntity) + for (update in updateList) { + if (update.isPluggable && update.isShowPlugin(PluginLocation.only_index)) { + list.add(update.transformGameEntity()) } - i++ } - for (gEntity in list) { - gEntity.setEntryMap(DownloadManager.getInstance(getApplication()).getEntryMap(gEntity.name)) + for (game in list) { + game.setEntryMap(DownloadManager.getInstance(getApplication()).getEntryMap(game.name)) } pluginList = list transformationItemData() @@ -173,7 +147,6 @@ class GameViewModel(application: Application, blockData: SubjectRecommendEntity? if (response != null) subjectDigestList.addAll(response) transformationItemData() if (initData) { - initPlugin() getSubjectList(initData) } } @@ -181,7 +154,6 @@ class GameViewModel(application: Application, blockData: SubjectRecommendEntity? override fun onFailure(e: HttpException?) { transformationItemData() if (initData) { - initPlugin() getSubjectList(initData) } } diff --git a/app/src/main/java/com/gh/gamecenter/install/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/install/PackageRepository.kt new file mode 100644 index 0000000000..716b52ffbc --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/install/PackageRepository.kt @@ -0,0 +1,242 @@ +package com.gh.gamecenter.install + +import android.arch.lifecycle.MutableLiveData +import android.preference.PreferenceManager +import android.text.TextUtils +import com.gh.common.constant.Constants +import com.gh.common.util.DataCollectionUtils +import com.gh.common.util.GameUtils +import com.gh.common.util.PackageUtils +import com.gh.common.util.UrlFilterUtils +import com.gh.gamecenter.db.info.GameInfo +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.GameInstall +import com.gh.gamecenter.entity.GameUpdateEntity +import com.gh.gamecenter.install.PackageRepository.gameInstalled +import com.gh.gamecenter.install.PackageRepository.gameUpdate +import com.gh.gamecenter.manager.FilterManager +import com.gh.gamecenter.manager.InstallManager +import com.gh.gamecenter.manager.PackageManager +import com.gh.gamecenter.retrofit.ObservableUtil +import com.gh.gamecenter.retrofit.Response +import com.gh.gamecenter.retrofit.RetrofitManager +import com.halo.assistant.HaloApp +import com.lightgame.utils.Utils +import com.tencent.bugly.beta.tinker.TinkerManager.getApplication +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import retrofit2.HttpException + +/** + * 游戏更新以及可插件化的数据统一放在 [gameUpdate] 由 [GameUpdateEntity.isPluggable] 字段区分 + * 已安装的应用列表[gameInstalled] 存在一个包对应多个游戏问题,如果需要一对一过滤可参考[PackageViewModel.filterSameApk] + */ +object PackageRepository { + + private val mApplication = HaloApp.getInstance().application + private val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mApplication) + private val mApi = RetrofitManager.getInstance(mApplication).api + + val gameUpdateLiveData = MutableLiveData>() + val gameInstalledLiveData = MutableLiveData>() + + val gameInstalled = ArrayList() + val gameUpdate = ArrayList() + + init { + initData() + } + + /** + * 预留方法,如果想手动初始化可以调用 + */ + @JvmStatic + fun initData() { + if (gameInstalled.isNotEmpty()) gameInstalled.clear() + if (gameUpdate.isNotEmpty()) gameUpdate.clear() + + val list = PackageUtils.getAllPackageName(mApplication) + + PackageManager.initData(list) + + filterPackers(list) + + uploadAppList() + + loadInstalledGameDigestAndNotifyData(list) + } + + /** + * 上传已安装的应用数据 + */ + private fun uploadAppList() { + //检查是否符合应用上报周期 + val time = mSharedPreferences.getLong("last_upload_applist_time", 0) + //一周为一个周期 + if (Utils.getTime(mApplication) - time >= 604800L) { + DataCollectionUtils.uploadAppList(mApplication, PackageUtils.getAppList(mApplication)) + } + } + + /** + * 忽略非合法数据 + */ + private fun filterPackers(list: MutableList) { + // 忽略特定的包 todo 去除这个包的目的? + list.remove(Constants.XPOSED_INSTALLER_PACKAGE_NAME) + + // 忽略非助手收录的包 todo 必须先获取接口数据 否则无法此次操作失败(bug) + val localList = ArrayList() + val filterManager = FilterManager(mApplication) + for (pkgName in list) { + if (filterManager.isFilter(pkgName)) { + localList.add(pkgName) + } + } + } + + /** + * 获取已安装游戏的数据以及检查游戏更新[checkGameUpdate]/插件化[checkGamePlugin] + * 如果有数据变动会调用[gameUpdateLiveData] [gameInstalledLiveData]实现相关页面刷新 + * + * @param list 已安装的游戏包名集合 + */ + private fun loadInstalledGameDigestAndNotifyData(list: ArrayList) { + var isNotifyUpdate = false + val latch = ObservableUtil.latch(list.size, { + if (isNotifyUpdate) gameUpdateLiveData.postValue(gameUpdate) + gameInstalledLiveData.postValue(gameInstalled) + }, Any()) + + for (pkgName in list) { + val filterQuery = UrlFilterUtils.getFilterQuery("package", pkgName) + mApi.loadGameDataByPackageName(filterQuery) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response>() { + override fun onResponse(response: List?) { + if (response != null) { + for (game in response) { + gameInstalled.add(GameInstall.transformGameInstall(game, pkgName)) + val isCanPluggable = checkGamePlugin(game, pkgName) + val isCanUpdate = checkGameUpdate(game) + if (!isNotifyUpdate && isCanUpdate || isCanPluggable) { + isNotifyUpdate = true + } + val gameInfo = GameInfo() + gameInfo.id = game.id + gameInfo.gameIcon = game.icon + gameInfo.packageName = pkgName + gameInfo.gameName = game.name + InstallManager.getInstance().updateByEntity(gameInfo) + } + } + latch.countDown() + } + + override fun onFailure(e: HttpException?) { + latch.countDown() + } + }) + } + } + + /** + * 检查游戏更新 + * @param game + * @return 该请求是否存在可更新的游戏 + */ + private fun checkGameUpdate(game: GameEntity): Boolean { + val updateList = PackageUtils.isCanUpdate(getApplication(), game) + if (updateList.size > 0) { + PackageManager.addUpdateList(updateList) + for (updateEntity in updateList) { + addUpdateOrPluggable(updateEntity) + } + return true + } + return false + } + + /** + * 检查游戏插件化 + * @param game + * @param installedPkgName 已安装的游戏包名 + * @return 该请求是否存在可插件化的游戏 + */ + private fun checkGamePlugin(game: GameEntity, installedPkgName: String): Boolean { + if (game.getTag().isNotEmpty() && game.getApk().isNotEmpty()) { + val apkList = game.getApk() + for (apk in apkList) { + if (apk.packageName == installedPkgName && !TextUtils.isEmpty(apk.ghVersion) + && !PackageUtils.isSignature(getApplication(), apk.packageName)) { + val updateEntity = GameUtils.getGameUpdateEntity(game, apk) + addUpdateOrPluggable(updateEntity) + PackageManager.addUpdate(updateEntity) + return true + } + } + } + + return false + } + + /** + * 添加更新或插件化数据(主要目的是排重) + * @param data + */ + private fun addUpdateOrPluggable(data: GameUpdateEntity) { + var isExist = false + for (entity in gameUpdate) { + if (entity.packageName == data.packageName && entity.id == data.id) { + isExist = true + } + } + if (!isExist) gameUpdate.add(data) + } + + /** + * 新增已安装的游戏 + * @param pkgName 已安装的游戏包名 + */ + fun installedGame(pkgName: String) { + val list = ArrayList() + list.add(pkgName) + loadInstalledGameDigestAndNotifyData(list) + } + + /** + * 新增卸载游戏 + * @param pkgName 已安装的游戏包名 + */ + fun uninstalledGame(pkgName: String) { + // 删除更新列表 + for (game in gameUpdate) { + if (game.packageName == pkgName) { + gameUpdate.remove(game) + gameUpdateLiveData.postValue(gameUpdate) + break + } + } + + // 删除该已安装列表数据 + var i = 0 + while (i < gameInstalled.size) { + val game = gameInstalled[i] + var isExistInstall = false + val packageMap = game.packageMap + for (key in packageMap.keys) { + if (key == pkgName) { + packageMap[pkgName] = false + } + if (packageMap[key]!!) isExistInstall = true + } + if (!isExistInstall) { + gameInstalled.remove(game) + } else { + i++ + } + } + gameInstalledLiveData.postValue(gameInstalled) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/install/PackageViewModel.kt b/app/src/main/java/com/gh/gamecenter/install/PackageViewModel.kt new file mode 100644 index 0000000000..e3004bdf20 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/install/PackageViewModel.kt @@ -0,0 +1,74 @@ +package com.gh.gamecenter.install + +import android.app.Application +import android.arch.lifecycle.AndroidViewModel +import android.arch.lifecycle.MutableLiveData +import android.arch.lifecycle.ViewModel +import android.arch.lifecycle.ViewModelProvider +import android.text.TextUtils +import com.gh.common.util.PackageUtils +import com.gh.gamecenter.entity.GameInfoEntity +import com.gh.gamecenter.entity.GameInstall +import com.gh.gamecenter.entity.GameUpdateEntity +import com.halo.assistant.HaloApp + + +class PackageViewModel(application: Application, + private val repository: PackageRepository) : AndroidViewModel(application) { + init { + + } + + fun getGameUpdateLiveData(): MutableLiveData> { + return repository.gameUpdateLiveData + } + + fun getGameInstalledLiveData(): MutableLiveData> { + return repository.gameInstalledLiveData + } + + fun addInstalledGame(pkgName: String?) { + if (!TextUtils.isEmpty(pkgName)) repository.installedGame(pkgName!!) + } + + fun addUninstalledGame(pkgName: String?) { + if (!TextUtils.isEmpty(pkgName)) repository.uninstalledGame(pkgName!!) + } + + /** + * 过滤同包名游戏,按原顺序排序 + * @return + */ + fun filterSameApk(installedList: List?): ArrayList { + val list = ArrayList() + if (installedList != null) { + for (gameInstall in installedList) { + for ((key, value) in gameInstall.packageMap) { + if (value) { + val info = GameInfoEntity() + info.id = gameInstall.id + info.packageName = key + info.isSignature = PackageUtils.isSignature(getApplication(), key) + info.installTime = PackageUtils.getInstalledTime(getApplication(), key) + list.add(info) + } + + } + } + } + return list + } + + /** + * 检查数据(查看数据是否初始化完成,未完成则重新加载) + * 网络状态变更时调用 + */ + fun checkInstallData() { + } + + class Factory : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return PackageViewModel(HaloApp.getInstance().application, PackageRepository) as T + } + } +} diff --git a/app/src/main/java/com/gh/gamecenter/manager/InstallManager.java b/app/src/main/java/com/gh/gamecenter/manager/InstallManager.java index 06d7f311be..0e63470459 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/InstallManager.java +++ b/app/src/main/java/com/gh/gamecenter/manager/InstallManager.java @@ -7,6 +7,7 @@ import com.gh.gamecenter.db.InstallDao; import com.gh.gamecenter.db.info.GameInfo; import com.gh.gamecenter.db.info.InstallInfo; import com.gh.gamecenter.eventbus.EBConcernChanged; +import com.halo.assistant.HaloApp; import org.greenrobot.eventbus.EventBus; @@ -16,6 +17,9 @@ import java.util.List; public class InstallManager { + private static InstallManager sInstance; + private static final byte[] LOCK = new byte[0]; + private Context context; private InstallDao dao; @@ -24,6 +28,17 @@ public class InstallManager { dao = new InstallDao(context); } + public static InstallManager getInstance() { + if (sInstance == null) { + synchronized (LOCK) { + if (sInstance == null) { + sInstance = new InstallManager(HaloApp.getInstance().getApplication()); + } + } + } + return sInstance; + } + /** * 添加一个已安装的游戏 */ diff --git a/app/src/main/java/com/gh/gamecenter/personal/installed/InstallGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/personal/installed/InstallGameViewModel.kt index 4d595e9b77..0b5986490b 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/installed/InstallGameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/installed/InstallGameViewModel.kt @@ -120,7 +120,7 @@ class InstallGameViewModel(application: Application) : AndroidViewModel(applicat for (entity in sortList) { sequences.add(RetrofitManager.getInstance(getApplication()).api.getGameDigest(entity.id)) } - Observable.merge(sequences) + Observable.mergeDelayError(sequences) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { 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 501f6d8c9f..a6ca008a7a 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 @@ -145,6 +145,13 @@ public interface ApiService { @GET("games?view=digest") Observable> getGameDigestByPackageName(@Query("filter") String filter); + + /** + * 根据包名获取游戏摘要 + */ + @GET("games?view=digest") + Observable> loadGameDataByPackageName(@Query("filter") String filter); + /** * 获取游戏更新 */