diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 47b6c37bc0..b483162762 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -619,6 +619,10 @@
android:name=".qa.questions.draft.QuestionDraftActivity"
android:screenOrientation="portrait" />
+
+
diff --git a/app/src/main/java/com/gh/common/util/ErrorHelper.kt b/app/src/main/java/com/gh/common/util/ErrorHelper.kt
index 4e05ad9474..8b9feb51e7 100644
--- a/app/src/main/java/com/gh/common/util/ErrorHelper.kt
+++ b/app/src/main/java/com/gh/common/util/ErrorHelper.kt
@@ -18,6 +18,7 @@ object ErrorHelper {
* [showHighPriorityHint] 用来标识有同样错误码可以触发两种处理时,为 true 时选择重要的
* [customizedHandler] 返回 true 为已处理该错误码,false 则交由 [handleError] 处理
*/
+ @JvmStatic
fun handleErrorWithCustomizedHandler(context: Context,
errorString: String?,
showHighPriorityHint: Boolean = false,
diff --git a/app/src/main/java/com/gh/common/util/LogUtils.java b/app/src/main/java/com/gh/common/util/LogUtils.java
index b58dbe5f81..b34ed324fb 100644
--- a/app/src/main/java/com/gh/common/util/LogUtils.java
+++ b/app/src/main/java/com/gh/common/util/LogUtils.java
@@ -767,4 +767,27 @@ public class LogUtils {
}
LoghubUtils.log(object, "event", false);
}
+
+ public static void uploadPackageSkip(String action, String gameId, String gameName) {
+ JSONObject object = new JSONObject();
+ JSONObject payloadObject = new JSONObject();
+ try {
+ object.put("event", "external_jump");
+ object.put("action", action);
+
+ if (!TextUtils.isEmpty(gameId)&&!TextUtils.isEmpty(gameName)) {
+ payloadObject.put("game_id", gameId);
+ payloadObject.put("game_name", gameName);
+ object.put("payload", payloadObject);
+ }
+
+ object.put("meta", getMetaObject());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ if (BuildConfig.DEBUG) {
+ Utils.log("LogUtils->" + object.toString());
+ }
+ LoghubUtils.log(object, "event", false);
+ }
}
diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java
index 8526b3240f..d44fcc16bc 100644
--- a/app/src/main/java/com/gh/gamecenter/MainActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java
@@ -20,6 +20,7 @@ import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;
import com.gh.base.AppUncaughtHandler;
@@ -43,6 +44,7 @@ import com.gh.common.util.DialogUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
+import com.gh.common.util.ErrorHelper;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.HomePluggableHelper;
@@ -56,6 +58,7 @@ import com.gh.common.util.PlatformUtils;
import com.gh.common.util.SPUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.ToastUtils;
+import com.gh.common.util.UrlFilterUtils;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.download.DownloadFragment;
import com.gh.gamecenter.entity.CommunityEntity;
@@ -67,20 +70,18 @@ import com.gh.gamecenter.eventbus.EBNetworkState;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.fragment.MainWrapperFragment;
-import com.gh.gamecenter.gamedetail.GameDetailFragment;
+import com.gh.gamecenter.home.skip.PackageSkipActivity;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.manager.UpdateManager;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.normal.NormalFragment;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.qa.CommunityFragment;
-import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.suggest.SuggestSelectFragment;
import com.gh.gamecenter.suggest.SuggestType;
import com.google.gson.Gson;
-import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
@@ -92,7 +93,6 @@ import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
-import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
import java.io.BufferedReader;
@@ -101,6 +101,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
+import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
@@ -108,9 +109,11 @@ import java.util.zip.ZipFile;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
+import kotlin.jvm.functions.Function1;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
+import retrofit2.HttpException;
import static com.gh.common.util.EntranceUtils.ENTRANCE_BROWSER;
import static com.gh.common.util.EntranceUtils.HOST_LAUNCH_SIMULATOR_GAME;
@@ -122,7 +125,7 @@ import static com.gh.common.util.EntranceUtils.KEY_MARKET_DETAILS;
import static com.gh.common.util.EntranceUtils.KEY_NEXT_TO;
import static com.gh.common.util.EntranceUtils.KEY_TO;
import static com.gh.common.util.EntranceUtils.KEY_TYPE;
-import static com.gh.common.util.ExtensionsKt.singleToMain;
+import static com.gh.common.util.ExtensionsKt.observableToMain;
import static com.gh.gamecenter.fragment.MainWrapperFragment.INDEX_PERSONAL;
import static com.gh.gamecenter.personal.PersonalFragment.LOGIN_TAG;
import static com.gh.gamecenter.personal.PersonalFragment.LOGOUT_TAG;
@@ -453,20 +456,43 @@ public class MainActivity extends BaseActivity {
*
* @param packageName
*/
- @SuppressLint("CheckResult")
private void redirectGameDetail(String packageName) {
- RetrofitManager.getInstance(this).getApi().redirectGameDetail(packageName)
- .compose(singleToMain())
- .subscribe(new BiResponse() {
+ String filterQuery = UrlFilterUtils.getFilterQuery("package", packageName, "type", "package_redirect");
+ RetrofitManager.getInstance(this).getApi().loadGameDataByPackageName(filterQuery)
+ .compose(observableToMain())
+ .subscribe(new Response>() {
@Override
- public void onSuccess(JsonObject data) {
- String gameId = data.get("game_id").getAsString();
- DirectUtils.directToGameDetail(MainActivity.this, gameId, GameDetailFragment.INDEX_DESC, "应用跳转");
+ public void onResponse(@Nullable List response) {
+ super.onResponse(response);
+ if (response == null || response.isEmpty()) return;
+ if (response.size() > 1) {
+ startActivity(PackageSkipActivity.getIntent(MainActivity.this, response));
+ LogUtils.uploadPackageSkip("show_enter", "", "");
+ } else {
+ GameDetailActivity.startGameDetailActivity(MainActivity.this, response.get(0), "应用跳转");
+ LogUtils.uploadPackageSkip("game_detail_enter", response.get(0).getId(), response.get(0).getName());
+ }
}
@Override
- public void onFailure(@NotNull Exception exception) {
- super.onFailure(exception);
+ public void onFailure(@Nullable HttpException e) {
+ super.onFailure(e);
+ try {
+ ErrorHelper.handleErrorWithCustomizedHandler(MainActivity.this, e.response().errorBody().string(), false, new Function1() {
+ @Override
+ public Boolean invoke(Integer code) {
+ if (code == 404001) {
+ toast("抱歉,暂未找到相关内容");
+ LogUtils.uploadPackageSkip("game_library_enter", "", "");
+ EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_GAME));
+ return true;
+ }
+ return false;
+ }
+ });
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
}
});
}
diff --git a/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipActivity.kt b/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipActivity.kt
new file mode 100644
index 0000000000..18f7fddc80
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipActivity.kt
@@ -0,0 +1,32 @@
+package com.gh.gamecenter.home.skip
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.base.BaseActivity
+import com.gh.common.util.DisplayUtils
+import com.gh.gamecenter.R
+import com.gh.gamecenter.entity.GameEntity
+
+class PackageSkipActivity : BaseActivity() {
+
+ override fun getLayoutId(): Int = R.layout.activity_amway
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val containerFragment = supportFragmentManager.findFragmentByTag(PackageSkipFragment::class.java.simpleName)
+ ?: PackageSkipFragment().with(intent.extras)
+ // 若 placeholder 外层为 RelativeLayout 的话,会出现莫名的偏移
+ supportFragmentManager.beginTransaction().replace(R.id.placeholder, containerFragment, PackageSkipFragment::class.java.simpleName).commitAllowingStateLoss()
+ DisplayUtils.setStatusBarColor(this, R.color.transparent, true)
+ }
+
+ companion object {
+ @JvmStatic
+ fun getIntent(context: Context, games: List): Intent {
+ val intent = Intent(context, PackageSkipActivity::class.java)
+ intent.putParcelableArrayListExtra(GameEntity::class.java.name, ArrayList(games))
+ return intent
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipAdapter.kt
new file mode 100644
index 0000000000..846a4b9e3e
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipAdapter.kt
@@ -0,0 +1,53 @@
+package com.gh.gamecenter.home.skip
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.DownloadItemUtils
+import com.gh.common.util.EmptyCallback
+import com.gh.common.util.LogUtils
+import com.gh.common.util.StringUtils
+import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.GameViewHolder
+import com.gh.gamecenter.databinding.GameItemBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.game.GameItemViewHolder
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class PackageSkipAdapter(val context: Context, val games: ArrayList, private val itemClickCallback: () -> Unit) : BaseRecyclerAdapter(context) {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false)))
+ }
+
+ override fun getItemCount(): Int = games.size
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is GameItemViewHolder) {
+ val gameEntity = games[position]
+ holder.binding.game = gameEntity
+ holder.initServerType(gameEntity)
+ val subjectData = gameEntity.subjectData
+ holder.binding.isShowSuffix = subjectData?.isShowSuffix
+ holder.binding.briefStyle = subjectData?.briefStyle
+
+ holder.binding.executePendingBindings()
+ DownloadItemUtils.setOnClickListener(mContext, holder.binding.downloadBtn, gameEntity, position,
+ this,
+ StringUtils.buildString("应用跳转:", subjectData?.name, "-列表[", (position + 1).toString(), "])"),
+ StringUtils.buildString("应用跳转-", subjectData?.name, ":", gameEntity.name), null,
+ object : EmptyCallback {
+ override fun onCallback() {
+ LogUtils.uploadPackageSkip("show_download", gameEntity.id, gameEntity.name)
+ }
+ })
+ DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), !gameEntity.isPluggable, subjectData?.briefStyle)
+ holder.itemView.setOnClickListener {
+ LogUtils.uploadPackageSkip("show_click", gameEntity.id, gameEntity.name)
+ GameDetailActivity.startGameDetailActivity(context, gameEntity, "应用跳转")
+ itemClickCallback.invoke()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipFragment.kt b/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipFragment.kt
new file mode 100644
index 0000000000..dff2050163
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/skip/PackageSkipFragment.kt
@@ -0,0 +1,118 @@
+package com.gh.gamecenter.home.skip
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import androidx.recyclerview.widget.DefaultItemAnimator
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.gh.base.fragment.BaseFragment
+import com.gh.common.util.LogUtils
+import com.gh.download.DownloadManager
+import com.gh.gamecenter.databinding.FragmentPackageSkipBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.eventbus.EBDownloadStatus
+import com.gh.gamecenter.eventbus.EBPackage
+import com.lightgame.download.DataWatcher
+import com.lightgame.download.DownloadEntity
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class PackageSkipFragment : BaseFragment() {
+
+ private lateinit var mBinding: FragmentPackageSkipBinding
+ private lateinit var mAdapter: PackageSkipAdapter
+ private var games: ArrayList = arrayListOf()
+ private var positionAndPackageMap = HashMap()
+
+ override fun getLayoutId(): Int = 0
+
+ private val dataWatcher = object : DataWatcher() {
+ override fun onDataChanged(downloadEntity: DownloadEntity) {
+ for (key in positionAndPackageMap.keys) {
+ if (key.contains(downloadEntity.packageName) && key.contains(downloadEntity.gameId)) {
+ val position = positionAndPackageMap[key]
+ if (position != null && position < games.size) {
+ games[position].getEntryMap()[downloadEntity.platform] = downloadEntity
+ mAdapter.notifyItemChanged(position)
+ }
+ }
+ }
+ }
+ }
+
+ override fun getInflatedLayout(): View {
+ mBinding = FragmentPackageSkipBinding.inflate(LayoutInflater.from(requireContext()), null, false)
+ return mBinding.root
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ games = arguments?.getParcelableArrayList(GameEntity::class.java.name)
+ ?: arrayListOf()
+ positionAndPackageMap.clear()
+ games.forEachIndexed { index, gameEntity ->
+ addGamePositionAndPackage(gameEntity, index)
+ }
+ mBinding.normalToolbar.setNavigationOnClickListener {
+ LogUtils.uploadPackageSkip("home_enter", "", "")
+ requireActivity().finish()
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mBinding.listRv.apply {
+ (itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
+ layoutManager = LinearLayoutManager(requireContext())
+ mAdapter = PackageSkipAdapter(requireContext(), games) {
+ requireActivity().finish()
+ }
+ adapter = mAdapter
+ }
+ }
+
+ private fun addGamePositionAndPackage(game: GameEntity, position: Int) {
+ var packages = ""
+ for (apkEntity in game.getApk()) {
+ packages += apkEntity.packageName
+ }
+ packages += game.simulator?.apk?.packageName
+ positionAndPackageMap[packages + position + game.id] = position
+ game.gameLocation = GameEntity.GameLocation.INDEX
+ game.setEntryMap(DownloadManager.getInstance(requireContext()).getEntryMap(game.name))
+ }
+
+ override fun onResume() {
+ super.onResume()
+ DownloadManager.getInstance(requireContext()).addObserver(dataWatcher)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ DownloadManager.getInstance(requireContext()).removeObserver(dataWatcher)
+ }
+
+ //安装、卸载事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(busFour: EBPackage) {
+ if ("安装" == busFour.type || "卸载" == busFour.type) {
+ mAdapter.notifyDataSetChanged()
+ }
+ }
+
+ // 下载被删除事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(status: EBDownloadStatus) {
+ if ("delete" == status.status) {
+ for (key in positionAndPackageMap.keys) {
+ if (key.contains(status.packageName) && key.contains(status.gameId)) {
+ val position = positionAndPackageMap[key]
+ if (position != null && position < games.size) {
+ games[position].getEntryMap().remove(status.platform)
+ mAdapter.notifyItemChanged(position)
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_package_skip.xml b/app/src/main/res/layout/fragment_package_skip.xml
new file mode 100644
index 0000000000..3c3b7c1693
--- /dev/null
+++ b/app/src/main/res/layout/fragment_package_skip.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file