package com.gh.gamecenter.fragment; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.os.Message; import android.text.Editable; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; 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; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; import com.gh.base.fragment.WaitingDialogFragment; import com.gh.common.constant.Constants; import com.gh.common.util.CheckLoginUtils; import com.gh.common.util.ClickUtils; import com.gh.common.util.DialogUtils; import com.gh.common.util.EnergyTaskHelper; import com.gh.common.util.EntranceUtils; import com.gh.common.util.ExtensionsKt; 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.PatternUtils; import com.gh.common.util.PermissionHelper; import com.gh.common.util.QuickLoginHelper; import com.gh.common.util.SPUtils; import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.LoginActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.WebActivity; import com.gh.gamecenter.entity.LoginTokenEntity; import com.gh.gamecenter.entity.UserInfoEntity; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.manager.UserManager; import com.gh.gamecenter.normal.NormalFragment; import com.gh.gamecenter.security.BindPhoneActivity; 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.AppManager; import com.lightgame.view.CheckableImageView; import org.greenrobot.eventbus.EventBus; import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; import butterknife.BindView; import butterknife.OnClick; /** * Created by khy on 14/08/17. */ public class LoginFragment extends NormalFragment implements LoginUtils.onCaptchaCallBackListener , LoginHelper.LoginCallback, View.OnClickListener, Observer> { @BindView(R.id.login_phone_et) EditText mLoginPhoneEt; @BindView(R.id.login_pass_et) EditText mLoginPassEt; @BindView(R.id.login_captcha) TextView mLoginCaptcha; @BindView(R.id.login_phone_btn) TextView mLoginBtn; @BindView(R.id.login_privacy_policy) TextView mPrivacyPolicy; @BindView(R.id.login_invite_container) 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; private UserViewModel mUserViewModel; private String mServiceId; private int screenHeight; private Animation mShakeAnim; private int mStatus = LoginActivity.STATUS_DEFAULT; @Override protected void handleMessage(Message msg) { if (msg.what == 0) { // 验证码倒计时 int arg1 = msg.arg1; arg1--; if (arg1 >= 0) { Message message = new Message(); message.what = 0; message.arg1 = arg1; mBaseHandler.sendMessageDelayed(message, 1000); mLoginCaptcha.setText(arg1 + "s"); } else { mLoginCaptcha.setText("重新获取"); mLoginCaptcha.setTextColor(ExtensionsKt.toColor(R.color.theme_font)); // mLoginCaptcha.setBackgroundResource(R.drawable.border_black_bg); mLoginCaptcha.setEnabled(true); } } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == com.tencent.connect.common.Constants.REQUEST_LOGIN) { // QQ Login callback LoginHelper.onQQLoginCallback(requestCode, resultCode, data); } else if (requestCode == 32973) { // WeiBo Login callback LoginHelper.onWeiboLoginCallback(requestCode, resultCode, data); } } @Override protected int getLayoutId() { return R.layout.fragment_login; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mStatus = getArguments().getInt(EntranceUtils.KEY_SHOW_QUICK_LOGIN, LoginActivity.STATUS_DEFAULT); } else { mStatus = LoginActivity.STATUS_DEFAULT; } final UserViewModel.Factory factory = new UserViewModel.Factory(HaloApp.getInstance().getApplication()); mUserViewModel = ViewModelProviders.of(this, factory).get(UserViewModel.class); mUserViewModel.getLoginObsUserinfo().observe(this, this); if (BuildConfig.DEBUG || BuildConfig.BUILD_TIME != 0) { if (SPUtils.getBoolean(Constants.SP_HAS_COMPLETE_INVITE_CODE)) { mLoginInviteContainer.setVisibility(View.GONE); } else { mLoginInviteContainer.setVisibility(View.VISIBLE); } } else { 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 * 80 / 640; mLoginPhoneContainer.setLayoutParams(params); if (mStatus == LoginActivity.STATUS_DEFAULT) { mQuickLoginTv.setVisibility(View.GONE); } else { mQuickLoginTv.setVisibility(View.VISIBLE); } mLoginPassEt.addTextChangedListener(new LoginTextWatcher(mLoginPassEt)); mLoginPhoneEt.addTextChangedListener(new LoginTextWatcher(mLoginPhoneEt)); SpannableStringBuilder privacyContent = new SpannableStringBuilder("阅读并同意《用户协议》和《隐私政策》"); privacyContent.setSpan(new ClickableSpan() { @Override public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setColor(getResources().getColor(R.color.theme_font)); ds.setUnderlineText(false); } @Override public void onClick(@NonNull View widget) { MtaHelper.onEvent("我的光环_新", "登录页面", "隐私政策"); Intent intent = WebActivity.getPrivacyPolicyIntent(getContext()); startActivity(intent); } }, privacyContent.length() - 6, privacyContent.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); privacyContent.setSpan(new ClickableSpan() { @Override public void updateDrawState(@NonNull TextPaint ds) { super.updateDrawState(ds); ds.setColor(getResources().getColor(R.color.theme_font)); ds.setUnderlineText(false); } @Override public void onClick(@NonNull View widget) { MtaHelper.onEvent("我的光环_新", "登录页面", "用户协议"); startActivity(WebActivity.getUserRegulationWebIntent(getContext())); } }, privacyContent.length() - 13, privacyContent.length() - 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); mPrivacyPolicy.setText(privacyContent); mPrivacyPolicy.setMovementMethod(new LinkMovementMethod()); } @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_close_btn, R.id.checkIv, R.id.checkClickView1, R.id.checkClickView2, R.id.quickLoginTv}) public void onClick(View v) { super.onClick(v); switch (v.getId()) { case R.id.quickLoginTv: if (mStatus == LoginActivity.STATUS_FROM_QUICK_LOGIN_PAGE) { requireActivity().finish(); } else if (mStatus == LoginActivity.STATUS_FROM_QUICK_LOGIN_PERMISSION) { showPermissionDialog(); } break; case R.id.checkIv: case R.id.checkClickView1: case R.id.checkClickView2: updatePolicyCheckedStatus(); break; case R.id.login_captcha: MtaHelper.onEvent("我的光环_新", "登录页面", "获取验证码"); final String phoneNum = mLoginPhoneEt.getText().toString().trim().replaceAll(" ", ""); if (PatternUtils.isPhoneNum(phoneNum) && phoneNum.length() == 11) { if (isAgreePolicy()) { mLoginCaptcha.setEnabled(false); ExtensionsKt.showKeyBoard(mLoginPassEt); LoginUtils.getPhoneCaptcha(getContext(), phoneNum, LoginFragment.this); } } else { toast("请输入正确的手机号"); } break; case R.id.login_phone_btn: MtaHelper.onEvent("我的光环_新", "登录页面", "点击登录"); loginByMobile(); break; case R.id.login_qq_btn: if (!ClickUtils.isFastDoubleClick() && isAgreePolicy()) { MtaHelper.onEvent("我的光环_新", "登录页面", "QQ登录"); LoginHelper.loginWithQQ(this, requireActivity()); } break; case R.id.login_weibo_btn: if (isAgreePolicy()) { MtaHelper.onEvent("我的光环_新", "登录页面", "微博登录"); LoginHelper.loginWithWeibo(this, requireActivity()); } break; case R.id.login_wechat_btn: if (isAgreePolicy()) { MtaHelper.onEvent("我的光环_新", "登录页面", "微信登录"); LoginHelper.loginWithWechat(this); } break; case R.id.login_close_btn: requireActivity().finish(); break; } } private void showPermissionDialog() { if (requireContext().checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { startQuickLogin(); } else { DialogUtils.showQuickLoginPermissionDialog( requireContext(), () -> PermissionHelper.checkReadPhoneStatePermissionBeforeAction(requireContext(), this::startQuickLogin), () -> { } ); } } private void startQuickLogin() { requireActivity().finish(); Activity currentActivity = AppManager.getInstance().getRecentActiveActivity(); if (currentActivity != null) { QuickLoginHelper.startLogin(currentActivity, "一键登录权限弹窗"); } } 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(); String phoneNum = mLoginPhoneEt.getText().toString().trim().replaceAll(" ", ""); if (TextUtils.isEmpty(phoneNum)) { toast("手机号码不能为空"); return; } else if (!isAgreePolicy()) { return; } else if (TextUtils.isEmpty(code)) { toast("验证码不能为空"); return; } else if (TextUtils.isEmpty(mServiceId)) { toast("验证码错误,请重新获取"); return; } Map params = new HashMap<>(); params.put("mobile", phoneNum); params.put("code", code); params.put("service_id", mServiceId); String inviteCode = mLoginInviteEt.getText().toString().trim().replaceAll(" ", ""); if (!TextUtils.isEmpty(inviteCode)) { params.put("invite_code", inviteCode); } login(new JSONObject(params), LoginTag.phone); } @Override public void onCaptcha(String serviceId) { if (!TextUtils.isEmpty(serviceId)) { mServiceId = serviceId; // 启动验证码倒计时 Message message = new Message(); message.what = 0; message.arg1 = 60; // 倒数时间 mBaseHandler.sendMessage(message); mLoginCaptcha.setTextColor(ExtensionsKt.toColor(R.color.hint)); // mLoginCaptcha.setBackgroundResource(R.drawable.border_captcha_bg); mLoginCaptcha.setEnabled(false); } else { mLoginCaptcha.setEnabled(true); } } @Override public void onLoginSuccess(@NotNull LoginTag loginType, @NotNull JSONObject jsonContent) { login(jsonContent, loginType); } @Override public void onLoginFailure(@NotNull LoginTag loginType, @NotNull String error) { toast(error); } @Override public void onChanged(@Nullable ApiResponse response) { if (mLoginDialog != null) { mLoginDialog.dismissAllowingStateLoss(); mLoginDialog = null; } if (response != null && response.getData() != null) { LoginTokenEntity loginTokenEntity = UserManager.getInstance().getLoginTokenEntity(); if (loginTokenEntity != null) { // 已完成填写邀请码 String inviteCode = mLoginInviteEt.getText().toString().trim().replaceAll(" ", ""); if (!TextUtils.isEmpty(inviteCode)) { SPUtils.setBoolean(Constants.SP_HAS_COMPLETE_INVITE_CODE, true); EnergyTaskHelper.postInviteCodeTask(inviteCode, "mobile_login", null); } String loginType = loginTokenEntity.getLoginType(); if (LoginTag.qq.name().equals(loginType) || LoginTag.wechat.name().equals(loginType) || LoginTag.weibo.name().equals(loginType) || LoginTag.douyin.name().equals(loginType) || LoginTag.oauth.name().equals(loginType)) { LogUtils.login("success", loginType, mEntrance); } else { LogUtils.login("success", "mobile", mEntrance); } // 第三方登录方式登录后跳转绑定手机页面(https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1206) if (UserManager.getInstance().getUserInfoEntity() != null && TextUtils.isEmpty(UserManager.getInstance().getUserInfoEntity().getLoginMobile())) { startActivity(BindPhoneActivity.getLoginSuccessIntent(requireContext())); } } // 防止UserManager数据丢失后重复登录 if (TextUtils.isEmpty(UserManager.getInstance().getToken())) { mUserViewModel.retryCheckLogin(); } /*Object videoLinkEntity = HaloApp.get(HOST_UPLOAD_VIDEO, true); if (videoLinkEntity instanceof VideoLinkEntity) { startActivity(VideoManagerActivity.getIntent( requireContext(), (VideoLinkEntity) videoLinkEntity, EntranceUtils.ENTRANCE_BROWSER, "")); }*/ if (getActivity() != null && CheckLoginUtils.isLogin()) { getActivity().finish(); // 如果是从一键登录页跳转过来的,登录成功后也要finish一键登录页 if (mStatus == LoginActivity.STATUS_FROM_QUICK_LOGIN_PAGE) { QuickLoginHelper.finishAuthActivity(); } } } } @Override public void onDestroyView() { super.onDestroyView(); mBaseHandler.removeCallbacksAndMessages(null); if (!UserManager.getInstance().isLoggedIn()) { EventBus.getDefault().post(new EBReuse(Constants.EB_QUIT_LOGIN)); } } private void login(JSONObject content, LoginTag loginTag) { if (loginTag.equals(LoginTag.phone)) { LogUtils.login("logging", "mobile", mEntrance); } else { LogUtils.login("logging", loginTag.name(), mEntrance); } if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { mLoginDialog = WaitingDialogFragment.newInstance(getString(R.string.logging)); mLoginDialog.show(getChildFragmentManager(), null); } mUserViewModel.login(content, loginTag); } private class LoginTextWatcher implements TextWatcher { private EditText mEditText; public LoginTextWatcher(EditText e) { mEditText = e; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { int tvCount = s.length(); if (mEditText == mLoginPhoneEt) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < s.length(); i++) { if (i != 3 && i != 8 && s.charAt(i) == ' ') { continue; } else { stringBuilder.append(s.charAt(i)); if ((stringBuilder.length() == 4 || stringBuilder.length() == 9) && stringBuilder.charAt(stringBuilder.length() - 1) != ' ') { stringBuilder.insert(stringBuilder.length() - 1, ' '); } } } if (!stringBuilder.toString().equals(s.toString())) { mLoginPhoneEt.setText(stringBuilder.toString()); mLoginPhoneEt.setSelection(mLoginPhoneEt.getText().toString().length()); } } if (mEditText == mLoginPassEt) { if (tvCount > 5) { mLoginBtn.setEnabled(true); mLoginBtn.setAlpha(1f); } else { mLoginBtn.setEnabled(false); mLoginBtn.setAlpha(0.4f); } } } @Override public void afterTextChanged(Editable s) { } } private void updatePolicyCheckedStatus() { mCheckIv.setChecked(!mCheckIv.isChecked()); if (mCheckIv.isChecked()) { mLoginCaptcha.setTextColor(ContextCompat.getColor(requireContext(), R.color.theme_font)); } else { mLoginCaptcha.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_999999)); } } }