diff --git a/app/build.gradle b/app/build.gradle index 6b15316..9e74583 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,6 +78,7 @@ dependencies { implementation files('libs/gmhelper.jar') implementation files('libs/BaiduLBS_Android.jar') implementation files('libs/min-dev-java-1.0-release.jar') + implementation project(path: ':fileselectorlib') // implementation files('libs/vpnjce-1.0.jar') // 在依赖中添加对jre的依赖,以尝试解决android.jar中原生javax与java中的javax的冲突问题 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 index 46a2a36..c77ad05 100644 --- 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 @@ -7,9 +7,14 @@ package com.pkusz.min_vpn_client.activity.login; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ +import android.app.AlertDialog; +import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.View; +import android.view.Window; +import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -30,6 +35,7 @@ import com.pkusz.min_vpn_client.utils.DigestUtilKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Objects; import br.com.simplepass.loadingbutton.customViews.CircularProgressButton; @@ -43,7 +49,11 @@ import cn.qjm253.quick_android_easy_bar.EasyBar; import cn.qjm253.quick_android_easy_bar.EasyBarExtensionsKt; import kotlin.Unit; import kotlin.jvm.functions.Function1; -import com.pkusz.min_vpn_client.utils.IdentityDump; + +import com.pkusz.min_vpn_client.utils.identity.IdentityDump; +import com.pkusz.min_vpn_client.utils.identity.ScreenSizeUtils; +import com.zlylib.fileselectorlib.FileSelector; +import com.zlylib.fileselectorlib.utils.Const; public class LoginActivity extends MINVpnBaseActivity @@ -153,7 +163,12 @@ public class LoginActivity extends MINVpnBaseActivity ContextExtensionKt.hideSoftKeyboard(this,export_identity); export_identity.startAnimation(); export_identity.revertAnimation(); - new IdentityDump().exportIdentity(); + //new IdentityDump().exportIdentity(); + //showCustomizeDialog(); + FileSelector.from(this) + .onlySelectFolder() //只能选择文件夹 + .requestCode(2) //设置返回码 + .start(); Toast.makeText(this, "You clicked export identity button", Toast.LENGTH_SHORT).show(); }); @@ -163,7 +178,19 @@ public class LoginActivity extends MINVpnBaseActivity ContextExtensionKt.hideSoftKeyboard(this,import_identity); import_identity.startAnimation(); import_identity.revertAnimation(); - new IdentityDump().importIdentity(); + FileSelector.from(this) + // .onlyShowFolder() //只显示文件夹 + //.onlySelectFolder() //只能选择文件夹 + // .isSingle() // 只能选择一个 + .setMaxCount(1) //设置最大选择数 + .setFileTypes("png","jpg", "doc","apk", "mp3", "gif", "txt", "mp4", "zip","db","export") //设置文件类型 + .setSortType(FileSelector.BY_NAME_ASC) //设置名字排序 + //.setSortType(FileSelector.BY_TIME_ASC) //设置时间排序 + //.setSortType(FileSelector.BY_SIZE_DESC) //设置大小排序 + //.setSortType(FileSelector.BY_EXTENSION_DESC) //设置类型排序 + .requestCode(1) //设置返回码 + .setTargetPath("/storage/emulated/0/") + .start(); Toast.makeText(this, "You clicked import identity button", Toast.LENGTH_SHORT).show(); }); @@ -290,4 +317,73 @@ public class LoginActivity extends MINVpnBaseActivity public void syncVpnInfoFailed() { showWarning("从VMS同步VPN服务器信息失败"); } + + private void showCustomizeDialog() { + /* @setView 装入自定义View ==> R.layout.dialog_customize + * 由于dialog_customize.xml只放置了一个EditView,因此和图8一样 + * dialog_customize.xml可自定义更复杂的View + */ + View view = LayoutInflater.from(this).inflate(R.layout.layout_identity_dialog,null,false); + final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create(); + //使得点击对话框外部不消失对话框 + dialog.setCanceledOnTouchOutside(false); +// Button test_button=view.findViewById(R.id.text_button); +// test_button.setOnClickListener(v->{ +// Toast.makeText(this, "You clicked test button", Toast.LENGTH_SHORT).show(); +// dialog.dismiss(); +// }); + + dialog.show(); + + //设置dialog的位置、大小 + Window dialogWindow = dialog.getWindow(); + WindowManager.LayoutParams lp = dialogWindow.getAttributes(); + lp.width = (int) (ScreenSizeUtils.getInstance(this).getScreenWidth() * 0.8f); + lp.height = (int) (ScreenSizeUtils.getInstance(this).getScreenHeight() * 0.5f); + dialogWindow.setAttributes(lp); + + } + + @Override + //回调函数 + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + //导入身份 + if (requestCode == 1) { + if (data.getStringArrayListExtra(Const.EXTRA_RESULT_SELECTION) != null) { + ArrayList essFileList = data.getStringArrayListExtra(Const.EXTRA_RESULT_SELECTION); + StringBuilder builder = new StringBuilder(); + System.out.println(essFileList.size()); + System.out.println(essFileList); + for (String file : + essFileList) { + builder.append(file); + } + System.out.print(builder.toString()); + String path=builder.toString(); + new IdentityDump().importIdentity(path); + Toast.makeText(this, "export adress is "+path, Toast.LENGTH_SHORT).show(); + } + } + //导出身份 + if(requestCode==2){ + if (data.getStringArrayListExtra(Const.EXTRA_RESULT_SELECTION) != null) { + ArrayList essFileList = data.getStringArrayListExtra(Const.EXTRA_RESULT_SELECTION); + StringBuilder builder = new StringBuilder(); + System.out.println(essFileList.size()); + System.out.println(essFileList); + for (String file : + essFileList) { + builder.append(file); + } + String path=builder.toString(); + //new IdentityDump().importIdentity(path); + System.out.println(path); + new IdentityDump().exportIdentity(path); + Toast.makeText(this, "import address is "+path, Toast.LENGTH_SHORT).show(); + } + } + } + } } diff --git a/app/src/main/java/com/pkusz/min_vpn_client/utils/IdentityDump.java b/app/src/main/java/com/pkusz/min_vpn_client/utils/identity/IdentityDump.java similarity index 55% rename from app/src/main/java/com/pkusz/min_vpn_client/utils/IdentityDump.java rename to app/src/main/java/com/pkusz/min_vpn_client/utils/identity/IdentityDump.java index 9c98f3f..a72767d 100644 --- a/app/src/main/java/com/pkusz/min_vpn_client/utils/IdentityDump.java +++ b/app/src/main/java/com/pkusz/min_vpn_client/utils/identity/IdentityDump.java @@ -1,9 +1,12 @@ -package com.pkusz.min_vpn_client.utils; +package com.pkusz.min_vpn_client.utils.identity; +import com.pkusz.min_vpn_client.utils.KeyManager; + import security.SafeBag; import util.FileUtil; import java.io.IOException; +import java.security.SecureRandom; import java.util.Arrays; @@ -79,6 +82,56 @@ public class IdentityDump { .getIdentity("/"+username,identityPath)); } + public void importIdentity(String identityFilePath){ + // 导入身份前查看是否有该用户身份 +// System.out.println("试图取出未导入的用户身份: "+KeyManager.INSTANCE +// .getIdentity("/"+username,identityPath)); + // 从本地文件中读取身份数据 + byte[] identityBytes; + try { + identityBytes=FileUtil.readFile(identityFilePath); + } catch (IOException e) { + e.printStackTrace(); + return; + } + // 转成SafeBag + SafeBag safeBag=new SafeBag(identityBytes); + // 导入到本地身份数据库中 + try { + KeyManager.INSTANCE.getKeyChain().importSafeBag(safeBag,"",true); + } catch (Exception e) { + e.printStackTrace(); + } + // 导入身份后查看是否有该用户身份 + int last=identityFilePath.lastIndexOf("/"); + String identityPath=identityFilePath.substring(0,last); + System.out.println("查看是否成功导入用户身份: "+KeyManager.INSTANCE + .getIdentity("/"+username,identityPath)); + } + + + public void exportIdentity(String identityPath){ + String identityFilePath=identityPath+username+".export"; + // 生成数据库身份 + new IdentityDump().generateForeverIdentity(username,identityPath); + System.out.println("生成的用户身份: "+KeyManager.INSTANCE + .getIdentity("/"+username,identityPath)); + // 导出数据库身份 + SafeBag safeBag; + try { + safeBag=KeyManager.INSTANCE.getKeyChain().exportSafeBag(""); + System.out.println(Arrays.toString(safeBag.getValue())); + } catch (Exception e) { + e.printStackTrace(); + return; + } + // 将身份数据写入本地文件 + try { + FileUtil.writeFile(identityFilePath,safeBag.getValue()); + } catch (IOException e) { + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/pkusz/min_vpn_client/utils/identity/ScreenSizeUtils.java b/app/src/main/java/com/pkusz/min_vpn_client/utils/identity/ScreenSizeUtils.java new file mode 100644 index 0000000..4e42ae7 --- /dev/null +++ b/app/src/main/java/com/pkusz/min_vpn_client/utils/identity/ScreenSizeUtils.java @@ -0,0 +1,38 @@ +package com.pkusz.min_vpn_client.utils.identity; + +import android.content.Context; +import android.util.DisplayMetrics; +import android.view.WindowManager; + +public class ScreenSizeUtils { + private static ScreenSizeUtils instance = null; + private int screenWidth, screenHeight; + + public static ScreenSizeUtils getInstance(Context mContext) { + if (instance == null) { + synchronized (ScreenSizeUtils.class) { + if (instance == null) + instance = new ScreenSizeUtils(mContext); + } + } + return instance; + } + + private ScreenSizeUtils(Context mContext) { + WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); + DisplayMetrics dm = new DisplayMetrics(); + manager.getDefaultDisplay().getMetrics(dm); + screenWidth = dm.widthPixels;// 获取屏幕分辨率宽度 + screenHeight = dm.heightPixels;// 获取屏幕分辨率高度 + } + + //获取屏幕宽度 + public int getScreenWidth() { + return screenWidth; + } + + //获取屏幕高度 + public int getScreenHeight() { + return screenHeight; + } +} diff --git a/app/src/main/res/layout/layout_identity_dialog.xml b/app/src/main/res/layout/layout_identity_dialog.xml new file mode 100644 index 0000000..b5a7017 --- /dev/null +++ b/app/src/main/res/layout/layout_identity_dialog.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + +