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 51e028c783..079cd87e69 100644 --- a/app/src/main/java/com/gh/common/constant/Constants.java +++ b/app/src/main/java/com/gh/common/constant/Constants.java @@ -154,6 +154,8 @@ public class Constants { //游戏详情推荐弹窗 public static final String SP_RECOMMEND_POPUP = "recommend_popup"; + // 设备实名信息 + public static final String SP_DEVICE_CERTIFICATION_PREFIX = "device_certification_prefix"; // 使用浏览器安装开关 public static final String SP_USE_BROWSER_TO_INSTALL = "use_browser_to_install"; diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 72d4fc7b10..5601ca86c4 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -668,6 +668,8 @@ public class BindingAdapters { case cancel: case hijack: case notfound: + case uncertificated: + case unqualified: break; default: break; diff --git a/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt b/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt index fd02bf3931..f9296af497 100644 --- a/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt +++ b/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt @@ -87,6 +87,12 @@ class SimulatorDownloadManager private constructor() { DownloadStatus.notfound == downloadEntity.status -> { ToastUtils.showToast("下载链接异常,请稍后重试") } + DownloadStatus.uncertificated == downloadEntity.status -> { + ToastUtils.showToast("请先进行实名认证") + } + DownloadStatus.unqualified == downloadEntity.status -> { + ToastUtils.showToast("未成年人暂不允许在此时间下载游戏") + } DownloadStatus.hijack == downloadEntity.status -> { ToastUtils.showToast("网络劫持,请稍后重试") } diff --git a/app/src/main/java/com/gh/common/util/DataUtils.java b/app/src/main/java/com/gh/common/util/DataUtils.java index 245b0800c5..a4acfab466 100644 --- a/app/src/main/java/com/gh/common/util/DataUtils.java +++ b/app/src/main/java/com/gh/common/util/DataUtils.java @@ -1,5 +1,6 @@ package com.gh.common.util; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.Application; import android.content.Context; @@ -11,6 +12,9 @@ import com.gh.common.AppExecutor; import com.gh.common.constant.Constants; import com.gh.common.exposure.meta.MetaUtil; import com.gh.gamecenter.BuildConfig; +import com.gh.gamecenter.entity.UserInfoEntity; +import com.gh.gamecenter.retrofit.BiResponse; +import com.gh.gamecenter.retrofit.RetrofitManager; import com.gh.gid.GidCallback; import com.gh.gid.GidHelper; import com.halo.assistant.HaloApp; @@ -20,6 +24,8 @@ import com.lightgame.utils.Utils; import java.util.HashMap; import java.util.Map; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; import io.sentry.Sentry; import io.sentry.android.core.SentryAndroid; @@ -171,6 +177,8 @@ public class DataUtils { GameSubstituteRepositoryHelper.updateSubstitutableGames(); } + getDeviceCertification(gid); + // 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid MetaUtil.INSTANCE.refreshMeta(); } @@ -182,6 +190,23 @@ public class DataUtils { }); } + /** + * 获取应用 gid 绑定的实名信息 + */ + @SuppressLint("CheckResult") + private static void getDeviceCertification(String gid) { + RetrofitManager.getInstance(HaloApp.getInstance()) + .getApi() + .getCertification() + .subscribeOn(Schedulers.io()) + .subscribe(new BiResponse() { + @Override + public void onSuccess(UserInfoEntity data) { + SPUtils.setString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + gid, GsonUtils.toJson(data)); + } + }); + } + public static void onEvent(Context var0, String var1, String var2) { // Properties prop = new Properties(); // prop.setProperty(var1, var2); diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 054c461e58..0464b26895 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -175,6 +175,8 @@ public class DetailDownloadUtils { case cancel: case hijack: case notfound: + case uncertificated: + case unqualified: detailInitDownload(viewHolder, false); break; default: diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index 38f1039e32..8685b8d96b 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -266,9 +266,7 @@ object DirectUtils { } "authentication" -> { - CheckLoginUtils.checkLogin(context, entrance) { context.startActivity(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD)) - } } "user_background" -> { diff --git a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt index 2599132a4c..c5bfa51545 100644 --- a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt +++ b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt @@ -111,12 +111,14 @@ object DownloadNotificationHelper { if (entity.status == DownloadStatus.delete || entity.status == DownloadStatus.cancel || entity.status == DownloadStatus.hijack + || entity.status == DownloadStatus.unqualified + || entity.status == DownloadStatus.uncertificated || entity.status == DownloadStatus.notfound || entity.status == DownloadStatus.overflow || (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知 && !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty() && xapkStatus != XapkUnzipStatus.FAILURE.name) - ||entity.status == DownloadStatus.done && entity.isSimulatorGame()) {//模拟器游戏下载完需要cancel掉通知 + || entity.status == DownloadStatus.done && entity.isSimulatorGame()) {//模拟器游戏下载完需要cancel掉通知 requireUpdateNotificationGroupDelay = true notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID) } else { 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 11fa9a29ba..3342b2d576 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -3,6 +3,7 @@ package com.gh.common.util import android.os.Build import android.preference.PreferenceManager import com.gh.base.BaseActivity +import com.gh.base.CurrentActivityHolder import com.gh.common.constant.Constants import com.gh.common.exposure.ExposureUtils import com.gh.common.exposure.meta.MetaUtil @@ -15,6 +16,7 @@ import com.gh.download.DownloadManager import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.R import com.gh.gamecenter.SuggestionActivity +import com.gh.gamecenter.UserInfoEditActivity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SimpleGameEntity import com.gh.gamecenter.entity.SimulatorEntity @@ -24,6 +26,7 @@ import com.gh.gamecenter.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.setting.GameDownloadSettingFragment.Companion.AUTO_INSTALL_SP_KEY import com.gh.gamecenter.suggest.SuggestType +import com.gh.gamecenter.user.UserViewModel import com.halo.assistant.HaloApp import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity @@ -62,11 +65,6 @@ object DownloadObserver { if (DownloadStatus.hijack == downloadEntity.status) { // 链接被劫持 processHijack(downloadEntity) -// val nameAndPlatform = (downloadEntity.name + ":" -// + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform)) -// MtaHelper.onEvent("下载劫持", -// "游戏名字", nameAndPlatform, -// "网络状态", DeviceUtils.getNetwork(mApplication)) return } else if (DownloadStatus.notfound == downloadEntity.status) { // 404 Not Found @@ -75,9 +73,6 @@ object DownloadObserver { downloadManager.cancel(downloadEntity.url) Utils.toast(mApplication, "该链接已失效!请联系管理员。") -// MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗", -// "游戏", downloadEntity.name, -// "平台", downloadEntity.platform) val currentActivity = AppManager.getInstance().currentActivity() ?: return DialogUtils.showAlertDialog(currentActivity, "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", { @@ -100,9 +95,6 @@ object DownloadObserver { Utils.toast(mApplication, "网络不稳定,下载任务已暂停") DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity) -// MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停", -// "游戏", downloadEntity.name, -// "平台", downloadEntity.platform) debugOnly { Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson()) } @@ -110,7 +102,66 @@ object DownloadObserver { } else if (DownloadStatus.redirected == downloadEntity.status) { debugOnly { Utils.log("重定向完毕") } DownloadDataHelper.uploadRedirectEvent(downloadEntity) + } else if (DownloadStatus.unqualified == downloadEntity.status) { + // 未成年 + val currentActivity = CurrentActivityHolder.getCurrentActivity() + if (currentActivity == null) { + ToastUtils.toast("为保护未成年身心健康成长,根据相关政策要求,该游戏不对未成年人开放下载") + } else { + NewLogUtils.logCertificationHintDialogTrigger(true) + DialogHelper.showDialog( + currentActivity, + title = "实名提示", + content = "为保护未成年身心健康成长,根据相关政策要求,该游戏不对未成年人开放下载", + confirmText = "知道了", + cancelText = "", + confirmClickCallback = { +// NewLogUtils.logCertificationHintDialogTrigger(true) + } + ) + } + DownloadManager.getInstance(HaloApp.getInstance()).addInvisiblePendingTask(downloadEntity) + + // 删除任务 + downloadEntity.status = DownloadStatus.cancel + downloadManager.cancel(downloadEntity.url) + } else if (DownloadStatus.uncertificated == downloadEntity.status) { + // 未实名 + NewLogUtils.logCertificationTrigger(downloadEntity.gameId, downloadEntity.name) + + val currentActivity = CurrentActivityHolder.getCurrentActivity() + if (currentActivity == null) { + ToastUtils.toast("为保护未成年身心健康成长,根据相关政策要求,该游戏不对未成年人开放下载") + } else { + NewLogUtils.logCertificationHintDialogAppearance() + DialogHelper.showDialog( + currentActivity, + title = "实名提示", + content = "为保护未成年身心健康成长,根据相关政策要求,该游戏不对未成年人开放下载\n" + + "如需下载,请前往实名认证", + confirmText = "前往实名认证", + cancelText = "取消", + confirmClickCallback = { + currentActivity.startActivity( + UserInfoEditActivity.getIntent( + currentActivity, + UserViewModel.TYPE_ID_CARD, + true + ) + ) + NewLogUtils.logCertificationHintDialogOptionsClicked("前往实名认证") + }, + cancelClickCallback = { + NewLogUtils.logCertificationHintDialogOptionsClicked("取消") + } + ) + } + DownloadManager.getInstance(HaloApp.getInstance()).addInvisiblePendingTask(downloadEntity) + // 删除任务 + downloadEntity.status = DownloadStatus.cancel + downloadManager.cancel(downloadEntity.url) } + if (DownloadStatus.done == downloadEntity.status) { if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) { statDoneEvent(downloadEntity) @@ -199,11 +250,6 @@ object DownloadObserver { val pm = mApplication.packageManager val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, 0) if (packageInfo == null) { -// MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析", -// "游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform)) -// -// MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新", -// "游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform)) val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) if (downloadType == Constants.SIMULATOR_DOWNLOAD) { val currentActivity = AppManager.getInstance().currentActivity() @@ -260,14 +306,6 @@ object DownloadObserver { type = ExposureUtils.DownloadType.DOWNLOAD } -// val kv2 = HashMap() -// kv2["版本"] = downloadEntity.platform -// kv2["状态"] = "下载完成" -// kv2["位置"] = downloadEntity.entrance ?: "null" -// kv2["游戏分平台"] = downloadEntity.name + "-" + platform -// kv2["光环助手版本"] = BuildConfig.VERSION_NAME -// DataUtils.onEvent(mApplication, "游戏下载位置", downloadEntity.name, kv2) - if (downloadEntity.isPluggable) { val kv3 = HashMap() kv3["下载"] = "下载完成" @@ -275,13 +313,6 @@ object DownloadObserver { kv3["位置"] = downloadEntity.entrance ?: "null" type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD DataUtils.onEvent(mApplication, "插件化", downloadEntity.name, kv3) - -// MtaHelper.onEvent( -// "插件化_新", -// "位置", downloadEntity.entrance, -// "游戏", downloadEntity.name + "-" + downloadEntity.platform, -// "操作", "下载完成", -// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application)) } val isPlatformRecommend = java.lang.Boolean.parseBoolean(downloadEntity.getMetaExtra(Constants.IS_PLATFORM_RECOMMEND)) ExposureUtils.logADownloadCompleteExposureEvent( 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 15d894fdb3..7c0b11a21a 100644 --- a/app/src/main/java/com/gh/common/util/EntranceUtils.java +++ b/app/src/main/java/com/gh/common/util/EntranceUtils.java @@ -232,6 +232,7 @@ public class EntranceUtils { public static final String KEY_CATEGORY_LIST = "categoty_list"; public static final String KEY_IS_FREE = "is_free"; public static final String KEY_IS_SIGN = "is_sign"; + public static final String KEY_IS_FORCED_TO_CERTICIFICE = "is_forced_to_certificate"; public static final String KEY_IS_CHOOSE_APK = "is_choose_apk"; public static final String KEY_TAB_INDEX = "tab_index"; public static final String KEY_IS_CATEGORY_V2 = "is_category_v2"; diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index 933f376ece..db785675de 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -1,6 +1,7 @@ package com.gh.common.util import android.annotation.SuppressLint +import com.gh.common.json.JsonObjectBuilder import com.gh.common.json.json import com.gh.common.loghub.LoghubUtils import com.gh.common.tracker.Tracker @@ -21,6 +22,16 @@ object NewLogUtils { LoghubUtils.log(jsonObject, logStore, uploadImmediately) } + fun parseAndPutMeta(): JsonObjectBuilder.() -> Unit = { + val meta = LogUtils.getMetaObject() + val metaKeys = meta.keys() + while (metaKeys.hasNext()) { + val key: String = metaKeys.next().toString() + val value = meta.getString(key) + key to value + } + } + // 专题右上角的点击事件 fun logSubjectTopTabClick(buttonName: String?, subjectName: String?, linkEntity: LinkEntity?) { val json = json { @@ -52,6 +63,76 @@ object NewLogUtils { .subscribe(EmptyResponse()) } + // 触发实名认证 + fun logCertificationTrigger(gameId: String, gameName: String) { + val json = json { + "event" to "verification_trigger" + "game_id" to gameId + "game_name" to gameName + "timestamp" to System.currentTimeMillis() / 1000 + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 触发实名认证的来源 (下载触发或用户手动触发) + fun logCertificationTriggerType(isForced: Boolean) { + val json = json { + "event" to "verification_page" + "trigger" to if (isForced) "实名认证流程" else "" + "timestamp" to System.currentTimeMillis() / 1000 + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + /** + * 记录实名认证结果 + * @param result 0 失败, 1 成功但未成年 2 成功且成年 + */ + fun logCertificationResult(isForced: Boolean, result: Int) { + val json = json { + "event" to "verification_finished" + "trigger" to if (isForced) "实名认证流程" else "" + "result" to result + "timestamp" to System.currentTimeMillis() / 1000 + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 实名弹窗弹出(含前往实名认证选项) + fun logCertificationHintDialogAppearance() { + val json = json { + "event" to "verification_pop_a_show" + "timestamp" to System.currentTimeMillis() / 1000 + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 实名弹窗(含前往实名认证选项) 选项点击 + fun logCertificationHintDialogOptionsClicked(text: String) { + val json = json { + "event" to "verification_pop_a_click" + "timestamp" to System.currentTimeMillis() / 1000 + "button" to text + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 实名弹窗弹出(不含前往实名认证选项) + fun logCertificationHintDialogTrigger(isForced: Boolean) { + val json = json { + "event" to "verification_pop_b_show" + "timestamp" to System.currentTimeMillis() / 1000 + "trigger" to if (isForced) "实名认证流程" else "" + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + // 游戏详情点击顶部标签 fun logGameDetailTagClick(gameId: String, gameName: String, tagId: String, tagName: String) { val json = json { diff --git a/app/src/main/java/com/gh/common/util/RealNameHelper.kt b/app/src/main/java/com/gh/common/util/RealNameHelper.kt index 6d642e0fbe..52778ce87f 100644 --- a/app/src/main/java/com/gh/common/util/RealNameHelper.kt +++ b/app/src/main/java/com/gh/common/util/RealNameHelper.kt @@ -11,40 +11,7 @@ object RealNameHelper { @JvmStatic fun checkIfAuth(context: Context, gameEntity: GameEntity, callback: EmptyCallback) { - if (gameEntity.auth?.switch == "on") { - if ((gameEntity.auth?.timeStart == "00:00" && gameEntity.auth?.timeEnd == "00:00") - || withinTimeRange(gameEntity.auth?.timeStart, gameEntity.auth?.timeEnd)) { - context.ifLogin("") { - if (!UserManager.getInstance().isAuth) { - context.startActivity(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD)) - } else { - callback.onCallback() - } - } - } else { - callback.onCallback() - } - } else { - callback.onCallback() - } - } - - private fun withinTimeRange(timeStart: String?, timeEnd: String?): Boolean { - val realTimeEnd = if (timeEnd == "00:00") "23:59" else timeEnd - - val startHourAndMinuteArray = timeStart?.split(":") - val endHourAndMinuteArray = realTimeEnd?.split(":") - - val calStart = Calendar.getInstance().apply { - set(Calendar.HOUR_OF_DAY, startHourAndMinuteArray?.first()!!.toInt()) - set(Calendar.MINUTE, startHourAndMinuteArray.secondOrNull()!!.toInt()) - } - val calEnd = Calendar.getInstance().apply { - set(Calendar.HOUR_OF_DAY, endHourAndMinuteArray?.first()!!.toInt()) - set(Calendar.MINUTE, endHourAndMinuteArray.secondOrNull()!!.toInt()) - } - - return (Calendar.getInstance().after(calStart) && Calendar.getInstance().before(calEnd)) + callback.onCallback() } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/download/DownloadDataHelper.kt b/app/src/main/java/com/gh/download/DownloadDataHelper.kt index 172a18f918..dc1bdf824d 100644 --- a/app/src/main/java/com/gh/download/DownloadDataHelper.kt +++ b/app/src/main/java/com/gh/download/DownloadDataHelper.kt @@ -78,6 +78,10 @@ object DownloadDataHelper { "解析包错误-下载过程中" } else if (status == DownloadStatus.hijack || status == DownloadStatus.notfound) { "下载失败" + } else if (status == DownloadStatus.uncertificated) { + "未实名" + } else if (status == DownloadStatus.unqualified) { + "未成年" } else if (status == DownloadStatus.redirected) { "重定向至最终地址" } else { diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 3fd672a9e7..ac039783c5 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -89,6 +89,8 @@ public class DownloadManager implements DownloadStatusListener { private DownloadDao mDownloadDao; + private ArrayList mInvisiblePendingTaskList; // 用户不可见的 pending 任务 + private Set mUpdateMarks; @Override @@ -162,6 +164,7 @@ public class DownloadManager implements DownloadStatusListener { gameMap = new ArrayMap<>(); statusMap = new ArrayMap<>(); downloadingMap = new ArrayMap<>(); + mInvisiblePendingTaskList = new ArrayList<>(); mHandler = new Handler(Looper.getMainLooper()) { @Override @@ -1047,6 +1050,33 @@ public class DownloadManager implements DownloadStatusListener { sendMessageDelayed(msg, 1000); } + /** + * 添加不可见的 pending 下载任务 + * @param downloadEntity 任务信息实体 + */ + public void addInvisiblePendingTask(DownloadEntity downloadEntity) { + boolean isAlreadyExist = false; + for (DownloadEntity existTask : mInvisiblePendingTaskList) { + if (existTask.getUrl().equals(downloadEntity.getUrl())) { + isAlreadyExist = true; + break; + } + } + if (!isAlreadyExist) { + mInvisiblePendingTaskList.add(downloadEntity); + } + } + + /** + * 启动所有不可见的 pending 下载任务 + */ + public void resumeAllInvisiblePendingTask() { + for (DownloadEntity task : mInvisiblePendingTaskList) { + add(task); + } + mInvisiblePendingTaskList.clear(); + } + public static void updateMetaMap() { HashMap map = new HashMap<>(); map.put(HttpDnsManager.APP_VERSION, BuildConfig.VERSION_NAME); @@ -1055,6 +1085,7 @@ public class DownloadManager implements DownloadStatusListener { map.put(HttpDnsManager.OAID, HaloApp.getInstance().getOAID()); map.put(HttpDnsManager.USER_ID, UserManager.getInstance().getUserId()); map.put(HttpDnsManager.IMEI, MetaUtil.getBase64EncodedIMEI()); + map.put(HttpDnsManager.TOKEN, UserManager.getInstance().getToken()); HttpDnsManager.metaMap = map; } diff --git a/app/src/main/java/com/gh/gamecenter/UserInfoEditActivity.java b/app/src/main/java/com/gh/gamecenter/UserInfoEditActivity.java index 0d61a12974..c372b31e84 100644 --- a/app/src/main/java/com/gh/gamecenter/UserInfoEditActivity.java +++ b/app/src/main/java/com/gh/gamecenter/UserInfoEditActivity.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.os.Bundle; import androidx.annotation.NonNull; +import com.gh.common.util.EntranceUtils; import com.gh.gamecenter.user.UserViewModel; import com.halo.assistant.fragment.user.UserInfoEditFragment; @@ -16,8 +17,19 @@ public class UserInfoEditActivity extends NormalActivity { @NonNull public static Intent getIntent(Context context, String editType) { + return getIntent(context, editType, false); + } + + /** + * 获取修改信息 intent + * @param editType 类型 + * @param isForcedToCertificate 来源是否为强制实名 + */ + @NonNull + public static Intent getIntent(Context context, String editType, Boolean isForcedToCertificate) { Bundle args = new Bundle(); args.putString(UserViewModel.KEY_EDIT_TYPE, editType); + args.putBoolean(EntranceUtils.KEY_IS_FORCED_TO_CERTICIFICE, isForcedToCertificate); return getTargetIntent(context, UserInfoEditActivity.class, UserInfoEditFragment.class, args); } diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt index b5241878a1..2e72bef702 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt @@ -251,7 +251,7 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() { } private fun notifyChildFragmentLifecycle(currentSelectedPosition: Int) { - tryCatchInRelease { + tryWithDefaultCatch { // 补充 Viewpager Fragment 的生命周期, 先调用旧选中 fragment 的 onPause 再当前的 onResume // 避免部分被内嵌的 Fragment 不能正常运作 if (mFragmentList.size > mLastSelectedPosition) { diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt b/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt index 1627939f69..2f8430fdcd 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt @@ -192,12 +192,7 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m } } "实名认证" -> { - if (UserManager.getInstance().isLoggedIn) { - context.startActivity(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD)) - } else { - MtaHelper.onEvent("我的光环_新", "功能入口-跳转登录", "实名认证") - CheckLoginUtils.checkLogin(context, "我的光环-实名认证") { } - } + context.startActivity(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD)) } "微信提醒" -> { MtaHelper.onEvent("我的光环", "设置微信提醒") diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt index d93e75ae50..e71808b323 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt @@ -239,6 +239,8 @@ class UserHomeFragment : NormalFragment() { } userCountContainer.post { + if(!isAdded) return@post + val newHeight = userCountContainer.bottom + (12F + 16F).dip2px() userBackgroundContainer.layoutParams = userBackgroundContainer.layoutParams.apply { height = newHeight 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 231fe58f03..ebd5a8c868 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 @@ -252,6 +252,18 @@ public interface ApiService { @Query("version_code") int code, @Query("channel") String channel); + /** + * 获取实名认证 + */ + @GET("certification") + Single getCertification(); + + /** + * 更新实名认证 + */ + @POST("certification") + Single postCertification(@Body RequestBody body); + /** * 获取新闻详情 */ diff --git a/app/src/main/java/com/gh/gamecenter/user/UserRepository.java b/app/src/main/java/com/gh/gamecenter/user/UserRepository.java index f993acb2f5..2540b3b8d5 100644 --- a/app/src/main/java/com/gh/gamecenter/user/UserRepository.java +++ b/app/src/main/java/com/gh/gamecenter/user/UserRepository.java @@ -1,11 +1,13 @@ package com.gh.gamecenter.user; +import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.os.Build; import android.preference.PreferenceManager; import android.text.TextUtils; +import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; @@ -22,7 +24,9 @@ import com.gh.common.util.EnergyTaskHelper; import com.gh.common.util.GsonUtils; import com.gh.common.util.LoginHelper; import com.gh.common.util.LoginUtils; +import com.gh.common.util.NewLogUtils; import com.gh.common.util.SPUtils; +import com.gh.download.DownloadManager; import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.R; import com.gh.gamecenter.entity.AvatarBorderEntity; @@ -35,6 +39,7 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.manager.UserManager; import com.gh.gamecenter.message.MessageUnreadRepository; import com.gh.gamecenter.personal.PersonalFragment; +import com.gh.gamecenter.retrofit.BiResponse; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.gh.gamecenter.retrofit.service.ApiService; @@ -199,7 +204,7 @@ public class UserRepository { loginTypeForHumanEyes = "手机"; userToken = content.getString("mobile"); observable = mApiService.loginByMobile(body); - } else if (loginTag == LoginTag.oauth) { + } else if (loginTag == LoginTag.oauth) { loginTypeForHumanEyes = "一键登录"; userToken = content.getString("token"); observable = mApiService.loginByOauth(body); @@ -307,15 +312,18 @@ public class UserRepository { } //更改用户信息 - public void changeUserInfo(final String content, final String editType) { - if (mCacheUserInfoEntity == null) { + @SuppressLint("CheckResult") + public void changeUserInfo(final String content, final String editType, final Boolean isForcedToCertificate) { + // 未登录也可以更新实名认证 https://git.ghzs.com/pm/halo-app-issues/-/issues/1526 (这里拦截掉实名更新类型的东西) + if (UserViewModel.TYPE_ID_CARD.equals(editType)) { + updateCertificate(content, isForcedToCertificate); return; } + JSONObject object = new JSONObject(); try { - if (editType.equals(UserViewModel.TYPE_ID_CARD) || - editType.equals(UserViewModel.TYPE_BACKGROUND) || - editType.equals(UserViewModel.TYPE_ICON_BORDER)) { + if (editType.equals(UserViewModel.TYPE_BACKGROUND) + || editType.equals(UserViewModel.TYPE_ICON_BORDER)) { object = new JSONObject(); object.put(editType, new JSONObject(content)); } else { @@ -441,6 +449,55 @@ public class UserRepository { .subscribe(userInfoResponse(loginTag)); } + /** + * 更新实名信息 + */ + @SuppressLint("CheckResult") + private void updateCertificate(final String content, final Boolean isForcedToCertificate) { + UserInfoEntity userInfoEntity = new UserInfoEntity(); + IdCardEntity idCardEntity = GsonUtils.fromJson(content, IdCardEntity.class); + userInfoEntity.setIdCard(idCardEntity); + RequestBody body = RequestBody.create( + MediaType.parse("application/json"), GsonUtils.toJson(userInfoEntity)); + RetrofitManager.getInstance(HaloApp.getInstance()).getApi().postCertification(body) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BiResponse() { + @Override + public void onSuccess(ResponseBody data) { + ApiResponse response = new ApiResponse<>(); + response.setData(new UserInfoEntity()); + mEditObsResponseUserInfo.postValue(response); + // 登录状态下更新实名认证信息 + if (mCacheUserInfoEntity != null) { + mCacheUserInfoEntity.setIdCard(GsonUtils.fromJson(content, IdCardEntity.class)); + userInfoHandle(mCacheUserInfoEntity, true); + } + try { + JSONObject object = new JSONObject(data.string()); + boolean isUnQualified = object.getBoolean("minor"); + int qualifyInt = 1; + if (!isUnQualified) { + qualifyInt = 2; + } + NewLogUtils.INSTANCE.logCertificationResult(isForcedToCertificate, qualifyInt); + } catch (Throwable e) { + e.printStackTrace(); + } + + // 重启因为实名认证而处于等待中的任务 + DownloadManager.getInstance(HaloApp.getInstance()).resumeAllInvisiblePendingTask(); + } + + @Override + public void onFailure(@NonNull Exception exception) { + mEditObsResponseUserInfo.postValue(null); + ErrorHelper.handleLoginError(HaloApp.getInstance(), (HttpException) exception); + NewLogUtils.INSTANCE.logCertificationResult(isForcedToCertificate, 0); + } + }); + } + private Response userInfoResponse(final LoginTag loginTag) { return new Response() { @Override diff --git a/app/src/main/java/com/gh/gamecenter/user/UserViewModel.java b/app/src/main/java/com/gh/gamecenter/user/UserViewModel.java index 67c5d1335c..33e43ee2b3 100644 --- a/app/src/main/java/com/gh/gamecenter/user/UserViewModel.java +++ b/app/src/main/java/com/gh/gamecenter/user/UserViewModel.java @@ -77,7 +77,11 @@ public class UserViewModel extends AndroidViewModel { } public void changeUserInfo(String content, String type) { - mUserRepository.changeUserInfo(content, type); + changeUserInfo(content, type, false); + } + + public void changeUserInfo(String content, String type, Boolean isForcedToCertificate) { + mUserRepository.changeUserInfo(content, type, isForcedToCertificate); } // 用EventBus通知退出登录会存在事件丢失问题(页面没创建),暂时直接调UserRepository做退出登录处理 diff --git a/app/src/main/java/com/halo/assistant/fragment/user/UserInfoEditFragment.java b/app/src/main/java/com/halo/assistant/fragment/user/UserInfoEditFragment.java index 4f5ad100d6..05ea19422b 100644 --- a/app/src/main/java/com/halo/assistant/fragment/user/UserInfoEditFragment.java +++ b/app/src/main/java/com/halo/assistant/fragment/user/UserInfoEditFragment.java @@ -19,9 +19,14 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProviders; +import com.gh.common.constant.Constants; import com.gh.common.util.DialogUtils; +import com.gh.common.util.EntranceUtils; import com.gh.common.util.ExtensionsKt; +import com.gh.common.util.GsonUtils; import com.gh.common.util.MtaHelper; +import com.gh.common.util.NewLogUtils; +import com.gh.common.util.SPUtils; import com.gh.common.util.TextHelper; import com.gh.common.view.UrlInterceptedLinkMovementMethod; import com.gh.gamecenter.R; @@ -108,6 +113,8 @@ public class UserInfoEditFragment extends NormalFragment { private String mEditType; + private Boolean mIsForcedToCertificate; + public static final String AUTH_SUCCESS = "auth_success";//认证通过 @Override @@ -120,6 +127,7 @@ public class UserInfoEditFragment extends NormalFragment { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mEditType = getArguments().getString(UserViewModel.KEY_EDIT_TYPE); + mIsForcedToCertificate = getArguments().getBoolean(EntranceUtils.KEY_IS_FORCED_TO_CERTICIFICE); initMenu(R.menu.menu_button); mSaveMenuItem = getItemMenu(R.id.menu_button); @@ -167,7 +175,7 @@ public class UserInfoEditFragment extends NormalFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - if (mUserInfoEntity != null) { + if (mUserInfoEntity != null || UserViewModel.TYPE_ID_CARD.equals(mEditType)) { initView(); } } @@ -240,23 +248,38 @@ public class UserInfoEditFragment extends NormalFragment { if (mSaveMenuItem != null) mSaveMenuItem.setVisible(false); mIdCard.setVisibility(View.VISIBLE); title = "实名认证"; - IdCardEntity idCard = mUserInfoEntity.getIdCard(); - if (idCard != null && !TextUtils.isEmpty(idCard.getName())) { - StringBuilder sb = new StringBuilder(idCard.getName().substring(0, 1)); - for (int i = 0; i < idCard.getName().length() - 1; i++) { - sb.append("*"); + + UserInfoEntity certificationOnlyInfoEntity = null; + String deviceCertificationInfoString = SPUtils.getString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + HaloApp.getInstance().getGid()); + if (!TextUtils.isEmpty(deviceCertificationInfoString)) { + certificationOnlyInfoEntity = GsonUtils.fromJson(deviceCertificationInfoString, UserInfoEntity.class); + if (mUserInfoEntity == null && certificationOnlyInfoEntity != null) { + mUserInfoEntity = certificationOnlyInfoEntity; } - mIdCardNameEt.setText(sb.toString()); - mIdCardEt.setText(idCard.getId().replaceAll("(\\d)\\d{16}([0-9,x-y])", "$1****************$2")); - mIdCardNameEt.setEnabled(false); - mIdCardEt.setEnabled(false); - mUserinfoCommit.setVisibility(View.GONE); - mUserinfoVerifiedSuccess.setVisibility(View.VISIBLE); - mUserInfoInformationTv.setVisibility(View.GONE); - } else { - mIdCardNameEt.setFilters(new InputFilter[]{TextHelper.getFilter(20, "最多20个字")}); - mIdCardEt.setFilters(new InputFilter[]{TextHelper.getFilter(18, "最多18个字")}); } + + if (mUserInfoEntity != null) { + IdCardEntity idCard = mUserInfoEntity.getIdCard(); + if (idCard != null && !TextUtils.isEmpty(idCard.getName())) { + StringBuilder sb = new StringBuilder(idCard.getName().substring(0, 1)); + for (int i = 0; i < idCard.getName().length() - 1; i++) { + sb.append("*"); + } + mIdCardNameEt.setText(sb.toString()); + mIdCardEt.setText(idCard.getId().replaceAll("(\\d)\\d{16}([0-9,x-y])", "$1****************$2")); + mIdCardNameEt.setEnabled(false); + mIdCardEt.setEnabled(false); + mUserinfoCommit.setVisibility(View.GONE); + mUserinfoVerifiedSuccess.setVisibility(View.VISIBLE); + mUserInfoInformationTv.setVisibility(View.GONE); + } else { + NewLogUtils.INSTANCE.logCertificationTriggerType(mIsForcedToCertificate); + } + } else { + NewLogUtils.INSTANCE.logCertificationTriggerType(mIsForcedToCertificate); + } + mIdCardNameEt.setFilters(new InputFilter[]{TextHelper.getFilter(20, "最多20个字")}); + mIdCardEt.setFilters(new InputFilter[]{TextHelper.getFilter(18, "最多18个字")}); break; case UserViewModel.TYPE_INTRODUCE: mUserInfoIntroduce.setVisibility(View.VISIBLE); diff --git a/dependencies.gradle b/dependencies.gradle index 54e01db044..9850ef7dda 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,8 +7,8 @@ ext { targetSdkVersion = 26 // application info (每个大版本之间的 versionCode 增加 20) - versionCode = 372 - versionName = "5.1.2" + versionCode = 374 + versionName = "5.1.4" applicationId = "com.gh.gamecenter" // AndroidX diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 6fafcf506f..9bcb3072af 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 6fafcf506ff32306d449323189a29e1eeeb157cc +Subproject commit 9bcb3072af706aec214c9909d289d22b362f9c85