项目中的一键登录整理
-
效果图
-
极光一键登录
-
运行提供 demo,手动导入一些 jar
-
加入了一些混淆
-
-dontoptimize -dontpreverify -dontwarn cn.jpush.** -keep class cn.jpush.** { ; } -dontwarn cn.jiguang.* -keep class cn.jiguang.** { ; } -dontwarn com.cmic.* -keep class com.cmic.** { ; } -dontwarn com.unicom.* -keep class com.unicom.** { ; } -dontwarn cn.com.chinatelecom.* -keep class cn.com.chinatelecom.** { *; } -
思路
- 点击按钮登录时,用一个 透明 的 SignActivity 来 承载 极光创建的 CtLoginActivity,并手动的关闭 CtLoginActivity
- 有一些比如在文章详情页登录,登录后还需显示原来界面,可通过在application中设置一些字段,用于判断是否需要在执行MainActivity后,继续跳转
-
代码如下
<!-- 设置主题为透明 xml中不能和portrait 混用,Android 8.0 会出现问题 -->
<activity
android:name=".activity.login_onekey.SignActivityV1"
android:launchMode="singleTask"
android:theme="@style/loginTheme"
/>
<!-- 一键登录主题 -->
<style name="loginTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
public class SignActivityV1 extends NormalActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
//设置坚屏 一定要放到try catch里面,否则会崩溃
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} catch (Exception e) {
}
//检查 当前网络环境不支持认证,不支持去验证码登录
if(!checkYiJianLogin()){
finish();
SignActivity.startLogin(this, SignActivity.LOGIN);
return;
}
//因为有很多细节的地方一键登录,在这里面做了快速点击判断
if (DoubleClickUtils.isFastDoubleClick()) {
return;
}
if (this != null) {
//显示加载Dialog
showProgressDialogByZL();
//设置一键授权的展示样式
setUIConfig(this);
//获取号码认证的token
JVerificationInterface.getToken(this, 5000, new VerifyListener() {
@Override
public void onResult(int code, String content, String operator) {
//2008 正在获取token中,稍后再试
Log.e("tag", "code= " + code + " token=" + content + ", operator=" + operator);
if (code == FETCH_TOKEN_SUCCESS) {
toGetYuYueCode(SignActivityV1.this);
} else {
//关闭Dialog
hideProgressDialogByZL();
finish();
SignActivity.startLogin(SignActivityV1.this, SignActivity.LOGIN);
}
}
});
}
}
private void toGetYuYueCode(NormalActivity activity) {
JVerificationInterface.preLogin(activity, 3000, (code, content) -> {
hideProgressDialogByZL();
//7000 表示成功
Log.e("tag", "[" + code + "] message=" + content);
if (code == 7000) {
toYiJian(activity);
} else {
JVerificationInterface.clearPreLoginCache();
finish();
SignActivity.startLogin(activity, SignActivity.LOGIN);
}
});
}
private void toYiJian(NormalActivity activity) {
//这个回调是监听状态的,取消会到这里6002 ,成功也会到这里 6000 失败也会到这里 4005
//false 表示不自动关闭
JVerificationInterface.loginAuth(activity, false, (code, token, operator) -> {
Log.e("tag", "onResult: code=" + code + ",token=" + token + ",operator=" + operator);
activity.runOnUiThread(() -> {
if (code == CODE_LOGIN_SUCCESS) {
yijianLogin(activity, token);
Log.e("tag", "onResult: loginSuccess 请求成功后 并把承载的Activity销毁掉" + token);
} else if (code == CODE_LOGIN_CANCELD) {
Log.e("tag", "onResult: loginError 取消 并把承载的Activity销毁掉");
finish();
} else if (code == CODE_LOGIN_FAILED) {
Log.e("tag", "onResult: loginError 失败 并把承载的Activity销毁掉");
finish();
SignActivity.startLogin(activity, SignActivity.LOGIN);
}
});
}, new AuthPageEventListener() {
@Override
public void onEvent(int cmd, String msg) {
Log.e("tag", "[onEvent]. [" + cmd + "]message=" + msg);
//2.2.4版本新增了这个,为什么尼,因为关闭了自动销毁,需手动销毁
if (1 == cmd) {
finish();
} else if (6 == cmd) {
//协议栏checkbox变为选中事件
}
}
});
}
//一键登录的逻辑
private void yijianLogin(Activity activity, String token) {
....
//项目中是保持一些数据,然后跳转 MainActvity
Intent intent1 = new Intent(SignActivityV1.this, MainActivity.class);
startActivity(intent1);
//有一些比如在文章详情页登录,登录后还需显示这界面
...通过在application中设置一些字段,用于判断是否需要在执行MainActivity后,继续跳转...
}
}
private static boolean checkYiJianLogin() {
boolean verityEnable = JVerificationInterface.checkVerifyEnable(MindApplication.getInstance());
if(!verityEnable){
Log.e("tag","[2016],msg = 当前网络环境不支持认证");
return false;
}
return true;
}
private void setUIConfig(Activity activity) {
JVerifyUIConfig portrait = getFullScreenPortraitConfig(activity);
JVerifyUIConfig landscape = null;
//支持授权页设置横竖屏两套config,在授权页中触发横竖屏切换时,sdk自动选择对应的config加载。
JVerificationInterface.setCustomUIWithConfig(portrait, landscape);
}
private JVerifyUIConfig getFullScreenPortraitConfig(Activity activity) {
//隐私 + 用户 路径
String user_url = Url.webViewUrl + WebDetailActivity.USER_DISPLINE;
String yinsi_url = Url.webViewUrl + WebDetailActivity.SECURITY_DISPLINE;
JVerifyUIConfig.BuilderuiConfigBuilder = new JVerifyUIConfig.Builder();
uiConfigBuilder.setStatusBarColorWithNav(true);
uiConfigBuilder.setStatusBarDarkMode(true);
uiConfigBuilder.setStatusBarTransparent(true);
uiConfigBuilder.setSloganTextColor(0xFFA6A9B6);
uiConfigBuilder.setSloganTextSize(12);
uiConfigBuilder.setSloganOffsetY(208);
uiConfigBuilder.setLogoOffsetY(60);
uiConfigBuilder.setNumFieldOffsetY(168);
uiConfigBuilder.setNumberTextBold(true);
uiConfigBuilder.setNumberSize(28);
uiConfigBuilder.setPrivacyState(true);
uiConfigBuilder.setLogoImgPath("icon_login_1");
uiConfigBuilder.setNavTransparent(true);
uiConfigBuilder.setNavReturnImgPath("btn_back1");
uiConfigBuilder.setCheckedImgPath(null);
uiConfigBuilder.setNumberColor(0xFF222328);
uiConfigBuilder.setLogBtnImgPath("selector_btn_normal");
uiConfigBuilder.setLogBtnTextColor(0xFFFFFFFF);
uiConfigBuilder.setLogBtnTextSize(16);
uiConfigBuilder.setLogBtnText("本机号码一键登录");
uiConfigBuilder.setLogBtnOffsetY(288);
uiConfigBuilder.setLogBtnWidth(320);
uiConfigBuilder.setLogBtnHeight(45);
//第二个是协议的颜色
uiConfigBuilder.setAppPrivacyColor(0xFFA6A9B6, 0xFFFFA42F);
uiConfigBuilder.setPrivacyText("我已阅读并同意 ", " 和扑克财经 ", " 与 ", " ");
uiConfigBuilder.setAppPrivacyOne("用户协议", user_url);
uiConfigBuilder.setAppPrivacyTwo("隐私政策", yinsi_url);
uiConfigBuilder.setUncheckedImgPath("agree1");
uiConfigBuilder.setCheckedImgPath("agreed_1");
uiConfigBuilder.setPrivacyCheckboxSize(15);
uiConfigBuilder.setPrivacyCheckboxInCenter(false);
uiConfigBuilder.setPrivacyCheckboxHidden(true);
uiConfigBuilder.setPrivacyTextCenterGravity(true);
uiConfigBuilder.setPrivacyOffsetX(85);
uiConfigBuilder.setPrivacyTextSize(12);
// 一般提示语
RelativeLayout.LayoutParams layoutParam1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParam1.setMargins(0, dp2Pix(activity, 264.0f), 0, 0);
layoutParam1.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
layoutParam1.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
TextView tv1 = new TextView(activity);
tv1.setText("未注册的手机号验证后自动注册并登录");
tv1.setTextSize(12);
tv1.setTextColor(activity.getResources().getColor(R.color._a6a9b6));
tv1.setLayoutParams(layoutParam1);
uiConfigBuilder.addCustomView(tv1, false, new JVerifyUIClickCallback() {
@Override
public void onClicked(Context context, View view) {
}
});
// 手机登录按钮
RelativeLayout.LayoutParams layoutParamPhoneLogin = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParamPhoneLogin.setMargins(0, dp2Pix(activity, 352.0f), 0, 0);
layoutParamPhoneLogin.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
layoutParamPhoneLogin.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
TextView tvPhoneLogin = new TextView(activity);
tvPhoneLogin.setText("其他号码登录");
tvPhoneLogin.setTextSize(14);
tvPhoneLogin.setTextColor(activity.getResources().getColor(R.color.black_33));
tvPhoneLogin.setLayoutParams(layoutParamPhoneLogin);
uiConfigBuilder.addCustomView(tvPhoneLogin, false, new JVerifyUIClickCallback() {
@Override
public void onClicked(Context context, View view) {
if (DoubleClickUtils.isFastDoubleClick()) {
return;
}
JVerificationInterface.dismissLoginAuthActivity();
SignActivity.startLogin(activity, SignActivity.LOGIN);
}
});
int screenHeight = ScreenUtils.getScreenHeight();
int dy = screenHeight - dp2Pix(this, 92);
// 微信登录
LinearLayout layoutLoginGroup = new LinearLayout(activity);
RelativeLayout.LayoutParams layoutLoginGroupParam = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutLoginGroupParam.setMargins(0, 0, 0, dp2Pix(activity, 92.0f));
layoutLoginGroupParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
layoutLoginGroupParam.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
layoutLoginGroupParam.setLayoutDirection(LinearLayout.HORIZONTAL);
layoutLoginGroup.setLayoutParams(layoutLoginGroupParam);
ImageView btnWechat = new ImageView(activity);
btnWechat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (DoubleClickUtils.isFastDoubleClick()) {
return;
}
if (!uiConfigBuilder.build().privacyState()) {
ToastUtils.showShort("请先同意用户协议和隐私政策");
return;
}
//微信的一些操作 -- 成功后销毁Activity
bindSDK(SHARE_MEDIA.WEIXIN);
}
});
btnWechat.setImageResource(R.drawable.icon_login_wx);
LinearLayout.LayoutParams btnParam = new LinearLayout.LayoutParams(dp2Pix(activity, 45.0f), dp2Pix(activity, 45.0f));
btnParam.setMargins(25, 0, 25, 0);
layoutLoginGroup.addView(btnWechat, btnParam);
uiConfigBuilder.addCustomView(layoutLoginGroup, false, new JVerifyUIClickCallback() {
@Override
public void onClicked(Context context, View view) {
Log.e("tag", "一键登录11");
}
});
return uiConfigBuilder.build();
}
public void showProgressDialogByZL(){
CustomProgressDialog.showLoading(this,"加载中...");
}
public void hideProgressDialogByZL(){
CustomProgressDialog.stopLoading();
}
package com.pouke.mindcherish.activity.login_onekey;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.pouke.mindcherish.R;
import org.greenrobot.eventbus.EventBus;
import java.lang.ref.WeakReference;
/**
* @author zl
* @date 2021/7/2
* @description 自定义 ProgressDialog
*/
public class CustomProgressDialog extends Dialog implements DialogInterface.OnCancelListener {
private WeakReference<Context> mContext = new WeakReference<>(null);
private volatile static CustomProgressDialog sDialog;
private CustomProgressDialog(Context context, CharSequence message) {
super(context, R.style.CustomProgressDialogByZl);
mContext = new WeakReference<>(context);
@SuppressLint("InflateParams")
View view = LayoutInflater.from(context).inflate(R.layout.dialog_custom_progress, null);
TextView tvMessage = (TextView) view.findViewById(R.id.tv_message);
if (!TextUtils.isEmpty(message)) {
tvMessage.setText(message);
}
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
addContentView(view, lp);
setOnCancelListener(this);
}
@Override
public void onCancel(DialogInterface dialog) {
// 点手机返回键等触发Dialog消失,应该取消正在进行的网络请求等
Context context = mContext.get();
if (context != null) {
Log.e("tag","progressDialog cancel ");
EventBus.getDefault().post(new CloseProgressDialogEvent());
}
}
public static synchronized void showLoading(Context context) {
showLoading(context, "loading...");
}
public static synchronized void showLoading(Context context, CharSequence message) {
showLoading(context, message, true);
}
public static synchronized void showLoading(Context context, CharSequence message, boolean cancelable) {
if (sDialog != null && sDialog.isShowing()) {
sDialog.dismiss();
}
if (context == null || !(context instanceof Activity)) {
return;
}
sDialog = new CustomProgressDialog(context, message);
//false -- 不能销毁
sDialog.setCancelable(cancelable);
if (sDialog != null && !sDialog.isShowing() && !((Activity) context).isFinishing()) {
sDialog.show();
}
}
public static synchronized void stopLoading() {
if (sDialog != null && sDialog.isShowing()) {
sDialog.dismiss();
}
sDialog = null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/custom_progress_dialog_bg"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:paddingTop="20dp"
android:paddingBottom="20dp">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="@android:color/white"
android:indeterminateTintMode="src_atop"/>
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="加载中..."
android:textColor="@android:color/white"
android:layout_marginTop="10dp"
/>
</LinearLayout>
</LinearLayout>
custom_progress_dialog_bg 格式如下
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/alpha_80_black"/>
<corners android:radius="8dp"/>
</shape>
<color name="alpha_80_black">#CC000000</color>
<!-- 自定义 进度框 -->
<style name="CustomProgressDialogByZl" parent="@android:style/Theme.Dialog">
<!-- Dialog的windowFrame框为无 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 是否显示title -->
<item name="android:windowNoTitle">true</item>
<!-- 设置dialog的背景 -->
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 用来控制灰度的值,当为1时,界面除了我们的dialog内容是高亮显示的,dialog以外的区域是黑色的,完全看不到其他内容,系统的默认值是0.5 可设置为0.2 -->
<item name="android:backgroundDimAmount">0</item>
<!-- 是否模糊 此属性控制悬浮窗背景是否变暗。 -->
<item name="android:backgroundDimEnabled">true</item>
</style>
|