diff --git a/app/build.gradle b/app/build.gradle
index 1cdd5bd..ad3f176 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -75,6 +75,7 @@ android {
}
dependencies {
+ implementation files('libs\\gmhelper.jar')
// testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
@@ -110,7 +111,7 @@ dependencies {
api project(path: ':locallib_quick_android:quick_android_custom_view')
api project(path: ':locallib_quick_android:quick_android_easy_bar')
api project(path: ':locallib_quick_android:quick_android_mvp')
- api project(path: ':locallib_quick_android:quick_android_rx_permission')
+// api project(path: ':locallib_quick_android:quick_android_rx_permission')
// api project(path: ':locallib_quick_android/quick_android_qrcode')
// api project(path: ':locallib_quick_android/quick_android_image_picker')
// api project(path: ':locallib_quick_android/quick_android_file_picker')
diff --git a/app/libs/gmhelper.jar b/app/libs/gmhelper.jar
new file mode 100644
index 0000000..d436d08
Binary files /dev/null and b/app/libs/gmhelper.jar differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dd4f699..2ef816f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,6 +21,9 @@
+
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java b/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java
new file mode 100644
index 0000000..8dba707
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java
@@ -0,0 +1,5 @@
+package com.pkusz.min_vpn_client;
+
+public class GlobalSetting {
+ public static boolean openBiometric = false;
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivity.java b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivity.java
new file mode 100644
index 0000000..de7b77a
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivity.java
@@ -0,0 +1,253 @@
+package com.pkusz.min_vpn_client.activity.login;
+/*
+ * @Author: Wang Feng
+ * @Description:
+ * @Version: 1.0.0
+ * @Date: 19:45 2021/6/25
+ * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
+ */
+
+import android.animation.Animator;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.google.android.material.checkbox.MaterialCheckBox;
+import com.pkusz.min_vpn_client.GlobalSetting;
+import com.pkusz.min_vpn_client.R;
+import com.pkusz.min_vpn_client.activity.base.MINVpnBaseActivity;
+import com.pkusz.min_vpn_client.activity.welcome.WelcomeActivity;
+import com.pkusz.min_vpn_client.model.MINVpnAPI;
+import com.pkusz.min_vpn_client.model.request.LoginRequest;
+import com.pkusz.min_vpn_client.utils.AccountValidatorRegexUtil;
+import com.pkusz.min_vpn_client.utils.Base64Util;
+import com.pkusz.min_vpn_client.utils.DigestUtilKt;
+import com.pkusz.min_vpn_client.utils.KeyManager;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+import br.com.simplepass.loadingbutton.customViews.CircularProgressButton;
+import cn.qjm253.min_vpn.extensions.ActivityExtensionsKt;
+import cn.qjm253.quick_android_base.GlideApp;
+import cn.qjm253.quick_android_base.extensions.ContextExtensionKt;
+import cn.qjm253.quick_android_base.extensions.ViewExtensionKt;
+import cn.qjm253.quick_android_base.util.DisplayUtils;
+import cn.qjm253.quick_android_custom_view.other.ClearAbleEditText;
+import cn.qjm253.quick_android_easy_bar.EasyBar;
+import cn.qjm253.quick_android_easy_bar.EasyBarExtensionsKt;
+import kotlin.Unit;
+import kotlin.jvm.functions.Function1;
+
+public class LoginActivity extends MINVpnBaseActivity
+ implements LoginActivityContract.View{
+ // 常规变量区
+ private String username="";
+ private String password="";
+ // 界面变量区
+ private EasyBar easyBar;
+ private ImageView imageView_imgLogo;
+ private MaterialCheckBox savePasswordBox;
+ private TextView tvLoginWithSMS;
+ private TextView tvRegisterNow;
+ private TextView tvResetNow;
+ private ClearAbleEditText etUsername;
+ private CircularProgressButton btnLogin;
+ private ClearAbleEditText etPassword;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_login);
+ // 初始化各个组件
+ easyBar=findViewById(R.id.easyBar);
+ imageView_imgLogo=findViewById(R.id.imgLogo);
+ savePasswordBox=findViewById(R.id.savePasswordBox);
+ tvLoginWithSMS = findViewById(R.id.tvLoginWithSMS);
+ tvRegisterNow=findViewById(R.id.tvRegisterNow);
+ tvResetNow=findViewById(R.id.tvResetNow);
+ etUsername=findViewById(R.id.etUsername);
+ btnLogin=findViewById(R.id.btnLogin);
+ etPassword=findViewById(R.id.etPassword);
+
+ initView();
+ }
+
+ private void initView(){
+ // 初始化bar
+ EasyBarExtensionsKt.init(easyBar, EasyBar.Mode.ICON, String.valueOf(R.string.login),
+ (Function1) view -> {
+ System.out.println("假装跳转到扫码界面");
+// ContextExtensionKt.jumpTo(LoginActivity.this, QRcodeScanActivity.class);
+ return null;
+ },
+ (Function1) view -> {
+ System.out.println("假装跳转到设置界面");
+// ContextExtensionKt.jumpTo(LoginActivity.this, SettingActivity.class);
+ return null;
+ },
+ R.drawable.scan, R.drawable.setting, "", "", -1,
+ true, R.color.white);
+
+ // glideapp
+ GlideApp.with(this)
+ .load(R.drawable.logo)
+ .circleCrop()
+ .into(imageView_imgLogo);
+
+ // 判断是否已登录
+ if(MINVpnAPI.INSTANCE.isLogin()){
+ savePasswordBox.setChecked(true);
+ }else{
+ savePasswordBox.setChecked(false);
+ }
+
+ // 监听是否验证码登录
+ tvLoginWithSMS.setOnClickListener(v -> {
+ System.out.println("假装跳转到验证码界面");
+// ContextExtensionKt.jumpTo(this, LoginSMSActivity.class);
+ });
+
+ // 监听注册按钮
+ tvRegisterNow.setOnClickListener(v -> {
+ System.out.println("假装跳转到注册界面");
+// ContextExtensionKt.jumpTo(this, LoginSMSActivity.class);
+ });
+
+ // 监听重置密码按钮
+ tvResetNow.setOnClickListener(v -> {
+ System.out.println("假装跳转到重置界面");
+// ContextExtensionKt.jumpTo(this, LoginSMSActivity.class);
+ });
+
+ // 显示账号
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ etUsername.setText(Base64Util.Base64PlusDecode(MINVpnAPI.INSTANCE.getUsername()));
+ }else{
+ System.out.println("Base64Util.Base64PlusDecode error");
+ }
+
+ // 如果设置了密码保存,则显示密码
+ if(savePasswordBox.isChecked()){
+ etPassword.setText(MINVpnAPI.INSTANCE.getPassword());
+ }
+
+ // 登录按钮
+ btnLogin.setBackgroundResource(R.drawable.button_shape_default);
+ btnLogin.setOnClickListener(v->{
+ ContextExtensionKt.hideSoftKeyboard(this,btnLogin);
+ btnLogin.startAnimation();
+
+ this.username= Objects.requireNonNull(etUsername.getText()).toString();
+ this.password= Objects.requireNonNull(etPassword.getText()).toString();
+
+ if(username.isEmpty()||password.isEmpty()){
+ showWarning("请将信息填写完整");
+ btnLogin.revertAnimation();
+ return;
+ }
+ if(!AccountValidatorRegexUtil.INSTANCE.isPassword(password)){
+ showWarning("请输入有效的密码,密码为8-16位,必须包含大小写字母和特殊符号");
+ btnLogin.revertAnimation();
+ return;
+ }
+ if(!AccountValidatorRegexUtil.INSTANCE.isUsername(username)){
+ showWarning("请输入有效的用户名,用户名长度需要大于0小于20");
+ btnLogin.revertAnimation();
+ return;
+ }
+
+ // 账号转base64
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ username=Base64Util.Base64PlusEncode(username);
+ }else{
+ System.out.println("Base64Util.Base64PlusDecode error");
+ }
+
+ // 初始化keymanager
+ KeyManager.INSTANCE.initKeyChain("/"+username);
+
+ // 登录server(密码转md5)
+ LoginRequest loginRequest=new LoginRequest();
+ loginRequest.Prefix="/"+username;
+ loginRequest.Password= DigestUtilKt.encodeToMD5(password);
+ if(GlobalSetting.openBiometric){
+ // 第一种模式,人脸识别登录,暂时废弃
+// mPresenter.downloadRegisterFacePicture(username,loginRequest,this);
+ }else{
+ mPresenter.login(loginRequest);
+ }
+ });
+
+ // 监听键盘是否弹起
+ ActivityExtensionsKt.listenKeyboardVisible(this,(isOpen)->{
+ if(isOpen){
+ ViewExtensionKt.animer(imageView_imgLogo,
+ ViewExtensionKt.scaleXAnimation(imageView_imgLogo,1f, 0.5f),
+ ViewExtensionKt.scaleYAnimation(imageView_imgLogo,1f, 0.5f),
+ ViewExtensionKt.transYAnimation(imageView_imgLogo,
+ 0f, -DisplayUtils.dp2px(this, 40)),
+ ViewExtensionKt.transYAnimation(etUsername,
+ 0f, -DisplayUtils.dp2px(this, 90)),
+ ViewExtensionKt.transYAnimation(etPassword,
+ 0f, -DisplayUtils.dp2px(this, 90)),
+ ViewExtensionKt.transYAnimation(btnLogin,
+ 0f, -DisplayUtils.dp2px(this, 90)));
+ }else{
+ ViewExtensionKt.animer(imageView_imgLogo,
+ ViewExtensionKt.scaleXAnimation(imageView_imgLogo,0.5f, 1f),
+ ViewExtensionKt.scaleYAnimation(imageView_imgLogo,0.5f, 1f),
+ ViewExtensionKt.transYAnimation(imageView_imgLogo,
+ 0f, -DisplayUtils.dp2px(this, 40),0f),
+ ViewExtensionKt.transYAnimation(etUsername,
+ 0f, -DisplayUtils.dp2px(this, 90),0f),
+ ViewExtensionKt.transYAnimation(etPassword,
+ 0f, -DisplayUtils.dp2px(this, 90),0f),
+ ViewExtensionKt.transYAnimation(btnLogin,
+ 0f, -DisplayUtils.dp2px(this, 90),0f));
+ }
+ return null;
+ });
+
+
+ }
+
+
+
+
+ @NotNull
+ @Override
+ public LoginActivityPresenter onCreatePresenter() {
+ return new LoginActivityPresenter(this);
+ }
+
+ @Override
+ public void loginSuccess() {
+ loginSuccess("登录成功");
+ }
+
+ @Override
+ public void loginSuccess(String successMsg) {
+ showSuccess(successMsg);
+ MINVpnAPI.INSTANCE.updateUsername(username);
+ if(savePasswordBox.isChecked()){
+ MINVpnAPI.INSTANCE.updatePassword(password);
+ }else{
+ MINVpnAPI.INSTANCE.updatePassword("");
+ }
+ btnLogin.revertAnimation();
+ System.out.println("假装跳转到了Main");
+// ContextExtensionKt.jumpTo(this, .class);
+ finish();
+ }
+
+ @Override
+ public void loginFailed(String errMsg) {
+ showWarning("登录失败: "+errMsg);
+ btnLogin.revertAnimation();
+ }
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityContract.java b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityContract.java
new file mode 100644
index 0000000..2aa1302
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityContract.java
@@ -0,0 +1,39 @@
+package com.pkusz.min_vpn_client.activity.login;
+/*
+ * @Author: Wang Feng
+ * @Description:
+ * @Version: 1.0.0
+ * @Date: 16:28 2021/6/28
+ * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
+ */
+
+import android.content.Context;
+
+import com.pkusz.min_vpn_client.activity.base.MINVpnBaseView;
+import com.pkusz.min_vpn_client.model.request.LoginRequest;
+
+import cn.qjm253.quick_android_mvp.base.mvp.BaseModel;
+import cn.qjm253.quick_android_mvp.base.mvp.BasePresenter;
+
+public interface LoginActivityContract {
+ interface View extends MINVpnBaseView {
+ void loginSuccess();
+ void loginSuccess(String successMsg);
+ void loginFailed(String errMsg);
+ }
+
+ interface Model extends BaseModel {
+ void login(LoginRequest loginRequest);
+ void loginWithSafetyInfo(LoginRequest loginRequest, Context context);
+ void downloadRegisterFacePicture(String username,LoginRequest loginRequest, Context context);
+ }
+
+ abstract class Presenter extends BasePresenter {
+ void loginSuccess(){};
+ void loginSuccess(String successMsg){};
+ void loginFailed(String errMsg){};
+ void login(LoginRequest loginRequest){};
+ void loginWithSafetyInfo(LoginRequest loginRequest, Context context){};
+ void downloadRegisterFacePicture(String username,LoginRequest loginRequest, Context context){};
+ }
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityModel.java b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityModel.java
new file mode 100644
index 0000000..3ece153
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityModel.java
@@ -0,0 +1,52 @@
+package com.pkusz.min_vpn_client.activity.login;
+/*
+ * @Author: Wang Feng
+ * @Description:
+ * @Version: 1.0.0
+ * @Date: 16:37 2021/6/28
+ * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
+ */
+
+import android.content.Context;
+
+import com.pkusz.min_vpn_client.model.Request_API;
+import com.pkusz.min_vpn_client.model.request.LoginRequest;
+
+import common.LoggerHelper;
+
+public class LoginActivityModel implements LoginActivityContract.Model{
+ private LoginActivityPresenter mPresenter;
+
+ public LoginActivityModel(LoginActivityPresenter presenter){
+ this.mPresenter=presenter;
+ }
+
+ @Override
+ public void login(LoginRequest loginRequest) {
+// 与MIS通信,获取返回信息
+// Request_API.INSTANCE.login()
+ // 假定成功登录,则执行下面语句
+ boolean flag=true;
+ if(flag){
+ mPresenter.loginSuccess();
+ }else{
+ mPresenter.loginFailed("测试登录失败...");
+ }
+ }
+
+ @Override
+ public void loginWithSafetyInfo(LoginRequest loginRequest, Context context) {
+ // 内含百度定位、mac地址等信息
+ boolean flag=true;
+ if(flag){
+ mPresenter.loginSuccess();
+ }else{
+ mPresenter.loginFailed("测试登录失败...");
+ }
+ }
+
+ @Override
+ public void downloadRegisterFacePicture(String username, LoginRequest loginRequest, Context context) {
+ LoggerHelper.warning("model.downloadRegisterFacePicture: 暂停人脸识别登录功能");
+ }
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityPresenter.java b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityPresenter.java
new file mode 100644
index 0000000..ea4ff6a
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/activity/login/LoginActivityPresenter.java
@@ -0,0 +1,49 @@
+package com.pkusz.min_vpn_client.activity.login;
+/*
+ * @Author: Wang Feng
+ * @Description:
+ * @Version: 1.0.0
+ * @Date: 16:35 2021/6/28
+ * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
+ */
+
+import android.content.Context;
+
+import com.pkusz.min_vpn_client.model.request.LoginRequest;
+
+public class LoginActivityPresenter extends LoginActivityContract.Presenter{
+ public LoginActivityPresenter(LoginActivity loginActivity){
+ mView=loginActivity;
+ mModel=new LoginActivityModel(this);
+ }
+
+ @Override
+ void loginSuccess() {
+ mView.loginSuccess();
+ }
+
+ @Override
+ void loginSuccess(String successMsg) {
+ mView.loginSuccess(successMsg);
+ }
+
+ @Override
+ void loginFailed(String errMsg) {
+ mView.loginFailed(errMsg);
+ }
+
+ @Override
+ void login(LoginRequest loginRequest) {
+ mModel.login(loginRequest);
+ }
+
+ @Override
+ void loginWithSafetyInfo(LoginRequest loginRequest, Context context) {
+ mModel.loginWithSafetyInfo(loginRequest, context);
+ }
+
+ @Override
+ void downloadRegisterFacePicture(String username, LoginRequest loginRequest, Context context) {
+ mModel.downloadRegisterFacePicture(username, loginRequest, context);
+ }
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/activity/welcome/WelcomeActivity.java b/app/src/main/java/com/pkusz/min_vpn_client/activity/welcome/WelcomeActivity.java
index 66205bc..29d3fba 100644
--- a/app/src/main/java/com/pkusz/min_vpn_client/activity/welcome/WelcomeActivity.java
+++ b/app/src/main/java/com/pkusz/min_vpn_client/activity/welcome/WelcomeActivity.java
@@ -8,28 +8,34 @@ package com.pkusz.min_vpn_client.activity.welcome;
*/
import android.os.Bundle;
-import android.os.PersistableBundle;
+import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.pkusz.min_vpn_client.R;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseActivity;
-import com.pkusz.min_vpn_client.extensions.FileUtilsExtensions;
+import com.pkusz.min_vpn_client.activity.login.LoginActivity;
import org.jetbrains.annotations.NotNull;
import cn.qjm253.min_vpn.extensions.FileUtilsExtensionsKt;
+import cn.qjm253.quick_android_base.GlideApp;
+import cn.qjm253.quick_android_base.QuickAndroid;
+import cn.qjm253.quick_android_base.extensions.ContextExtensionKt;
import cn.qjm253.quick_android_base.util.FileUtils;
-import cn.qjm253.quick_android_mvp.base.mvp.BaseView;
+import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.plugins.RxJavaPlugins;
public class WelcomeActivity extends MINVpnBaseActivity
implements WelcomeActivityContract.View{
+ ImageView imageView_imgLogo;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
+ imageView_imgLogo=findViewById(R.id.imgLogo);
}
@Override
@@ -48,7 +54,45 @@ public class WelcomeActivity extends MINVpnBaseActivity {
+ Disposable disp = QuickAndroid.INSTANCE.createRxPermission(WelcomeActivity.this)
+ .request(premissions, "请求权限")
+ .subscribe(quickAndroidRxPermissionItem -> {
+ if (quickAndroidRxPermissionItem.getGranted()) {
+ System.out.println("开始跳转");
+ ContextExtensionKt.jumpTo(WelcomeActivity.this,LoginActivity.class);
+ finish();
+ } else {
+ System.out.println("无跳转权限");
+ finish();
+ }
+ });
+ },600);
+ System.out.println("jump to login result: "+b);
}
@NotNull
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/MINVpnAPI.java b/app/src/main/java/com/pkusz/min_vpn_client/model/MINVpnAPI.java
new file mode 100644
index 0000000..7a6cdee
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/model/MINVpnAPI.java
@@ -0,0 +1,34 @@
+package com.pkusz.min_vpn_client.model;
+/*
+ * @Author: Wang Feng
+ * @Description:
+ * @Version: 1.0.0
+ * @Date: 17:23 2021/6/28
+ * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
+ */
+
+public enum MINVpnAPI {
+ INSTANCE;
+
+ private String username="";
+
+ public boolean isLogin(){
+ return !username.equals("");
+ }
+
+ public String getUsername(){
+ return username;
+ }
+
+ public String getPassword(){
+ return "";
+ }
+
+ public void updateUsername(String username){
+
+ }
+
+ public void updatePassword(String password){
+
+ }
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/Request_API.java b/app/src/main/java/com/pkusz/min_vpn_client/model/Request_API.java
index 0df942d..c8e8f80 100644
--- a/app/src/main/java/com/pkusz/min_vpn_client/model/Request_API.java
+++ b/app/src/main/java/com/pkusz/min_vpn_client/model/Request_API.java
@@ -24,9 +24,10 @@ import logicface.LogicFace;
import logicface.LogicFaceException;
import packet.Interest;
-public class Request_API {
+public enum Request_API {
+ INSTANCE;
private boolean isConnected = false;
- public LogicFace face = null;
+ private LogicFace face = null;
private String globalPrefix="/mis";
private boolean tcpTestFinished=false;
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/request/LoginRequest.java b/app/src/main/java/com/pkusz/min_vpn_client/model/request/LoginRequest.java
index 6d15f6d..44afaea 100644
--- a/app/src/main/java/com/pkusz/min_vpn_client/model/request/LoginRequest.java
+++ b/app/src/main/java/com/pkusz/min_vpn_client/model/request/LoginRequest.java
@@ -7,7 +7,7 @@ package com.pkusz.min_vpn_client.model.request;
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
-public class LoginRequest {
+public class LoginRequest extends BaseRequest{
// 继承属性
public String Type = BaseRequest.Type;
public String Command = "Login";
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/utils/AccountValidatorRegexUtil.kt b/app/src/main/java/com/pkusz/min_vpn_client/utils/AccountValidatorRegexUtil.kt
new file mode 100644
index 0000000..a414821
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/utils/AccountValidatorRegexUtil.kt
@@ -0,0 +1,176 @@
+package com.pkusz.min_vpn_client.utils
+
+import java.util.regex.Pattern
+
+/**
+ * 账户相关属性验证工具
+ */
+object AccountValidatorRegexUtil {
+ /**
+ * 正则表达式:验证用户名
+ */
+ val REGEX_USERNAME = "^[a-zA-Z]\\w{5,20}$"
+
+ /**
+ * 正则表达式:验证密码
+ */
+ val REGEX_PASSWORD = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[\$@\$!%*.#?&])[A-Za-z\\d\$@\$!%*.#?&]{8,20}\$"
+
+/* val REGEX_PASSWORD1 = "^((?![a-z]+$)(?![A-Z]+$)(?!\\d+$)(?![!@#$%^&*._-]+$)(?![a-zA-Z\\d]+$)(?![a-zA-Z!@#$%^&*._-]+$)(?![\\d!@#$%^&*._-]+$)[a-zA-Z\\d!@#$%^&*._-]+){8,20}$"
+ val REGEX_PASSWORD2 = ".*[A-Z]+.*"
+ val REGEX_PASSWORD3 = ".*[a-z]+.*"*/
+ /**
+ * 正则表达式:验证手机号
+ */
+ val REGEX_MOBILE = "^1[3-9]\\d{9}\$"
+
+ /**
+ * 正则表达式:验证邮箱
+ */
+ val REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"
+
+ /**
+ * 正则表达式:验证汉字
+ */
+ val REGEX_CHINESE = "^[\u4e00-\u9fa5],{0,}$"
+
+ /**
+ * 正则表达式:验证身份证
+ */
+ val REGEX_ID_CARD = "(^\\d{18}$)|(^\\d{15}$)"
+
+ /**
+ * 正则表达式:验证URL
+ */
+ val REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?"
+
+ /**
+ * 正则表达式:验证IP地址
+ */
+ val REGEX_IP_ADDR = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"
+
+ /**
+ * 正则表达式:验证NDN前缀
+ */
+ val REGEX_NDN_PREFIX = "(/([a-z]|[A-Z]|[0-9]|-|_){1,40}){1,10}"
+
+
+ /**
+ * 正则表达式:验证NDN前缀
+ */
+ val REGEX_PORT = "([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])"
+
+
+ /**
+ * 校验用户名
+ *
+ * @param username
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isUsername(username: String): Boolean {
+ //return Pattern.matches(REGEX_USERNAME, username)
+ return username.length > 0 && username.length < 20
+ }
+
+ /**
+ * 校验密码
+ *
+ * @param password
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isPassword(password: String): Boolean {
+/* return Pattern.matches(REGEX_PASSWORD1, password) && Pattern.matches(REGEX_PASSWORD2, password)
+ && Pattern.matches(REGEX_PASSWORD3, password)*/
+ return Pattern.matches(REGEX_PASSWORD, password)
+ }
+
+ /**
+ * 校验手机号
+ *
+ * @param mobile
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isMobile(mobile: String): Boolean {
+ return Pattern.matches(REGEX_MOBILE, mobile)
+ }
+
+ /**
+ * 校验邮箱
+ *
+ * @param email
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isEmail(email: String): Boolean {
+ return Pattern.matches(REGEX_EMAIL, email)
+ }
+
+ /**
+ * 校验汉字
+ *
+ * @param chinese
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isChinese(chinese: String): Boolean {
+ return Pattern.matches(REGEX_CHINESE, chinese)
+ }
+
+ /**
+ * 校验身份证
+ *
+ * @param idCard
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isIDCard(idCard: String): Boolean {
+ return Pattern.matches(REGEX_ID_CARD, idCard)
+ }
+
+ /**
+ * 校验URL
+ *
+ * @param url
+ * @return 校验通过返回true,否则返回false
+ */
+ fun isUrl(url: String): Boolean {
+ return Pattern.matches(REGEX_URL, url)
+ }
+
+ /**
+ * 校验IP地址
+ *
+ * @param ipAddr
+ * @return
+ */
+ fun isIPAddr(ipAddr: String): Boolean {
+ return Pattern.matches(REGEX_IP_ADDR, ipAddr)
+ }
+
+ /**
+ * 校验NDN前缀
+ *
+ * @param ndnPrefix
+ * @return
+ */
+ fun isndnPrefix(ndnPrefix: String): Boolean {
+ return Pattern.matches(REGEX_NDN_PREFIX, ndnPrefix)
+ }
+
+ /**
+ * 校验端口号
+ *
+ * @param ndnPrefix
+ * @return
+ */
+ fun isPort(port: String): Boolean {
+ return Pattern.matches(REGEX_PORT, port)
+ }
+
+ /**
+ * 校验端口号
+ *
+ * @param ndnPrefix
+ * @return
+ */
+ fun isInviteCode(invitecode: String): Boolean {
+ return invitecode.length > 0 && invitecode.length < 20
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/utils/Base64Util.java b/app/src/main/java/com/pkusz/min_vpn_client/utils/Base64Util.java
new file mode 100644
index 0000000..a13cc73
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/utils/Base64Util.java
@@ -0,0 +1,47 @@
+package com.pkusz.min_vpn_client.utils;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+
+public class Base64Util {
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ public static String Base64PlusEncode(String srcStr){
+ String dstStr = "" ;
+ try {
+ dstStr = Base64.getMimeEncoder().encodeToString(srcStr.getBytes("utf-8"));
+ } catch (UnsupportedEncodingException e) {
+ return dstStr ;
+ }
+ dstStr = dstStr.replaceAll("=","-").replaceAll("/","_") ;
+ return dstStr;
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ public static String Base64PlusDecode(String srcStr){
+ srcStr = srcStr.replaceAll("_","/").replaceAll("-","=") ;
+ byte[] dstStrByte = null;
+ try {
+ dstStrByte = Base64.getMimeDecoder().decode(srcStr.getBytes("utf-8"));
+ } catch (UnsupportedEncodingException e) {
+ return new String(dstStrByte) ;
+ }
+
+ return new String(dstStrByte);
+ }
+
+ public static String BlocChainEncode(String srcStr) {
+ String dstStr = "" ;
+ try {
+ //dstStr = Base64.getMimeEncoder().encodeToString(srcStr.getBytes("utf-8"));
+ dstStr = android.util.Base64.encodeToString(srcStr.getBytes("utf-8"),
+ android.util.Base64.NO_WRAP | android.util.Base64.NO_PADDING | android.util.Base64.URL_SAFE);
+ } catch (UnsupportedEncodingException e) {
+ return dstStr ;
+ }
+ return dstStr;
+ }
+}
diff --git a/app/src/main/java/com/pkusz/min_vpn_client/utils/DigestUtil.kt b/app/src/main/java/com/pkusz/min_vpn_client/utils/DigestUtil.kt
new file mode 100644
index 0000000..78946bd
--- /dev/null
+++ b/app/src/main/java/com/pkusz/min_vpn_client/utils/DigestUtil.kt
@@ -0,0 +1,69 @@
+package com.pkusz.min_vpn_client.utils
+
+import org.zz.gmhelper.SM3Util
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+
+object DigestUtil {
+ fun md5(message: String) {
+ val digest = MessageDigest.getInstance("MD5")
+ digest.update(message.toByte())
+ digest.digest()
+ }
+}
+
+fun String.encodeToMD5(): String {
+ try {
+ //获取md5加密对象
+ val instance: MessageDigest = MessageDigest.getInstance("MD5")
+ //对字符串加密,返回字节数组
+ val digest: ByteArray = instance.digest(this.toByteArray())
+ val sb = StringBuffer()
+ for (b in digest) {
+ //获取低八位有效值
+ val i: Int = b.toInt() and 0xff
+ //将整数转化为16进制
+ var hexString = Integer.toHexString(i)
+ if (hexString.length < 2) {
+ //如果是一位的话,补0
+ hexString = "0$hexString"
+ }
+ sb.append(hexString)
+ }
+ return sb.toString()
+
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ }
+
+ return ""
+}
+
+fun String.encodeToSM3(): String {
+ try {
+// //获取md5加密对象
+// val instance: MessageDigest = MessageDigest.getInstance("MD5")
+// //对字符串加密,返回字节数组
+ val digest:ByteArray = SM3Util.hash(this.toByteArray())
+ //val digest: ByteArray = instance.digest(this.toByteArray())
+ val sb = StringBuffer()
+ for (b in digest) {
+ //获取低八位有效值
+ val i: Int = b.toInt() and 0xff
+ //将整数转化为16进制
+ var hexString = Integer.toHexString(i)
+ if (hexString.length < 2) {
+ //如果是一位的话,补0
+ hexString = "0$hexString"
+ }
+ sb.append(hexString)
+ }
+ return sb.toString()
+
+ } catch (e: NoSuchAlgorithmException) {
+ e.printStackTrace()
+ }
+
+ return ""
+}
+
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index c92c561..0ba1020 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -5,7 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="cn.qjm253.min_vpn.activity.login.LoginActivity">
+ tools:context=".activity.login.LoginActivity">
diff --git a/locallib_quick_android/quick_android_base/build.gradle b/locallib_quick_android/quick_android_base/build.gradle
index 82ca341..c2d7f18 100644
--- a/locallib_quick_android/quick_android_base/build.gradle
+++ b/locallib_quick_android/quick_android_base/build.gradle
@@ -36,6 +36,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "androidx.appcompat:appcompat:${appcompact_version}"
+// implementation project(path: ':locallib_quick_android:quick_android_rx_permission')
testImplementation "junit:junit:${junit_version}"
implementation "androidx.constraintlayout:constraintlayout:${constraintlayout_version}"
androidTestImplementation "androidx.test:runner:${test_runner_version}"
diff --git a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/QuickAndroid.kt b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/QuickAndroid.kt
index 860c45e..a7d0876 100644
--- a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/QuickAndroid.kt
+++ b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/QuickAndroid.kt
@@ -2,6 +2,8 @@ package cn.qjm253.quick_android_base
import android.app.Application
import android.content.Context
+import androidx.fragment.app.FragmentActivity
+import cn.qjm253.quick_android_rx_permission.QuickAndroidRxPermission
import com.github.anzewei.parallaxbacklayout.ParallaxHelper
import com.orhanobut.logger.AndroidLogAdapter
import com.orhanobut.logger.Logger
@@ -38,4 +40,8 @@ object QuickAndroid {
enableParallaxBack = true
return this
}
+
+ fun createRxPermission(activity: FragmentActivity): QuickAndroidRxPermission {
+ return QuickAndroidRxPermission.create(activity)
+ }
}
\ No newline at end of file
diff --git a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ContextExtension.kt b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ContextExtension.kt
index 791a406..6c718a1 100644
--- a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ContextExtension.kt
+++ b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ContextExtension.kt
@@ -39,15 +39,22 @@ fun Context.jumpTo(cls: Class<*>, vararg flags: Int) {
startActivity(intent)
}
+//fun jumpTo(vararg cls: Class<*>) {
+// val intent = Intent(this, cls)
+// flags.forEach {
+// intent.addFlags(it)
+// }
+// startActivity(intent)
+//}
-fun Context.jumpTo(cls: Class<*>, intentParam: IntentParam? = null, vararg flags: Int) {
- val intent = Intent(this, cls)
- flags.forEach {
- intent.addFlags(it)
- }
- intentParam?.applyParam(intent)
- startActivity(intent)
-}
+//fun Context.jumpTo(cls: Class<*>, intentParam: IntentParam? = null, vararg flags: Int) {
+// val intent = Intent(this, cls)
+// flags.forEach {
+// intent.addFlags(it)
+// }
+// intentParam?.applyParam(intent)
+// startActivity(intent)
+//}
fun Activity.jumpForResult(cls: Class<*>, requestCode: Int = 0, intentParam: IntentParam? = null) {
val intent = Intent(this, cls)
@@ -146,4 +153,3 @@ fun Context.checkMyPermission(permission: String, granted: () -> Unit = {}, deny
private fun autoGenericCode(code: String, num: Int): String {
return String.format("%0" + num + "d", Integer.parseInt(code))
}
-
diff --git a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/FragmentManagerExtensions.kt b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/FragmentManagerExtensions.kt
index 9e1ceb7..53ef01f 100644
--- a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/FragmentManagerExtensions.kt
+++ b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/FragmentManagerExtensions.kt
@@ -37,7 +37,7 @@ private fun getFragment(tag: String, clazz: Class, fragmentMana
fragmentManager
.beginTransaction()
.add(fragment, tag)
- .commitNow()
+ .commitNowAllowingStateLoss()
}
return fragment!!
}
diff --git a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ViewExtension.kt b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ViewExtension.kt
index ea04d95..5aaba67 100644
--- a/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ViewExtension.kt
+++ b/locallib_quick_android/quick_android_base/src/main/java/cn/qjm253/quick_android_base/extensions/ViewExtension.kt
@@ -108,7 +108,28 @@ fun View.animer(vararg animations: ObjectAnimator, duration: Long, listener: Ani
if (listener != null)
animatorSet.addListener(listener)
animatorSet.start()
+}
+fun View.animer(vararg animations: ObjectAnimator, duration: Long) {
+ if (animations.isEmpty())
+ return
+ val animatorSet = AnimatorSet()
+ val builder = animatorSet.setDuration(duration)
+ .play(animations[0])
+ animations.filterIndexed { index, _ -> index != 0 }
+ .forEach { builder.with(it) }
+ animatorSet.start()
+}
+
+fun View.animer(vararg animations: ObjectAnimator) {
+ if (animations.isEmpty())
+ return
+ val animatorSet = AnimatorSet()
+ val builder = animatorSet.setDuration(200)
+ .play(animations[0])
+ animations.filterIndexed { index, _ -> index != 0 }
+ .forEach { builder.with(it) }
+ animatorSet.start()
}
/**
@@ -120,4 +141,4 @@ fun View.transRotateAlpha(transX: FloatArray = floatArrayOf(0f, 0f), transY: Flo
listener: Animator.AnimatorListener? = null) {
this.animer(transXAnimation(*transX), transYAnimation(*transY), rotationAnimation(*rotation),
alphaAnimation(*alpha), duration = duration, listener = listener)
-}
\ No newline at end of file
+}
diff --git a/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermission.kt b/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermission.kt
new file mode 100644
index 0000000..1369503
--- /dev/null
+++ b/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermission.kt
@@ -0,0 +1,69 @@
+package cn.qjm253.quick_android_rx_permission
+// 迁移过来代码
+import androidx.annotation.StringRes
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import cn.qjm253.quick_android_base.QuickAndroid
+import cn.qjm253.quick_android_base.extensions.getLazySingleton
+import cn.qjm253.quick_android_base.util.RxSchedulersHelper
+import io.reactivex.Observable
+
+/**
+ * @author SunnyQjm
+ * @date 19-7-8 上午9:03
+ */
+
+class QuickAndroidRxPermission {
+ companion object {
+ const val TAG = "QuickAndroidRxPermission"
+
+ fun create(activity: FragmentActivity): QuickAndroidRxPermission {
+ return QuickAndroidRxPermission(activity)
+ }
+
+ fun create(fragment: Fragment): QuickAndroidRxPermission {
+ return QuickAndroidRxPermission(fragment)
+ }
+ }
+
+ private var mRxPermissionFragment: Lazy
+ private var requestCode = 0
+
+ constructor(activity: FragmentActivity) {
+ mRxPermissionFragment = activity.supportFragmentManager
+ .getLazySingleton(TAG, QuickAndroidRxPermissionFragment::class.java)
+ }
+
+ constructor(fragment: Fragment) {
+ mRxPermissionFragment = fragment.childFragmentManager
+ .getLazySingleton(TAG, QuickAndroidRxPermissionFragment::class.java)
+ }
+
+
+ fun request(permissions: Array, @StringRes tip: Int): Observable {
+ requestCode++
+ return mRxPermissionFragment.value.requestPermissions(permissions, tip, requestCode)
+ .compose(RxSchedulersHelper.io_main())
+ }
+
+ fun request(permissions: Array, tip: String = "请求权限"): Observable {
+ requestCode++
+ return mRxPermissionFragment.value.requestPermissions(permissions, tip, requestCode)
+ .compose(RxSchedulersHelper.io_main())
+ }
+
+// fun request(strings: Array): Any {
+//
+// }
+}
+
+//////////////////////////////////////////////////////////
+////////// QuickAndroid 扩展
+//////////////////////////////////////////////////////////
+fun QuickAndroid.createRxPermission(activity: FragmentActivity): QuickAndroidRxPermission {
+ return QuickAndroidRxPermission.create(activity)
+}
+
+fun QuickAndroid.createRxPermission(fragment: Fragment): QuickAndroidRxPermission {
+ return QuickAndroidRxPermission.create(fragment)
+}
\ No newline at end of file
diff --git a/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermissionFragment.kt b/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermissionFragment.kt
new file mode 100644
index 0000000..e4b5033
--- /dev/null
+++ b/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermissionFragment.kt
@@ -0,0 +1,77 @@
+package cn.qjm253.quick_android_rx_permission
+
+import android.os.Bundle
+import androidx.annotation.StringRes
+import androidx.fragment.app.Fragment
+import io.reactivex.Observable
+import io.reactivex.ObservableEmitter
+import pub.devrel.easypermissions.EasyPermissions
+
+/**
+ * @author SunnyQjm
+ * @date 19-7-8 上午9:13
+ */
+
+class QuickAndroidRxPermissionFragment : Fragment(), EasyPermissions.PermissionCallbacks {
+
+ private val permissionsMap =
+ mutableMapOf>()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ retainInstance = true
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
+ }
+
+ /**
+ * 授权成功
+ */
+ override fun onPermissionsGranted(requestCode: Int, perms: MutableList) {
+ permissionsMap[requestCode]?.let {
+ it.onNext(QuickAndroidRxPermissionItem(true, requestCode, perms))
+ it.onComplete()
+ permissionsMap.remove(requestCode)
+ }
+ }
+
+ /**
+ * 授权失败
+ */
+ override fun onPermissionsDenied(requestCode: Int, perms: MutableList) {
+ permissionsMap[requestCode]?.let {
+ it.onNext(QuickAndroidRxPermissionItem(false, requestCode, perms))
+ it.onComplete()
+ permissionsMap.remove(requestCode)
+ }
+ }
+
+
+ /**
+ * 请求权限
+ */
+ fun requestPermissions(permissions: Array, @StringRes tip: Int, requestCode: Int)
+ : Observable {
+ return requestPermissions(permissions, getString(tip), requestCode)
+ }
+
+
+ fun requestPermissions(permissions: Array, tip: String, requestCode: Int)
+ : Observable {
+ return Observable.create { emitter ->
+ permissionsMap[requestCode] = emitter
+ activity?.let {
+ if (EasyPermissions.hasPermissions(it, *permissions)) {
+ onPermissionsGranted(requestCode, permissions.toMutableList())
+ } else {
+ EasyPermissions.requestPermissions(this, tip, requestCode, *permissions)
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermissionItem.kt b/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermissionItem.kt
new file mode 100644
index 0000000..eaa55e9
--- /dev/null
+++ b/locallib_quick_android/quick_android_base/src/main/java/quick_android_rx_permission/QuickAndroidRxPermissionItem.kt
@@ -0,0 +1,12 @@
+package cn.qjm253.quick_android_rx_permission
+
+/**
+ * @author SunnyQjm
+ * @date 19-7-8 上午9:34
+ */
+
+class QuickAndroidRxPermissionItem(
+ val granted: Boolean,
+ val requestCode: Int,
+ val perms: MutableList
+)
\ No newline at end of file
diff --git a/locallib_quick_android/quick_android_rx_permission/src/main/java/cn/qjm253/quick_android_rx_permission/QuickAndroidRxPermission.kt b/locallib_quick_android/quick_android_rx_permission/src/main/java/cn/qjm253/quick_android_rx_permission/QuickAndroidRxPermission.kt
index 139bbbd..c44f295 100644
--- a/locallib_quick_android/quick_android_rx_permission/src/main/java/cn/qjm253/quick_android_rx_permission/QuickAndroidRxPermission.kt
+++ b/locallib_quick_android/quick_android_rx_permission/src/main/java/cn/qjm253/quick_android_rx_permission/QuickAndroidRxPermission.kt
@@ -51,6 +51,10 @@ class QuickAndroidRxPermission {
return mRxPermissionFragment.value.requestPermissions(permissions, tip, requestCode)
.compose(RxSchedulersHelper.io_main())
}
+
+// fun request(strings: Array): Any {
+//
+// }
}
//////////////////////////////////////////////////////////