mirror of
https://gitee.com/willfree/min-vpn-client_v2.git
synced 2026-10-04 19:42:00 +08:00
add activity-login: 增加登录模块,可成功从welcome跳转到登录页面
This commit is contained in:
1 parent
34d3d506b6
commit
fa47d323be
25 files changed
+989
-20
No files matched your search
+2
-1
@@ -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')
|
||||
|
||||
Binary file not shown.
@@ -21,6 +21,9 @@
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.login.LoginActivity"
|
||||
android:launchMode="singleTask" />
|
||||
</application>
|
||||
|
||||
<!-- 以下为copy旧版本VPN的权限定义部分 -->
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.pkusz.min_vpn_client;
|
||||
|
||||
public class GlobalSetting {
|
||||
public static boolean openBiometric = false;
|
||||
}
|
||||
@@ -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<LoginActivityPresenter>
|
||||
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, Unit>) view -> {
|
||||
System.out.println("假装跳转到扫码界面");
|
||||
// ContextExtensionKt.jumpTo(LoginActivity.this, QRcodeScanActivity.class);
|
||||
return null;
|
||||
},
|
||||
(Function1<View, Unit>) 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();
|
||||
}
|
||||
}
|
||||
@@ -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<LoginActivityContract.View, LoginActivityContract.Model> {
|
||||
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){};
|
||||
}
|
||||
}
|
||||
@@ -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: 暂停人脸识别登录功能");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<WelcomeActivityPresenter>
|
||||
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<WelcomeActivityPresenter
|
||||
}
|
||||
|
||||
public void fingerprintAuthenticate(){
|
||||
System.out.println("指纹验证...");
|
||||
System.out.println("指纹验证 ing...");
|
||||
// todo: 指纹验证
|
||||
System.out.println("指纹验证 success");
|
||||
initView();
|
||||
}
|
||||
|
||||
private void initView(){
|
||||
GlideApp.with(this)
|
||||
.load(R.drawable.logo)
|
||||
.circleCrop()
|
||||
.into(imageView_imgLogo);
|
||||
imageView_imgLogo.setScaleX(0.5f);
|
||||
imageView_imgLogo.setScaleY(1.1f);
|
||||
String[] premissions= new String[]{
|
||||
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
android.Manifest.permission.FOREGROUND_SERVICE,
|
||||
android.Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
android.Manifest.permission.READ_PHONE_STATE,
|
||||
android.Manifest.permission.ACCESS_WIFI_STATE,
|
||||
android.Manifest.permission.INTERNET,
|
||||
android.Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
android.Manifest.permission.CAMERA
|
||||
};
|
||||
boolean b = imageView_imgLogo.postDelayed(() -> {
|
||||
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
|
||||
|
||||
@@ -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){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 ""
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
<include
|
||||
android:id="@+id/include"
|
||||
layout="@layout/bar_item" />
|
||||
|
||||
@@ -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}"
|
||||
|
||||
+6
@@ -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)
|
||||
}
|
||||
}
|
||||
+15
-9
@@ -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))
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ private fun <T: Fragment> getFragment(tag: String, clazz: Class<T>, fragmentMana
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
.add(fragment, tag)
|
||||
.commitNow()
|
||||
.commitNowAllowingStateLoss()
|
||||
}
|
||||
return fragment!!
|
||||
}
|
||||
|
||||
+22
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
+69
@@ -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<QuickAndroidRxPermissionFragment>
|
||||
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<String>, @StringRes tip: Int): Observable<QuickAndroidRxPermissionItem> {
|
||||
requestCode++
|
||||
return mRxPermissionFragment.value.requestPermissions(permissions, tip, requestCode)
|
||||
.compose(RxSchedulersHelper.io_main())
|
||||
}
|
||||
|
||||
fun request(permissions: Array<String>, tip: String = "请求权限"): Observable<QuickAndroidRxPermissionItem> {
|
||||
requestCode++
|
||||
return mRxPermissionFragment.value.requestPermissions(permissions, tip, requestCode)
|
||||
.compose(RxSchedulersHelper.io_main())
|
||||
}
|
||||
|
||||
// fun request(strings: Array<String>): Any {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
////////// QuickAndroid 扩展
|
||||
//////////////////////////////////////////////////////////
|
||||
fun QuickAndroid.createRxPermission(activity: FragmentActivity): QuickAndroidRxPermission {
|
||||
return QuickAndroidRxPermission.create(activity)
|
||||
}
|
||||
|
||||
fun QuickAndroid.createRxPermission(fragment: Fragment): QuickAndroidRxPermission {
|
||||
return QuickAndroidRxPermission.create(fragment)
|
||||
}
|
||||
+77
@@ -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<Int, ObservableEmitter<QuickAndroidRxPermissionItem>>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
retainInstance = true
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权成功
|
||||
*/
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
permissionsMap[requestCode]?.let {
|
||||
it.onNext(QuickAndroidRxPermissionItem(true, requestCode, perms))
|
||||
it.onComplete()
|
||||
permissionsMap.remove(requestCode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权失败
|
||||
*/
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
permissionsMap[requestCode]?.let {
|
||||
it.onNext(QuickAndroidRxPermissionItem(false, requestCode, perms))
|
||||
it.onComplete()
|
||||
permissionsMap.remove(requestCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 请求权限
|
||||
*/
|
||||
fun requestPermissions(permissions: Array<String>, @StringRes tip: Int, requestCode: Int)
|
||||
: Observable<QuickAndroidRxPermissionItem> {
|
||||
return requestPermissions(permissions, getString(tip), requestCode)
|
||||
}
|
||||
|
||||
|
||||
fun requestPermissions(permissions: Array<String>, tip: String, requestCode: Int)
|
||||
: Observable<QuickAndroidRxPermissionItem> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -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<String>
|
||||
)
|
||||
+4
@@ -51,6 +51,10 @@ class QuickAndroidRxPermission {
|
||||
return mRxPermissionFragment.value.requestPermissions(permissions, tip, requestCode)
|
||||
.compose(RxSchedulersHelper.io_main())
|
||||
}
|
||||
|
||||
// fun request(strings: Array<String>): Any {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
Reference in new issue
Block a user