diff --git a/app/build.gradle b/app/build.gradle index e924b801db..93f73ff163 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,6 +76,8 @@ android { buildConfigField "String", "TTAD_APPID", "\"${TTAD_APPID}\"" buildConfigField "String", "DOUYIN_CLIENTKEY", "\"${DOUYIN_CLIENTKEY}\"" buildConfigField "String", "DOUYIN_CLIENTSECRET", "\"${DOUYIN_CLIENTSECRET}\"" + buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\"" + buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\"" buildConfigField "String", "MIPUSH_APPID", "\"${MIPUSH_APPID}\"" buildConfigField "String", "MIPUSH_APPKEY", "\"${MIPUSH_APPKEY}\"" diff --git a/app/libs/quick_login_android_5.8.1.aar b/app/libs/quick_login_android_5.8.1.aar new file mode 100644 index 0000000000..7f877f15dd Binary files /dev/null and b/app/libs/quick_login_android_5.8.1.aar differ diff --git a/app/proguard-rules.txt b/app/proguard-rules.txt index 4bca71a4d2..d7a11b8e8b 100644 --- a/app/proguard-rules.txt +++ b/app/proguard-rules.txt @@ -127,4 +127,8 @@ ### 阿里云日志 -keep class com.aliyun.sls.android.producer.* { *; } --keep interface com.aliyun.sls.android.producer.* { *; } \ No newline at end of file +-keep interface com.aliyun.sls.android.producer.* { *; } + +### 中国移动一键登录 +-dontwarn class com.cmic.sso.sdk.** +-keep class com.cmic.sso.sdk.**{*;} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b753ebee75..d89e1ed742 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,6 +21,8 @@ + + @@ -76,6 +78,7 @@ android:largeHeap="true" android:resizeableActivity="true" android:theme="@style/AppCompatTheme.APP" + android:networkSecurityConfig="@xml/network_security_config" tools:replace="android:allowBackup" tools:targetApi="n"> @@ -632,6 +635,14 @@ android:name=".category2.CategoryV2Activity" android:screenOrientation="portrait" /> + + + startActivity(LoginActivity.getIntent(BaseActivity.this, - "你的账号已在另外一台设备登录多设备-重新登录")) + , () -> { + if (NetworkUtils.isOpenMobileData(BaseActivity.this)) { + QuickLoginHelper.startLogin(BaseActivity.this, "你的账号已在另外一台设备登录多设备-重新登录"); + } else { + startActivity(LoginActivity.getIntent(BaseActivity.this, + "你的账号已在另外一台设备登录多设备-重新登录")); + } + } ); mBaseHandler.postDelayed(() -> mIsExistLogoutDialog = false, 5000); } catch (Exception e) { diff --git a/app/src/main/java/com/gh/common/DefaultJsApi.kt b/app/src/main/java/com/gh/common/DefaultJsApi.kt index f04f795af8..f82f733f81 100644 --- a/app/src/main/java/com/gh/common/DefaultJsApi.kt +++ b/app/src/main/java/com/gh/common/DefaultJsApi.kt @@ -70,8 +70,12 @@ class DefaultJsApi(var context: Context) { @JavascriptInterface fun login(msg: Any) { - val intent = LoginActivity.getIntent(context, "浏览器") - context.startActivity(intent) + if (NetworkUtils.isOpenMobileData(context)) { + QuickLoginHelper.startLogin(context, "浏览器") + } else { + val intent = LoginActivity.getIntent(context, "浏览器") + context.startActivity(intent) + } } @JavascriptInterface diff --git a/app/src/main/java/com/gh/common/constant/Config.java b/app/src/main/java/com/gh/common/constant/Config.java index f05a797a3a..d7a885322a 100644 --- a/app/src/main/java/com/gh/common/constant/Config.java +++ b/app/src/main/java/com/gh/common/constant/Config.java @@ -55,6 +55,8 @@ public class Config { public static final String TTAD_APPID = BuildConfig.TTAD_APPID; public static final String DOUYIN_CLIENTKEY = BuildConfig.DOUYIN_CLIENTKEY; public static final String DOUYIN_CLIENTSECRET = BuildConfig.DOUYIN_CLIENTSECRET; + public static final String QUICK_LOGIN_APPID = BuildConfig.QUICK_LOGIN_APPID; + public static final String QUICK_LOGIN_APPKEY = BuildConfig.QUICK_LOGIN_APPKEY; // http://www.ghzs666.com/article/${articleId}.html public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一 public static final String PATCHES = "patches"; diff --git a/app/src/main/java/com/gh/common/util/CheckLoginUtils.java b/app/src/main/java/com/gh/common/util/CheckLoginUtils.java index 8789366136..f1d1996b79 100644 --- a/app/src/main/java/com/gh/common/util/CheckLoginUtils.java +++ b/app/src/main/java/com/gh/common/util/CheckLoginUtils.java @@ -24,11 +24,15 @@ public class CheckLoginUtils { LogUtils.login("dialog", null, entrance); LogUtils.login("activity", null, entrance); - // 有可能App未启动 - Bundle bundle = new Bundle(); - bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance); - bundle.putString(EntranceUtils.KEY_TO, LoginActivity.class.getName()); - EntranceUtils.jumpActivity(context, bundle); + if (NetworkUtils.isOpenMobileData(context)) { + QuickLoginHelper.startLogin(context, entrance); + } else { + // 有可能App未启动 + Bundle bundle = new Bundle(); + bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance); + bundle.putString(EntranceUtils.KEY_TO, LoginActivity.class.getName()); + EntranceUtils.jumpActivity(context, bundle); + } } else { if (listener != null) { listener.onLogin(); diff --git a/app/src/main/java/com/gh/common/util/DialogUtils.java b/app/src/main/java/com/gh/common/util/DialogUtils.java index de30f542b3..8aa635e271 100644 --- a/app/src/main/java/com/gh/common/util/DialogUtils.java +++ b/app/src/main/java/com/gh/common/util/DialogUtils.java @@ -63,6 +63,7 @@ import com.gh.gamecenter.AboutActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.SuggestionActivity; import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder; +import com.gh.gamecenter.databinding.DialogBindPhoneBinding; import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding; import com.gh.gamecenter.databinding.DialogPackageParseErrorBinding; import com.gh.gamecenter.databinding.DialogReportReasonBinding; @@ -2147,6 +2148,26 @@ public class DialogUtils { dialog.show(); } + public static void showBindPhoneDialog(Context context, ConfirmListener listener) { + context = checkDialogContext(context); + + final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent); + DialogBindPhoneBinding binding = DialogBindPhoneBinding.inflate(LayoutInflater.from(context)); + + binding.positiveTv.setOnClickListener(v -> { + dialog.dismiss(); + listener.onConfirm(); + }); + + binding.closeIv.setOnClickListener(v -> { + dialog.dismiss(); + }); + + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.setContentView(binding.getRoot()); + dialog.show(); + } + /** * @param context may be is application context * @return activity context diff --git a/app/src/main/java/com/gh/common/util/NetworkUtils.java b/app/src/main/java/com/gh/common/util/NetworkUtils.java index 9cc3ccf503..16941360d9 100644 --- a/app/src/main/java/com/gh/common/util/NetworkUtils.java +++ b/app/src/main/java/com/gh/common/util/NetworkUtils.java @@ -5,6 +5,11 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.telephony.TelephonyManager; +import com.cmic.sso.sdk.auth.AuthnHelper; + +import org.json.JSONException; +import org.json.JSONObject; + public class NetworkUtils { /** @@ -75,6 +80,26 @@ public class NetworkUtils { return false; } + /** + * 判断是否打开数据流量 + * + * 需要权限:READ_PHONE_STATE, ACCESS_NETWORK_STATE + * operatorType获取网络运营商: 0.未知 1.移动流量 2.联通流量网络 3.电信流量网络 + * networkType 网络状态:0未知;1流量 2 wifi;3 数据流量+wifi + */ + public static boolean isOpenMobileData(Context context){ + AuthnHelper helper = AuthnHelper.getInstance(context); + JSONObject jsonObject = helper.getNetworkType(context); + int net; + try { + net = Integer.parseInt(jsonObject.getString("networkType")); + if (net == 1 || net == 3) return true; + } catch (JSONException e) { + e.printStackTrace(); + } + return false; + } + /** * 获取当前网络连接的类型信息 * diff --git a/app/src/main/java/com/gh/common/util/QuickLoginHelper.kt b/app/src/main/java/com/gh/common/util/QuickLoginHelper.kt new file mode 100644 index 0000000000..f8c2e54ad3 --- /dev/null +++ b/app/src/main/java/com/gh/common/util/QuickLoginHelper.kt @@ -0,0 +1,204 @@ +package com.gh.common.util + +import android.annotation.SuppressLint +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.Window +import android.view.WindowManager +import com.cmic.sso.sdk.AuthThemeConfig +import com.cmic.sso.sdk.auth.AuthnHelper +import com.cmic.sso.sdk.auth.LoginClickListener +import com.cmic.sso.sdk.auth.TokenListener +import com.gh.common.constant.Config +import com.gh.common.util.PermissionHelper.checkReadPhoneStatePermissionBeforeAction +import com.gh.common.util.ToastUtils.toast +import com.gh.gamecenter.LoginActivity +import com.gh.gamecenter.R +import com.gh.gamecenter.databinding.DialogQuickLoginBinding +import com.gh.gamecenter.databinding.SetWaitDialogBinding +import com.gh.gamecenter.entity.LoginTokenEntity +import com.gh.gamecenter.user.ApiResponse +import com.gh.gamecenter.user.LoginTag +import com.gh.gamecenter.user.UserRepository +import org.json.JSONObject +import java.util.* + +/** + * 一键登录辅助类 + * 1.取号请求 + * 2.授权请求 + * 3.获取token + * 4.请求登录接口 + */ +object QuickLoginHelper { + + private var mAuthnHelper: AuthnHelper? = null + private var mTokenListener: TokenListener? = null + private var mDialog: Dialog? = null + private var mToken: String = "" + private const val REQUEST_GET_PHONE_INFO_CODE = 100 + private const val REQUEST_LOGIN_AUTH_CODE = 101 + + @JvmStatic + fun startLogin(context: Context, entrance: String) { + AuthnHelper.setDebugMode(true) + mAuthnHelper = AuthnHelper.getInstance(context.applicationContext) + mAuthnHelper?.run { + authThemeConfig = getConfig(context, entrance) + // 授权页面的回调方法 + setPageInListener { code, jsonObject -> + // 返回码200087代表授权页成功拉起 +// if (code == "200087") { +// } else { +// } + } + + // token回调 + mTokenListener = TokenListener { requestCode: Int, jsonObject: JSONObject -> + // “103000”为成功 + if (jsonObject.optString("resultCode") == "103000") { + when (requestCode) { + REQUEST_GET_PHONE_INFO_CODE -> { + // 2.授权请求 + mAuthnHelper!!.loginAuth(Config.QUICK_LOGIN_APPID, Config.QUICK_LOGIN_APPKEY, mTokenListener, REQUEST_LOGIN_AUTH_CODE) + } + + REQUEST_LOGIN_AUTH_CODE -> { + // 3.获取token + mToken = jsonObject.optString("token") + } + } + } + } + + checkReadPhoneStatePermissionBeforeAction(context, object : EmptyCallback { + override fun onCallback() { + // 1.取号请求 + mAuthnHelper!!.getPhoneInfo(Config.QUICK_LOGIN_APPID, Config.QUICK_LOGIN_APPKEY, mTokenListener, REQUEST_GET_PHONE_INFO_CODE) + } + }) + } + } + + private fun getConfig(context: Context, entrance: String): AuthThemeConfig{ + return AuthThemeConfig.Builder() + .setStatusBar(Color.WHITE, true) //状态栏颜色、是否高亮 + .setAuthContentView(getCustomView(context)) //自定义布局 + // 服务条款标题栏 + .setClauseLayoutResID(R.layout.layout_quick_login_navigation, "backIv") //服务条款标题栏 + .setNavTextColor(Color.BLACK) //服务条款标题颜色 + .setNavTextSize(18) //服务条款标题字体大小 + // 手机号码 + .setNumberSize(20, true) //手机号码字体大小 + .setNumberColor(R.color.text_333333.toColor()) //手机号码字体颜色 + .setNumFieldOffsetY(95) //号码栏Y偏移量 + // 登录按钮 + .setLogBtnImgPath("login_btn_bg") //登录按钮背景 + .setLogBtnText("本机号码一键登录", Color.WHITE, 16, false) //登录按钮相关 + .setLogBtnOffsetY(170) //登录按钮Y偏移量 + .setLogBtn(1000, 44) //登录按钮相关宽高 + .setLogBtnMargin(20, 20) //登录按钮相对于屏幕左右边缘边距 + // 回调 + .setBackPressedListener {} //返回键回调 + .setLogBtnClickListener(object : LoginClickListener { + override fun onLoginClickStart(context: Context, jsonObj: JSONObject?) { + LogUtils.login("logging", "一键登录", entrance) + mDialog = Dialog(context, R.style.DialogWindowTransparent).apply { + val binding = SetWaitDialogBinding.inflate(LayoutInflater.from(context)).apply { + setWaitMessage.text = R.string.logging.toResString() + } + requestWindowFeature(Window.FEATURE_NO_TITLE) + setContentView(binding.root) + setCanceledOnTouchOutside(false) + show() + } + } + + override fun onLoginClickComplete(context: Context, jsonObj: JSONObject?) { + if (mToken.isNotBlank()) { + val params = HashMap() + params["token"] = mToken + + // 4.请求登录接口 + UserRepository.getInstance(context).login( + JSONObject(params as Map<*, *>), + LoginTag.oauth, + object : BiCallback> { + override fun onFirst(first: LoginTokenEntity) { + if (mDialog != null && mDialog!!.isShowing) { + mDialog?.dismiss() + } + LogUtils.login("success", "一键登录", entrance) + mAuthnHelper?.quitAuthActivity() + } + + override fun onSecond(second: ApiResponse) { + if (mDialog != null && mDialog!!.isShowing) { + mDialog?.dismiss() + } + } + } + ) + } else { + if (mDialog != null && mDialog!!.isShowing) { + mDialog?.dismiss() + } + } + } + }) //登录按钮回调 + .setCheckBoxListener { _: Context?, _: JSONObject? -> + toast("请先勾选同意《${getOperatorType(context)}认证服务协议》《用户协议》《隐私政策》") + } //勾选回调 + // 勾选框 + .setCheckTipText("") //设置未勾选时弹出提示 + .setCheckBoxImgPath("ic_quick_login_check", "ic_quick_login_uncheck", 12, 12) //勾选图片 + // 服务条款、用户协议、隐私政策 + .setPrivacyState(false) //默认不勾选 + .setPrivacyAlignment("阅读并同意 " + AuthThemeConfig.PLACEHOLDER + " 用户协议 隐私政策", + "用户协议", R.string.disclaimer_url.toResString(), + "隐私政策", R.string.privacy_policy_url.toResString(), + "", "", "", "") //隐私条款的协议文本,自定义条款,自定义条款链接(支持四份条款) + .setPrivacyText(11, R.color.text_999999.toColor(), R.color.theme_font.toColor(), true, false) //条款文本设置 + .setPrivacyMargin(30, 32) //隐私条款距离手机左右边缘的边距 + .setPrivacyOffsetY(230) //隐私条款Y偏移量 + // 语言 + .setAppLanguageType(0) //0.中文简体1.中文繁体2.英文 + // 整体布局 + .setAuthPageWindowMode(WindowManager.LayoutParams.MATCH_PARENT, 320) //授权页窗口宽高比例 + .setWindowBottom(1) //授权页是否居于底部,0=居中;1=底部,设置为1Y轴的偏移 失效 + .setThemeId(R.style.quickLoginDialog) //授权页弹窗主题 + .build() + } + + // 获取自定义布局View + @SuppressLint("SetTextI18n") + private fun getCustomView(context: Context): View { + return DialogQuickLoginBinding.inflate(LayoutInflater.from(context)).apply { + closeIv.setOnClickListener { + mAuthnHelper?.quitAuthActivity() + } + changeLoginIv.setOnClickListener { + mAuthnHelper?.quitAuthActivity() + context.startActivity(LoginActivity.getIntent(context, "一键登录")) + } + descTv.text = "${getOperatorType(context)}提供认证服务" + }.root + } + + // 获取运营商名称 + private fun getOperatorType(context: Context): String { + mAuthnHelper?.run { + val jsonObject = getNetworkType(context) + tryWithDefaultCatch { + val net = jsonObject.optString("operatorType").toInt() + if (net == 1) return "中国移动" + if (net == 2) return "中国联通" + if (net == 3) return "中国电信" + } + } + return "" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java index 29a6ca9d93..60b9f0ffbb 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java +++ b/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java @@ -1,6 +1,7 @@ package com.gh.gamecenter.fragment; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.os.Message; import android.text.Editable; @@ -11,8 +12,14 @@ import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; +import android.util.DisplayMetrics; import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import androidx.annotation.NonNull; @@ -31,7 +38,9 @@ import com.gh.common.util.LogUtils; import com.gh.common.util.LoginHelper; import com.gh.common.util.LoginUtils; import com.gh.common.util.MtaHelper; +import com.gh.common.util.NetworkUtils; import com.gh.common.util.PatternUtils; +import com.gh.common.util.QuickLoginHelper; import com.gh.common.util.SPUtils; import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.R; @@ -46,7 +55,7 @@ import com.gh.gamecenter.user.ApiResponse; import com.gh.gamecenter.user.LoginTag; import com.gh.gamecenter.user.UserViewModel; import com.halo.assistant.HaloApp; -import com.lightgame.utils.Utils; +import com.lightgame.view.CheckableImageView; import org.greenrobot.eventbus.EventBus; import org.jetbrains.annotations.NotNull; @@ -80,6 +89,14 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList View mLoginInviteContainer; @BindView(R.id.login_invite_et) EditText mLoginInviteEt; + @BindView(R.id.login_phone_container) + RelativeLayout mLoginPhoneContainer; + @BindView(R.id.policyContainer) + LinearLayout mPolicyContainer; + @BindView(R.id.checkIv) + CheckableImageView mCheckIv; + @BindView(R.id.quickLoginTv) + TextView mQuickLoginTv; private WaitingDialogFragment mLoginDialog; @@ -87,6 +104,9 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList private String mServiceId; + private int screenHeight; + private Animation mShakeAnim; + @Override protected void handleMessage(Message msg) { if (msg.what == 0) { // 验证码倒计时 @@ -139,10 +159,31 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList mLoginInviteContainer.setVisibility(View.GONE); } + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLoginPhoneContainer.getLayoutParams(); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + screenHeight = getResources().getDisplayMetrics().heightPixels; + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + DisplayMetrics metrics = new DisplayMetrics(); + requireActivity().getDisplay().getRealMetrics(metrics); + screenHeight = metrics.heightPixels; + } else { + DisplayMetrics metrics = new DisplayMetrics(); + requireActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics); + screenHeight = metrics.heightPixels; + } + params.topMargin = screenHeight * 160 / 640; + mLoginPhoneContainer.setLayoutParams(params); + + if (NetworkUtils.isOpenMobileData(requireContext())) { + mQuickLoginTv.setVisibility(View.VISIBLE); + } else { + mQuickLoginTv.setVisibility(View.GONE); + } + mLoginPassEt.addTextChangedListener(new LoginTextWatcher(mLoginPassEt)); mLoginPhoneEt.addTextChangedListener(new LoginTextWatcher(mLoginPhoneEt)); - SpannableStringBuilder privacyContent = new SpannableStringBuilder("登录即代表你已阅读并同意《用户协议》和《隐私政策》"); + SpannableStringBuilder privacyContent = new SpannableStringBuilder("阅读并同意《用户协议》和《隐私政策》"); privacyContent.setSpan(new ClickableSpan() { @Override @@ -181,10 +222,20 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList } @OnClick({R.id.login_captcha, R.id.login_phone_btn, R.id.login_qq_btn, R.id.login_weibo_btn, - R.id.login_wechat_btn, R.id.login_douyin_btn, R.id.login_close_btn}) + R.id.login_wechat_btn, R.id.login_close_btn, R.id.checkIv, R.id.quickLoginTv}) public void onClick(View v) { super.onClick(v); switch (v.getId()) { + case R.id.quickLoginTv: + if (NetworkUtils.isOpenMobileData(requireContext())) { + QuickLoginHelper.startLogin(requireContext(), "验证码登录"); + } else { + toast("请先打开手机流量"); + } + break; + case R.id.checkIv: + mCheckIv.setChecked(!mCheckIv.isChecked()); + break; case R.id.login_captcha: MtaHelper.onEvent("我的光环_新", "登录页面", "获取验证码"); final String phoneNum = mLoginPhoneEt.getText().toString().trim().replaceAll(" ", ""); @@ -201,23 +252,22 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList loginByMobile(); break; case R.id.login_qq_btn: - if (!ClickUtils.isFastDoubleClick()) { + if (!ClickUtils.isFastDoubleClick() && isAgreePolicy()) { MtaHelper.onEvent("我的光环_新", "登录页面", "QQ登录"); LoginHelper.loginWithQQ(this, requireActivity()); } break; case R.id.login_weibo_btn: - MtaHelper.onEvent("我的光环_新", "登录页面", "微博登录"); - LoginHelper.loginWithWeibo(this, requireActivity()); + if (isAgreePolicy()) { + MtaHelper.onEvent("我的光环_新", "登录页面", "微博登录"); + LoginHelper.loginWithWeibo(this, requireActivity()); + } break; case R.id.login_wechat_btn: - MtaHelper.onEvent("我的光环_新", "登录页面", "微信登录"); - LoginHelper.loginWithWechat(this); - break; - case R.id.login_douyin_btn: - MtaHelper.onEvent("我的光环_新", "登录页面", "抖音登录"); - Utils.toast(requireContext(), "抖音登录临时维护中"); - LoginHelper.loginWithDouYin(this, requireActivity()); + if (isAgreePolicy()) { + MtaHelper.onEvent("我的光环_新", "登录页面", "微信登录"); + LoginHelper.loginWithWechat(this); + } break; case R.id.login_close_btn: requireActivity().finish(); @@ -225,6 +275,19 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList } } + private boolean isAgreePolicy() { + if (mCheckIv.isChecked()) { + return true; + } else { + toast("请先勾选同意《用户协议》《隐私政策》"); + if (mShakeAnim == null) { + mShakeAnim = AnimationUtils.loadAnimation(requireContext(), R.anim.login_policy_shake); + } + mPolicyContainer.startAnimation(mShakeAnim); + return false; + } + } + // 登录 private void loginByMobile() { String code = mLoginPassEt.getText().toString().trim(); @@ -233,6 +296,8 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList if (TextUtils.isEmpty(phoneNum)) { toast("手机号码不能为空"); return; + } else if (!isAgreePolicy()) { + return; } else if (TextUtils.isEmpty(code)) { toast("验证码不能为空"); return; @@ -308,41 +373,10 @@ LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackList LogUtils.login("success", "mobile", mEntrance); } - // 相同设备号,每一种第三方登录方式登录后跳转绑定手机页面,两次后则不在弹出(https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/949) + // 第三方登录方式登录后跳转绑定手机页面(https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1206) if (UserManager.getInstance().getUserInfoEntity() != null && TextUtils.isEmpty(UserManager.getInstance().getUserInfoEntity().getLoginMobile())) { - int time; - if (LoginTag.qq.name().equals(loginType)) { - time = SPUtils.getInt(Constants.SP_QQ_SHOW_BIND_PHONE_TIME); - if (time < 2) { - SPUtils.setInt(Constants.SP_QQ_SHOW_BIND_PHONE_TIME, ++time); - startActivity(BindPhoneActivity.getLoginSuccessIntent(requireContext())); - } - } - - if (LoginTag.wechat.name().equals(loginType)) { - time = SPUtils.getInt(Constants.SP_WECHAT_SHOW_BIND_PHONE_TIME); - if (time < 2) { - SPUtils.setInt(Constants.SP_WECHAT_SHOW_BIND_PHONE_TIME, ++time); - startActivity(BindPhoneActivity.getLoginSuccessIntent(requireContext())); - } - } - - if (LoginTag.weibo.name().equals(loginType)) { - time = SPUtils.getInt(Constants.SP_WEIBO_SHOW_BIND_PHONE_TIME); - if (time < 2) { - SPUtils.setInt(Constants.SP_WEIBO_SHOW_BIND_PHONE_TIME, ++time); - startActivity(BindPhoneActivity.getLoginSuccessIntent(requireContext())); - } - } - - if (LoginTag.douyin.name().equals(loginType)) { - time = SPUtils.getInt(Constants.SP_DOUYIN_SHOW_BIND_PHONE_TIME); - if (time < 2) { - SPUtils.setInt(Constants.SP_DOUYIN_SHOW_BIND_PHONE_TIME, ++time); - startActivity(BindPhoneActivity.getLoginSuccessIntent(requireContext())); - } - } + startActivity(BindPhoneActivity.getLoginSuccessIntent(requireContext())); } } // 防止UserManager数据丢失后重复登录 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 f48f518907..25b9621126 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 @@ -1119,6 +1119,13 @@ public interface ApiService { @POST("login/douyin") Observable loginByDouYin(@Body RequestBody body); + /** + * 一键登录 + */ + @Headers({"Content-Type: application/json", "Accept: application/json"}) + @POST("login/mobile_oauth") + Observable loginByOauth(@Body RequestBody body); + /** * 刷新accessToken */ diff --git a/app/src/main/java/com/gh/gamecenter/security/BindPhoneFragment.kt b/app/src/main/java/com/gh/gamecenter/security/BindPhoneFragment.kt index badc8a13dc..3479dbb944 100644 --- a/app/src/main/java/com/gh/gamecenter/security/BindPhoneFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/security/BindPhoneFragment.kt @@ -213,8 +213,7 @@ class BindPhoneFragment : NormalFragment() { when (v.id) { R.id.bind_phone_skip -> { - DialogUtils.showNoticeDialog(requireContext(), getString(R.string.bind_phone_title1), - getString(R.string.bind_phone_notice)) { requireActivity().finish() } + DialogUtils.showBindPhoneDialog(requireContext()) { requireActivity().finish() } } R.id.bind_phone_captcha -> { diff --git a/app/src/main/java/com/gh/gamecenter/user/LoginTag.java b/app/src/main/java/com/gh/gamecenter/user/LoginTag.java index b6646b55d9..df5cfec861 100644 --- a/app/src/main/java/com/gh/gamecenter/user/LoginTag.java +++ b/app/src/main/java/com/gh/gamecenter/user/LoginTag.java @@ -10,6 +10,7 @@ public enum LoginTag { wechat("wechat"), weibo("weibo"), douyin("douyin"), + oauth("oauth"), phone("phone"), refresh("refresh"), oldUserPhone("oldUserPhone"); 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 d327d06bc2..ee3edc9947 100644 --- a/app/src/main/java/com/gh/gamecenter/user/UserRepository.java +++ b/app/src/main/java/com/gh/gamecenter/user/UserRepository.java @@ -13,6 +13,7 @@ import com.gh.common.PushManager; import com.gh.common.constant.Constants; import com.gh.common.exposure.meta.MetaUtil; import com.gh.common.repository.ReservationRepository; +import com.gh.common.util.BiCallback; import com.gh.common.util.DataUtils; import com.gh.common.util.DeviceUtils; import com.gh.common.util.ErrorHelper; @@ -162,9 +163,12 @@ public class UserRepository { return mLoginObsResponseUserInfo; } + public void login(final JSONObject content, final LoginTag loginTag) { + login(content, loginTag, null); + } // 登录前,做好body判断 - public void login(final JSONObject content, final LoginTag loginTag) { + public void login(final JSONObject content, final LoginTag loginTag, BiCallback> callback) { Observable observable = null; String userToken = null; @@ -195,6 +199,10 @@ public class UserRepository { loginTypeForHumanEyes = "手机"; userToken = content.getString("mobile"); observable = mApiService.loginByMobile(body); + } else if (loginTag == LoginTag.oauth) { + loginTypeForHumanEyes = "一键登录"; + userToken = content.getString("token"); + observable = mApiService.loginByOauth(body); } else { return; } @@ -231,6 +239,10 @@ public class UserRepository { PushManager.getAndSetAlias(); GameSubstituteRepositoryHelper.updateSubstitutableGames(); + + if (callback != null) { + callback.onFirst(response); + } } @Override @@ -286,6 +298,10 @@ public class UserRepository { } catch (Exception e1) { e1.printStackTrace(); } + + if (callback != null) { + callback.onSecond(e); + } } }); } diff --git a/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.java b/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.java index 57ffc3e3b9..0410ff3bfe 100644 --- a/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.java +++ b/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.java @@ -293,6 +293,9 @@ public class SettingsFragment extends NormalFragment { case "douyin": loginType = "抖音"; break; + case "oauth": + loginType = "一键登录"; + break; default: if (loginType.length() == 11) { String sub1 = loginType.substring(0, 3); diff --git a/app/src/main/res/anim/cycle_interpolator.xml b/app/src/main/res/anim/cycle_interpolator.xml new file mode 100644 index 0000000000..291e39927e --- /dev/null +++ b/app/src/main/res/anim/cycle_interpolator.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/login_policy_shake.xml b/app/src/main/res/anim/login_policy_shake.xml new file mode 100644 index 0000000000..5810c8c588 --- /dev/null +++ b/app/src/main/res/anim/login_policy_shake.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/bg_login.webp b/app/src/main/res/drawable-xxhdpi/bg_login.webp new file mode 100644 index 0000000000..bbbfd847eb Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_login.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/bg_quick_login_dialog.webp b/app/src/main/res/drawable-xxhdpi/bg_quick_login_dialog.webp new file mode 100644 index 0000000000..8a663f076f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_quick_login_dialog.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_bind_phone_dialog_close.webp b/app/src/main/res/drawable-xxhdpi/ic_bind_phone_dialog_close.webp new file mode 100644 index 0000000000..d38d3ffdd3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_bind_phone_dialog_close.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_bind_phone_dialog_next.webp b/app/src/main/res/drawable-xxhdpi/ic_bind_phone_dialog_next.webp new file mode 100644 index 0000000000..64c6889ad7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_bind_phone_dialog_next.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_change_login.webp b/app/src/main/res/drawable-xxhdpi/ic_change_login.webp new file mode 100644 index 0000000000..9fec031b30 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_change_login.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_login_close.webp b/app/src/main/res/drawable-xxhdpi/ic_login_close.webp new file mode 100644 index 0000000000..d38d3ffdd3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_login_close.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_login_qq.webp b/app/src/main/res/drawable-xxhdpi/ic_login_qq.webp new file mode 100644 index 0000000000..7ef07fcf8f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_login_qq.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_login_wechat.webp b/app/src/main/res/drawable-xxhdpi/ic_login_wechat.webp new file mode 100644 index 0000000000..8ec3108108 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_login_wechat.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_login_weibo.webp b/app/src/main/res/drawable-xxhdpi/ic_login_weibo.webp new file mode 100644 index 0000000000..1ddcadf950 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_login_weibo.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_quick_login_check.webp b/app/src/main/res/drawable-xxhdpi/ic_quick_login_check.webp new file mode 100644 index 0000000000..9b66280e1e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_quick_login_check.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_quick_login_close.webp b/app/src/main/res/drawable-xxhdpi/ic_quick_login_close.webp new file mode 100644 index 0000000000..d38d3ffdd3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_quick_login_close.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_quick_login_uncheck.webp b/app/src/main/res/drawable-xxhdpi/ic_quick_login_uncheck.webp new file mode 100644 index 0000000000..7bbd2dc7e0 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_quick_login_uncheck.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/login_bg.webp b/app/src/main/res/drawable-xxhdpi/login_bg.webp deleted file mode 100644 index 736eb8c155..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/login_bg.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/login_close_icon.png b/app/src/main/res/drawable-xxhdpi/login_close_icon.png deleted file mode 100644 index 2a6b26cc98..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/login_close_icon.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/login_douyin_icon.webp b/app/src/main/res/drawable-xxhdpi/login_douyin_icon.webp deleted file mode 100644 index 27e3490cb5..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/login_douyin_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/login_qq_icon.webp b/app/src/main/res/drawable-xxhdpi/login_qq_icon.webp deleted file mode 100644 index a6a41e87ac..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/login_qq_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/login_wechat_icon.webp b/app/src/main/res/drawable-xxhdpi/login_wechat_icon.webp deleted file mode 100644 index 5f1e7306bd..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/login_wechat_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/login_weibo_icon.webp b/app/src/main/res/drawable-xxhdpi/login_weibo_icon.webp deleted file mode 100644 index 8fce0e426c..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/login_weibo_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/pic_bind_phone_dialog_guide.webp b/app/src/main/res/drawable-xxhdpi/pic_bind_phone_dialog_guide.webp new file mode 100644 index 0000000000..9f594f6179 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/pic_bind_phone_dialog_guide.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/login_bg.webp b/app/src/main/res/drawable-xxxhdpi/login_bg.webp deleted file mode 100644 index 261ae1049f..0000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/login_bg.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/login_close_icon.png b/app/src/main/res/drawable-xxxhdpi/login_close_icon.png deleted file mode 100644 index 7ccaf08de0..0000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/login_close_icon.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/login_douyin_icon.webp b/app/src/main/res/drawable-xxxhdpi/login_douyin_icon.webp deleted file mode 100644 index 1cc8faf49a..0000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/login_douyin_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/login_qq_icon.webp b/app/src/main/res/drawable-xxxhdpi/login_qq_icon.webp deleted file mode 100644 index b9b636f9a7..0000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/login_qq_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/login_wechat_icon.webp b/app/src/main/res/drawable-xxxhdpi/login_wechat_icon.webp deleted file mode 100644 index e202638ace..0000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/login_wechat_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/login_weibo_icon.webp b/app/src/main/res/drawable-xxxhdpi/login_weibo_icon.webp deleted file mode 100644 index aa6d68f39e..0000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/login_weibo_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable/bg_shape_white_radius_8.xml b/app/src/main/res/drawable/bg_shape_white_radius_8.xml new file mode 100644 index 0000000000..e3d1bdb280 --- /dev/null +++ b/app/src/main/res/drawable/bg_shape_white_radius_8.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_ic_login_checkbox.xml b/app/src/main/res/drawable/selector_ic_login_checkbox.xml new file mode 100644 index 0000000000..3e6fed39b1 --- /dev/null +++ b/app/src/main/res/drawable/selector_ic_login_checkbox.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_bind_phone.xml b/app/src/main/res/layout/dialog_bind_phone.xml new file mode 100644 index 0000000000..8744d0712f --- /dev/null +++ b/app/src/main/res/layout/dialog_bind_phone.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_quick_login.xml b/app/src/main/res/layout/dialog_quick_login.xml new file mode 100644 index 0000000000..d1c9ae45e1 --- /dev/null +++ b/app/src/main/res/layout/dialog_quick_login.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index dab11bd2a7..d18bc66973 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -18,22 +18,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" - android:src="@drawable/login_bg" /> - - + android:src="@drawable/bg_login" /> @@ -133,24 +124,13 @@ - - + + + android:orientation="vertical"> - + android:layout_marginTop="16dp" + android:orientation="horizontal"> - + + + + + + + + android:layout_marginTop="32dp" + android:gravity="center" + android:orientation="horizontal"> - + - + + + + + android:layout_marginLeft="2dp" + android:src="@drawable/ic_login_close"/> \ No newline at end of file diff --git a/app/src/main/res/layout/layout_quick_login_navigation.xml b/app/src/main/res/layout/layout_quick_login_navigation.xml new file mode 100644 index 0000000000..4844cc384c --- /dev/null +++ b/app/src/main/res/layout/layout_quick_login_navigation.xml @@ -0,0 +1,17 @@ + + + + + + \ 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 1b4392730b..aadbd8bdbc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -287,6 +287,7 @@ 输入邀请码(选填) +86 登录 + 一键登录 > QQ 微信 新浪微博 @@ -717,7 +718,6 @@ 绑定手机 绑定手机号 更换手机号 - 登录后你可以在【我的光环--账户安全】\n或【设置-账户安全】中绑定手机号噢~ 绑定手机后手机号将用于光环助手活动奖励领取、安全验证等用途 下一步 完成 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d1f45c7b43..417428d210 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -380,4 +380,10 @@ bold 12sp + + \ No newline at end of file diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000000..2439f15c2c --- /dev/null +++ b/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ + + + + diff --git a/gradle.properties b/gradle.properties index 7387781835..d908b526c5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -44,6 +44,8 @@ LETO_APPID=1001276 TTAD_APPID=5065631 DOUYIN_CLIENTKEY=aw66h51ftb71dkhi DOUYIN_CLIENTSECRET=155dee6c1de9ae31bffcbf32475dc161 +QUICK_LOGIN_APPID=300012035775 +QUICK_LOGIN_APPKEY=002BAABA2C078342DA33BEAB0A4C6A25 # hosts DEV_API_HOST=https\://dev-and-api.ghzs.com/v4d9d0/