diff --git a/app/build.gradle b/app/build.gradle
index 0427bbeb3d..69e6ba3d3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -353,7 +353,7 @@ dependencies {
implementation "io.github.florent37:shapeofview:$shapeOfView"
- implementation 'io.github.sinaweibosdk:core:11.6.0@aar'
+ implementation "io.github.sinaweibosdk:core:${weiboSDK}"
implementation project(':libraries:LGLibrary')
// implementation project(':libraries:MTA')
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ff4be2731b..7e4ec48515 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -722,6 +722,10 @@
+
+
= ArrayList()
+ private var mEditText: EditText? = null
+ private var drawableNormal: Drawable? = null
+ private var drawableSelected: Drawable? = null
+ private var mContext: Context? = null
+
+
+ //输入过程监听
+ private var mInputListener: InputListener? = null
+ //输入完成监听
+ private var mInputCompleteListener: InputCompleteListener? = null
+
+ /**
+ * view 添加到窗口时,延迟 500ms 弹出软键盘
+ */
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ mEditText?.postDelayed({ showSoftKeyBoard() }, 500)
+ }
+
+ /**
+ * 设置背景
+ * @param textView
+ * @param drawable
+ */
+ private fun setTextViewBackground(textView: TextView, drawable: Drawable?) {
+ if (drawable != null) textView.background = drawable
+ }
+
+ /**
+ * 获取当前输入的内容
+ *
+ * @return
+ */
+ val content: String
+ get() {
+ val text = mEditText?.text
+ return if (TextUtils.isEmpty(text)) "" else mEditText?.text.toString()
+ }
+
+ /**
+ * 清除内容
+ */
+ fun clearContent() {
+ mEditText?.setText("")
+ for (i in mTextViewList.indices) {
+ val textView = mTextViewList[i]
+ textView.text = ""
+ setTextViewBackground(textView, drawableNormal)
+ }
+ }
+
+ /**
+ * 设置默认的内容
+ *
+ * @param content
+ */
+ fun setDefaultContent(content: String) {
+ mEditText?.setText(content)
+ mEditText?.requestFocus()
+ val chars = content.toCharArray()
+ val min = chars.size.coerceAtMost(mTextViewList.size)
+ for (i in 0 until min) {
+ val aChar = chars[i]
+ val s = aChar.toString()
+ val textView = mTextViewList[i]
+ textView.text = s
+ setTextViewBackground(textView, drawableSelected)
+ }
+ if (mInputCompleteListener != null && min == mTextViewList.size) mInputCompleteListener?.onComplete(
+ content.substring(0, min)
+ )
+ }
+
+ /**
+ * 显示软键盘
+ */
+ private fun showSoftKeyBoard() {
+ val imm = mContext?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.showSoftInput(mEditText, InputMethodManager.SHOW_FORCED)
+ }
+
+ /**
+ * 添加输入完成的监听
+ *
+ * @param inputCompleteListener
+ */
+ fun addInputCompleteListener(inputCompleteListener: InputCompleteListener?) {
+ mInputCompleteListener = inputCompleteListener
+ val content = mEditText?.text
+ if (!TextUtils.isEmpty(content) && content.toString().length == mTextViewList.size) {
+ mInputCompleteListener?.onComplete(content.toString())
+ }
+ }
+
+ /**
+ * 添加输入过程的监听
+ *
+ * @param inputListener
+ */
+ fun addInputListener(inputListener: InputListener?) {
+ mInputListener = inputListener
+ mInputListener?.onChange(mEditText?.text.toString())
+ }
+
+ interface InputCompleteListener {
+ fun onComplete(content: String)
+ }
+
+ interface InputListener {
+ fun onChange(content: String)
+ }
+
+ private fun px2sp(context: Context, pxValue: Float): Int {
+ val fontScale = context.resources.displayMetrics.scaledDensity
+ return (pxValue / fontScale + 0.5f).toInt()
+ }
+
+ private fun sp2px(context: Context, spValue: Float): Int {
+ val fontScale = context.resources.displayMetrics.scaledDensity
+ return (spValue * fontScale + 0.5f).toInt()
+ }
+
+ companion object {
+ //默认 item 个数为 4 个
+ private const val DEFAULT_ITEM_COUNT = 4
+
+ //默认每个 item 的宽度为 100
+ private const val DEFAULT_ITEM_WIDTH = 100
+
+ //默认每个 item 的间距为 50
+ private const val DEFAULT_ITEM_MARGIN = 50
+
+ //默认每个 item 的字体大小为 14
+ private const val DEFAULT_ITEM_TEXT_SIZE = 14
+
+ //默认密码明文显示时间为 200ms,之后密文显示
+ private const val DEFAULT_PASSWORD_VISIBLE_TIME = 200
+ }
+
+ init {
+ mContext = context
+ orientation = HORIZONTAL
+ gravity = Gravity.CENTER
+ @SuppressLint("CustomViewStyleable") val obtainStyledAttributes =
+ getContext().obtainStyledAttributes(attrs, R.styleable.verify_EditText)
+ drawableNormal =
+ obtainStyledAttributes.getDrawable(R.styleable.verify_EditText_verify_background_normal)
+ drawableSelected =
+ obtainStyledAttributes.getDrawable(R.styleable.verify_EditText_verify_background_selected)
+ val textColor = obtainStyledAttributes.getColor(
+ R.styleable.verify_EditText_verify_textColor,
+ ContextCompat.getColor(context, R.color.black)
+ )
+ var count = obtainStyledAttributes.getInt(
+ R.styleable.verify_EditText_verify_count,
+ DEFAULT_ITEM_COUNT
+ )
+ val inputType = obtainStyledAttributes.getInt(
+ R.styleable.verify_EditText_verify_inputType,
+ InputType.TYPE_CLASS_NUMBER
+ )
+ val passwordVisibleTime = obtainStyledAttributes.getInt(
+ R.styleable.verify_EditText_verify_password_visible_time,
+ DEFAULT_PASSWORD_VISIBLE_TIME
+ )
+ val width = obtainStyledAttributes.getDimension(
+ R.styleable.verify_EditText_verify_width,
+ DEFAULT_ITEM_WIDTH.toFloat()
+ )
+ .toInt()
+ val height =
+ obtainStyledAttributes.getDimension(R.styleable.verify_EditText_verify_height, 0f)
+ .toInt()
+ val margin = obtainStyledAttributes.getDimension(
+ R.styleable.verify_EditText_verify_margin,
+ DEFAULT_ITEM_MARGIN.toFloat()
+ )
+ .toInt()
+ val textSize = px2sp(
+ context,
+ obtainStyledAttributes.getDimension(
+ R.styleable.verify_EditText_verify_textSize,
+ sp2px(context, DEFAULT_ITEM_TEXT_SIZE.toFloat()).toFloat()
+ )
+ ).toFloat()
+ val password =
+ obtainStyledAttributes.getBoolean(R.styleable.verify_EditText_verify_password, false)
+ obtainStyledAttributes.recycle()
+ if (count < 2) count = 2 //最少 2 个 item
+ mEditText = EditText(context)
+ mEditText?.inputType = inputType
+ mEditText?.layoutParams = LayoutParams(1, 1)
+ mEditText?.isCursorVisible = false
+ mEditText?.background = null
+ mEditText?.filters = arrayOf(LengthFilter(count)) //限制输入长度为 count
+ mEditText?.addTextChangedListener(object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+ val textView = mTextViewList[start] //获取对应的 textview
+ if (before == 0) { //输入
+ val input = s.subSequence(start, s.length) //获取新输入的字
+ textView.text = input
+ if (password) { //如果需要密文显示
+ textView.transformationMethod =
+ HideReturnsTransformationMethod.getInstance()
+ //passwordVisibleTime 毫秒后设置为密文显示
+ textView.postDelayed(
+ {
+ textView.transformationMethod =
+ PasswordTransformationMethod.getInstance()
+ },
+ passwordVisibleTime.toLong()
+ )
+ }
+ setTextViewBackground(textView, drawableSelected)
+ } else { //删除
+ textView.text = ""
+ setTextViewBackground(textView, drawableNormal)
+ }
+ mInputListener?.onChange(s.toString())
+ if (mInputCompleteListener != null && s.length == mTextViewList.size) mInputCompleteListener?.onComplete(
+ s.toString()
+ )
+ }
+
+ override fun afterTextChanged(s: Editable) {}
+ })
+ addView(mEditText)
+ //点击弹出软键盘
+ setOnClickListener {
+ mEditText?.requestFocus()
+ showSoftKeyBoard()
+ }
+ //遍历生成 textview
+ for (i in 0 until count) {
+ val textView = TextView(context)
+ textView.textSize = textSize
+ textView.gravity = Gravity.CENTER
+ textView.setTextColor(textColor)
+ val layoutParams = LayoutParams(
+ width,
+ if (height == 0) ViewGroup.LayoutParams.WRAP_CONTENT else height
+ )
+ if (i == 0) layoutParams.leftMargin = -1 else layoutParams.leftMargin = margin
+ textView.layoutParams = layoutParams
+ setTextViewBackground(textView, drawableNormal)
+ addView(textView)
+ mTextViewList.add(textView)
+ }
+ }
+}
diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java
index 42e5b3af50..75ade42c29 100644
--- a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.java
@@ -378,7 +378,7 @@ public class SplashScreenActivity extends BaseActivity {
private void prefetchData() {
AppExecutor.getIoExecutor().execute(() -> {
- if (HaloApp.getInstance().isBrandNewInstall) getTeenagerModel();
+ if (HaloApp.getInstance().isBrandNewInstall) getTeenagerMode();
Config.getGhzsSettings();
deviceDialogSetting();
getFilterDetailTags();
@@ -412,19 +412,19 @@ public class SplashScreenActivity extends BaseActivity {
}
@SuppressLint("CheckResult")
- private void getTeenagerModel() {
+ private void getTeenagerMode() {
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
- .getApi().getTeenagerModel(HaloApp.getInstance().getGid())
+ .getApi().getTeenagerMode(HaloApp.getInstance().getGid())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse() {
@Override
public void onSuccess(ResponseBody data) {
try {
- boolean preStatus = SPUtils.getBoolean(Constants.SP_TEENAGER_MODEL);
+ boolean preStatus = SPUtils.getBoolean(Constants.SP_TEENAGER_MODE);
JSONObject object = new JSONObject(data.string());
boolean curStatus = "open".equals(object.getString("status"));
- SPUtils.setBoolean(Constants.SP_TEENAGER_MODEL, curStatus);
+ SPUtils.setBoolean(Constants.SP_TEENAGER_MODE, curStatus);
if (preStatus != curStatus) {
EventBus.getDefault().post(new EBTeenagerModelStatus());
}
diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java
index 0685379e04..3d40cf1634 100644
--- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java
+++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java
@@ -49,6 +49,7 @@ import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBScroll;
import com.gh.gamecenter.gamedetail.GameDetailFragment;
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
+import com.gh.gamecenter.teenagermode.TeenagerModeActivity;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
@@ -341,8 +342,7 @@ public class DetailViewHolder {
DialogHelper.showCenterDialog(
mViewHolder.context,
"提示", "当前处于儿童/青少年模式, \n暂不提供游戏下载", "退出青少年模式", "关闭",
- () -> {
- },
+ () -> mViewHolder.context.startActivity(TeenagerModeActivity.getIntent(mViewHolder.context)),
() -> {
}
);
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java
index df688b82b5..a7bc460c20 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java
@@ -252,7 +252,7 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
mDownloadView.setVisibility(View.INVISIBLE);
}
- if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODEL)) {
+ if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
mTeenagerModelView.setVisibility(View.VISIBLE);
mSearchContainerView.setVisibility(View.GONE);
mSearchRightView.setVisibility(View.VISIBLE);
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 8386b6e1f6..c322d14e6c 100644
--- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt
@@ -26,6 +26,7 @@ import com.gh.gamecenter.mygame.MyGameActivity
import com.gh.gamecenter.qa.myqa.MyAskActivity
import com.gh.gamecenter.security.SecurityActivity
import com.gh.gamecenter.simulatorgame.SimulatorGameActivity
+import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.gamecenter.user.UserViewModel
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.halo.assistant.HaloApp
@@ -289,6 +290,7 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
}
}
"青少年模式" -> {
+ context.startActivity(TeenagerModeActivity.getIntent(context))
}
else -> {
DirectUtils.directToLinkPage(context, linkEntity, "", "我的光环")
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 ab29dd9739..eba7788d80 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
@@ -3227,5 +3227,29 @@ public interface ApiService {
* 获取青少年模式状态
*/
@GET("api_go/teen_mode/status")
- Single getTeenagerModel(@Query("android_id") String gid);
+ Single getTeenagerMode(@Query("android_id") String gid);
+
+ /**
+ * 青少年模式加锁
+ */
+ @POST("api_go/teen_mode/lock")
+ Single postTeenModeLock(@Body RequestBody body);
+
+ /**
+ * 青少年模式解锁
+ */
+ @POST("api_go/teen_mode/unlock")
+ Single postTeenModeUnlock(@Body RequestBody body);
+
+ /**
+ * 退出青少年模式
+ */
+ @POST("api_go/teen_mode/logout")
+ Single postTeenModeLogout(@Body RequestBody body);
+
+ /**
+ * 修改青少年模式密码
+ */
+ @PUT("api_go/teen_mode/password")
+ Single putTeenModePassword(@Body RequestBody body);
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt
index c9c1192fa8..40bc10f496 100644
--- a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt
@@ -287,7 +287,7 @@ class SearchGameIndexAdapter(context: Context,
}
- if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODEL)) {
+ if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
binding.gameItemIncluded.downloadBtn.visibility = View.GONE
} else {
binding.gameItemIncluded.downloadBtn.visibility = View.VISIBLE
diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt
index 0c40eba0fa..5c7c691018 100644
--- a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt
@@ -347,7 +347,7 @@ class SearchGameResultAdapter(context: Context,
}
- if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODEL)) {
+ if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
binding.gameItemIncluded.downloadBtn.visibility = View.GONE
} else {
binding.gameItemIncluded.downloadBtn.visibility = View.VISIBLE
diff --git a/app/src/main/java/com/gh/gamecenter/teenagermode/PasswordSettingFragment.kt b/app/src/main/java/com/gh/gamecenter/teenagermode/PasswordSettingFragment.kt
new file mode 100644
index 0000000000..df4e43b63a
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/teenagermode/PasswordSettingFragment.kt
@@ -0,0 +1,200 @@
+package com.gh.gamecenter.teenagermode
+
+import android.os.Bundle
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import com.gh.common.constant.Constants
+import com.gh.common.util.SPUtils
+import com.gh.common.util.isPublishEnv
+import com.gh.common.util.toColor
+import com.gh.common.view.VerifyEditText
+import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.MainActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.WebActivity
+import com.gh.gamecenter.databinding.FragmentPasswordSettingBinding
+import com.gh.gamecenter.normal.NormalFragment
+import com.lightgame.utils.AppManager
+
+class PasswordSettingFragment : NormalFragment() {
+
+ private var mBinding: FragmentPasswordSettingBinding? = null
+ private var mViewModel: TeenagerModeViewModel? = null
+
+ private var mPassword = ""
+ private var mLastPassword = ""
+
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout() =
+ FragmentPasswordSettingBinding.inflate(layoutInflater).apply { mBinding = this }.root
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mViewModel = ViewModelProvider(this).get(TeenagerModeViewModel::class.java)
+ mBinding?.resetPwdTv?.setOnClickListener {
+ val url = if (isPublishEnv()) {
+ Constants.TEEN_MODE_RESET_PASSWORD
+ } else {
+ Constants.TEEN_MODE_RESET_PASSWORD_DEV
+ }
+ startActivity(WebActivity.getWebIntent(requireContext(), "找回密码", url))
+ }
+ when (requireArguments().getString(TeenagerModeActivity.TYPE)) {
+ TeenagerModeActivity.TYPE_ENABLE -> showEnable()
+ TeenagerModeActivity.TYPE_DISABLE -> showDisable()
+ TeenagerModeActivity.TYPE_CHANGE_PWD -> showChangePwd()
+ }
+ }
+
+ private fun showEnable() {
+ mBinding?.titleTv?.text = "设置密码"
+ mBinding?.hintTv?.text = "启动儿童/青少年模式,需要先设置独立密码"
+ mBinding?.resetPwdTv?.visibility = View.GONE
+ mBinding?.verifyEt?.run {
+ requestFocus()
+ addInputListener(object : VerifyEditText.InputListener {
+ override fun onChange(content: String) {
+ mBinding?.nextTv?.alpha = if (content.length < 4) 0.4F else 1F
+ if (content.length < 4) mBinding?.nextTv?.setOnClickListener(null)
+ }
+ })
+ addInputCompleteListener(object : VerifyEditText.InputCompleteListener {
+ override fun onComplete(content: String) {
+ mBinding?.nextTv?.alpha = 1F
+ mBinding?.nextTv?.setOnClickListener {
+ mPassword = content
+ clearContent()
+ mBinding?.titleTv?.text = "确认密码"
+ mBinding?.hintTv?.text = "再次输入密码"
+ mBinding?.nextTv?.alpha = 0.4F
+ it.setOnClickListener(null)
+ addInputCompleteListener(object : VerifyEditText.InputCompleteListener {
+ override fun onComplete(content: String) {
+ mBinding?.nextTv?.alpha = 1F
+ it.setOnClickListener {
+ if (content == mPassword) {
+ mViewModel?.postTeenModeLock(mPassword) {
+ SPUtils.setBoolean(Constants.SP_TEENAGER_MODE, true)
+ toast("儿童/青少年模式已开启")
+ directToSplash()
+ }
+ } else {
+ mBinding?.hintTv?.text = "与第一次输入的密码不一致"
+ mBinding?.hintTv?.setTextColor(R.color.theme_red.toColor())
+ clearContent()
+ }
+ }
+ }
+ })
+ }
+ }
+ })
+ }
+ }
+
+ private fun showDisable() {
+ mBinding?.titleTv?.text = "关闭儿童/青少年模式"
+ mBinding?.hintTv?.text = "请输入密码确认"
+ mBinding?.resetPwdTv?.visibility = View.VISIBLE
+ mBinding?.verifyEt?.run {
+ requestFocus()
+ addInputListener(object : VerifyEditText.InputListener {
+ override fun onChange(content: String) {
+ mBinding?.nextTv?.alpha = if (content.length < 4) 0.4F else 1F
+ if (content.length < 4) mBinding?.nextTv?.setOnClickListener(null)
+ }
+ })
+ addInputCompleteListener(object : VerifyEditText.InputCompleteListener {
+ override fun onComplete(content: String) {
+ mBinding?.nextTv?.alpha = 1F
+ mBinding?.nextTv?.setOnClickListener {
+ mViewModel?.postTeenModeLogout(content, {
+ SPUtils.setBoolean(Constants.SP_TEENAGER_MODE, false)
+ toast("儿童/青少年模式已关闭")
+ directToSplash()
+ }, {
+ clearContent()
+ mBinding?.hintTv?.text = "密码错误请重新输入"
+ mBinding?.hintTv?.setTextColor(R.color.theme_red.toColor())
+ })
+ }
+ }
+ })
+ }
+ }
+
+ private fun showChangePwd() {
+ mBinding?.titleTv?.text = "修改密码"
+ mBinding?.hintTv?.text = "请输入当前密码"
+ mBinding?.resetPwdTv?.visibility = View.VISIBLE
+ mBinding?.verifyEt?.run {
+ requestFocus()
+ addInputListener(object : VerifyEditText.InputListener {
+ override fun onChange(content: String) {
+ mBinding?.nextTv?.alpha = if (content.length < 4) 0.4F else 1F
+ if (content.length < 4) mBinding?.nextTv?.setOnClickListener(null)
+ }
+ })
+ addInputCompleteListener(object : VerifyEditText.InputCompleteListener {
+ override fun onComplete(content: String) {
+ mBinding?.nextTv?.alpha = 1F
+ mBinding?.nextTv?.setOnClickListener {
+ mViewModel?.postTeenModeUnlock(content, {
+ mLastPassword = content
+ clearContent()
+ mBinding?.titleTv?.text = "请输入新密码"
+ mBinding?.hintTv?.text = "设置新的独立密码"
+ mBinding?.hintTv?.setTextColor(R.color.text_subtitle.toColor())
+ addInputCompleteListener(object : VerifyEditText.InputCompleteListener {
+ override fun onComplete(content: String) {
+ mBinding?.nextTv?.alpha = 1F
+ mBinding?.nextTv?.setOnClickListener {
+ mPassword = content
+ clearContent()
+ mBinding?.titleTv?.text = "确认密码"
+ mBinding?.hintTv?.text = "再次输入密码"
+ mBinding?.nextTv?.alpha = 0.4F
+ it.setOnClickListener(null)
+ addInputCompleteListener(object : VerifyEditText.InputCompleteListener {
+ override fun onComplete(content: String) {
+ mBinding?.nextTv?.alpha = 1F
+ it.setOnClickListener {
+ if (content == mPassword) {
+ mViewModel?.putTeenModePwd(mLastPassword, mPassword, {
+ toast("设置成功")
+ requireActivity().onBackPressed()
+ }, {
+ toast("网络异常")
+ })
+ } else {
+ mBinding?.hintTv?.text = "与第一次输入的密码不一致"
+ mBinding?.hintTv?.setTextColor(R.color.theme_red.toColor())
+ clearContent()
+ }
+ }
+ }
+ })
+ }
+ }
+ })
+ }, {
+ clearContent()
+ mBinding?.hintTv?.text = "密码错误请重新输入"
+ mBinding?.hintTv?.setTextColor(R.color.theme_red.toColor())
+ })
+ }
+ }
+ })
+ }
+ }
+
+ private fun directToSplash() {
+ AppManager.getInstance().finishActivity(AppManager.getInstance().findActivity(MainActivity::class.java))
+ AppManager.getInstance().finishActivity(AppManager.getInstance().findActivity(GameDetailActivity::class.java))
+ startActivity(MainActivity.getMainIntent(requireActivity()).apply {
+ putExtra(MainActivity.SHOW_AD, true)
+ })
+ requireActivity().finish()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt
new file mode 100644
index 0000000000..3984ca9be7
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt
@@ -0,0 +1,37 @@
+package com.gh.gamecenter.teenagermode
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import com.gh.base.BaseActivity
+import com.gh.gamecenter.R
+
+class TeenagerModeActivity : BaseActivity() {
+
+ private var mContainerFragment: Fragment? = null
+
+ override fun getLayoutId() = R.layout.activity_amway
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mContainerFragment = supportFragmentManager.findFragmentByTag(TeenagerModeFragment::class.java.simpleName)
+ ?: TeenagerModeFragment().with(intent.extras)
+ supportFragmentManager.beginTransaction().replace(R.id.placeholder, mContainerFragment!!, TeenagerModeFragment::class.java.simpleName).commitAllowingStateLoss()
+ }
+
+ override fun preventRecreateFragmentByFragmentManager(): Boolean = true
+
+ companion object {
+
+ const val TYPE = "type"
+ const val TYPE_ENABLE = "enable"
+ const val TYPE_DISABLE = "disable"
+ const val TYPE_CHANGE_PWD = "change_pwd"
+
+ @JvmStatic
+ fun getIntent(context: Context): Intent {
+ return Intent(context, TeenagerModeActivity::class.java)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeFragment.kt b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeFragment.kt
new file mode 100644
index 0000000000..39aa8a4bed
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeFragment.kt
@@ -0,0 +1,82 @@
+package com.gh.gamecenter.teenagermode
+
+import android.os.Bundle
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.gh.common.constant.Constants
+import com.gh.common.util.SPUtils
+import com.gh.common.util.SpanBuilder
+import com.gh.common.util.dip2px
+import com.gh.common.util.isPublishEnv
+import com.gh.common.view.CustomLinkMovementMethod
+import com.gh.gamecenter.R
+import com.gh.gamecenter.WebActivity
+import com.gh.gamecenter.databinding.FragmentTeenagerModeBinding
+import com.gh.gamecenter.normal.NormalFragment
+
+class TeenagerModeFragment : NormalFragment() {
+
+ private var mBinding: FragmentTeenagerModeBinding? = null
+
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout() = FragmentTeenagerModeBinding.inflate(layoutInflater).apply { mBinding = this }.root
+
+ override fun onResume() {
+ super.onResume()
+ val bundle = Bundle()
+ if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE, false)) {
+ bundle.putString(TeenagerModeActivity.TYPE, TeenagerModeActivity.TYPE_DISABLE)
+ showDisable()
+ } else {
+ bundle.putString(TeenagerModeActivity.TYPE, TeenagerModeActivity.TYPE_ENABLE)
+ showEnable()
+ }
+ mBinding?.switchTv?.setOnClickListener {
+ val mContainerFragment = requireActivity().supportFragmentManager.findFragmentByTag(PasswordSettingFragment::class.java.simpleName)
+ ?: PasswordSettingFragment().with(bundle)
+ requireActivity().supportFragmentManager.beginTransaction().run {
+ addToBackStack(null)
+ add(R.id.placeholder, mContainerFragment!!, PasswordSettingFragment::class.java.simpleName).commitAllowingStateLoss()
+ }
+ }
+ }
+
+ private fun showEnable() {
+ mBinding?.hintTv?.visibility = View.VISIBLE
+ mBinding?.changePwdTv?.visibility = View.GONE
+ mBinding?.titleTv?.text = "儿童/青少年模式"
+ mBinding?.switchTv?.text = "开启儿童/青少年模式"
+ val clickText = "《儿童/青少年使用须知》"
+ val hintText = "更多信息可阅读 $clickText"
+ mBinding?.hintTv?.text = SpanBuilder(hintText).click(
+ hintText.length - clickText.length, hintText.length,
+ R.color.theme_font, false
+ ) {
+ val url = if (isPublishEnv()) {
+ Constants.TEEN_MODE_RULE
+ } else {
+ Constants.TEEN_MODE_RULE_DEV
+ }
+ startActivity(WebActivity.getWebIntent(requireContext(), "儿童/青少年使用须知", url))
+ }.build()
+ mBinding?.hintTv?.movementMethod = CustomLinkMovementMethod.getInstance()
+ }
+
+ private fun showDisable() {
+ mBinding?.hintTv?.visibility = View.GONE
+ mBinding?.changePwdTv?.visibility = View.VISIBLE
+ mBinding?.titleTv?.text = "儿童/青少年模式已开启"
+ mBinding?.switchTv?.text = "关闭儿童/青少年模式"
+ mBinding?.switchTv?.layoutParams = (mBinding?.switchTv?.layoutParams as ConstraintLayout.LayoutParams).apply { setMargins(0, 0, 0, 68F.dip2px()) }
+ mBinding?.changePwdTv?.setOnClickListener {
+ val bundle = Bundle().apply { putString(TeenagerModeActivity.TYPE, TeenagerModeActivity.TYPE_CHANGE_PWD) }
+ val mContainerFragment = requireActivity().supportFragmentManager.findFragmentByTag(PasswordSettingFragment::class.java.simpleName)
+ ?: PasswordSettingFragment().with(bundle)
+ requireActivity().supportFragmentManager.beginTransaction().run {
+ addToBackStack(null)
+ add(R.id.placeholder, mContainerFragment!!, PasswordSettingFragment::class.java.simpleName).commitAllowingStateLoss()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeViewModel.kt b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeViewModel.kt
new file mode 100644
index 0000000000..2a2ab09540
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeViewModel.kt
@@ -0,0 +1,97 @@
+package com.gh.gamecenter.teenagermode
+
+import android.annotation.SuppressLint
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import com.gh.common.util.createRequestBody
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+import okhttp3.ResponseBody
+
+class TeenagerModeViewModel(application: Application) : AndroidViewModel(application) {
+
+ @SuppressLint("CheckResult")
+ fun postTeenModeLock(pwd: String, successCb: () -> Unit) {
+ val body = hashMapOf(
+ Pair("android_id", HaloApp.getInstance().gid),
+ Pair("password", pwd),
+ Pair("password_again", pwd)
+ ).createRequestBody()
+ RetrofitManager.getInstance(getApplication()).api.postTeenModeLock(body)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ successCb.invoke()
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun postTeenModeUnlock(pwd: String, successCb: () -> Unit, failureCb: () -> Unit) {
+ val body = hashMapOf(
+ Pair("android_id", HaloApp.getInstance().gid),
+ Pair("password", pwd)
+ ).createRequestBody()
+ RetrofitManager.getInstance(getApplication()).api.postTeenModeUnlock(body)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ successCb.invoke()
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ failureCb.invoke()
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun postTeenModeLogout(pwd: String, successCb: () -> Unit, failureCb: () -> Unit) {
+ val body = hashMapOf(
+ Pair("android_id", HaloApp.getInstance().gid),
+ Pair("password", pwd)
+ ).createRequestBody()
+ RetrofitManager.getInstance(getApplication()).api.postTeenModeLogout(body)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ successCb.invoke()
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ failureCb.invoke()
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun putTeenModePwd(pwd: String, newPwd: String, successCb: () -> Unit, failureCb: () -> Unit) {
+ val body = hashMapOf(
+ Pair("last_password", pwd),
+ Pair("android_id", HaloApp.getInstance().gid),
+ Pair("password", newPwd),
+ Pair("password_again", newPwd)
+ ).createRequestBody()
+ RetrofitManager.getInstance(getApplication()).api.putTeenModePassword(body)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ successCb.invoke()
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ failureCb.invoke()
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxxhdpi/teenager_mode_logo.webp b/app/src/main/res/drawable-xxxhdpi/teenager_mode_logo.webp
new file mode 100644
index 0000000000..2f5116ba76
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/teenager_mode_logo.webp differ
diff --git a/app/src/main/res/drawable/bg_verify_password.xml b/app/src/main/res/drawable/bg_verify_password.xml
new file mode 100644
index 0000000000..03a0f28e6d
--- /dev/null
+++ b/app/src/main/res/drawable/bg_verify_password.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_password_setting.xml b/app/src/main/res/layout/fragment_password_setting.xml
new file mode 100644
index 0000000000..a94392cbd6
--- /dev/null
+++ b/app/src/main/res/layout/fragment_password_setting.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_teenager_mode.xml b/app/src/main/res/layout/fragment_teenager_mode.xml
new file mode 100644
index 0000000000..b1a1c47f21
--- /dev/null
+++ b/app/src/main/res/layout/fragment_teenager_mode.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index cbded751b4..f705539dba 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -166,4 +166,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a9fa252241..6e1403884e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -863,4 +863,5 @@
该游戏暂时仅提供试玩版本。试玩版资源来自第三方网站,可能存在bug或兼容性问题。敬请留意后续相关消息。
该游戏暂时仅提供试玩版本。试玩版可能存在bug或兼容性问题。敬请留意后续相关消息。
游戏停服更新维护中,为避免情绪化内容对游戏评分带来的影响,因此开启停服保护功能。在停服保护状态期间,所新增及修改发布的评分将不计入总分,所评分评论内容在展示上也会有文字提示告知其他玩家。\n\n感谢您的配合及谅解,祝您游戏愉快!\n\n光环助手会持续关注产品建议及反馈,如您在使用过程中有任何问题,欢迎向我们反馈。
+ 开启青少年模式后,系统将自动关闭所有游戏的下载功能,需要输入密码才能恢复使用\n\n开启青少年模式,需要先设置独立密码,如忘记密码可联系客服申述重置\n\n青少年模式是光环助手响应国家政策,为促进青少年健康成长的一种模式,我们优先针对核心场景进行优化,也将继续致力于优化更多场景
diff --git a/dependencies.gradle b/dependencies.gradle
index 1a9c4d661a..f1ae6959f7 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -52,8 +52,7 @@ ext {
switchButton = "1.4.5"
swipeLayout = "1.2.0@aar"
autoScrollViewPager = "1.1.2"
- weiboSDK = "2.0.3:openDefaultRelease@aar"
-
+ weiboSDK = "11.6.0@aar"
apkChannelPackage = "1.0.5"
//Test