From 8d4fb99dd1a96f7545634764a37efbe995127e43 Mon Sep 17 00:00:00 2001
From: dxl <64101226@qq.com>
Date: Tue, 30 Jun 2020 15:41:31 +0800
Subject: [PATCH] Termux view implement.
---
app_main/build.gradle | 2 +-
app_main/src/main/AndroidManifest.xml | 2 +
.../chameleon/ChameleonGUIActivity.java | 2 +-
.../Proxmark3Rdv4RRGConnectActivity.java | 14 +-
.../cn/rrg/rdv/activities/main/AppMain.java | 3 -
.../rrg/rdv/activities/main/BaseActivity.java | 37 +--
.../main/PM3FlasherMainActivity.java | 3 +-
.../activities/tools/FileListActivity.java | 3 +-
.../tools/Proxmark3FirmwareActivity.java | 5 +
.../Proxmark3NewTerminalInitActivity.java | 35 +++
.../fragment/tools/MainSettingsFragment.java | 18 +-
.../main/java/cn/rrg/rdv/util/Commons.java | 37 ++-
.../src/main/java/cn/rrg/rdv/util/Paths.java | 10 +-
.../cn/rrg/rdv/util/Proxmark3Installer.java | 83 +++++++
.../main/java/cn/rrg/rdv/util/ZipUtils.java | 228 ++++++++++++++++++
app_main/src/main/res/values-en/strings.xml | 3 +-
app_main/src/main/res/values-zh/strings.xml | 3 +-
app_main/src/main/res/values/strings.xml | 3 +-
18 files changed, 416 insertions(+), 75 deletions(-)
create mode 100644 app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3NewTerminalInitActivity.java
create mode 100644 app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java
create mode 100644 app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java
diff --git a/app_main/build.gradle b/app_main/build.gradle
index ebd41c29..e0cc63cc 100644
--- a/app_main/build.gradle
+++ b/app_main/build.gradle
@@ -6,7 +6,7 @@ android {
defaultConfig {
applicationId "com.rfidresearchgroup.rfidtools"
minSdkVersion 24
- targetSdkVersion 29
+ targetSdkVersion 28
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
versionCode 21
versionName "1.4.5"
diff --git a/app_main/src/main/AndroidManifest.xml b/app_main/src/main/AndroidManifest.xml
index 52d02af7..317fc3b7 100644
--- a/app_main/src/main/AndroidManifest.xml
+++ b/app_main/src/main/AndroidManifest.xml
@@ -26,6 +26,7 @@
+
+
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java
index 23c30dd6..57b55ad7 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java
@@ -138,7 +138,7 @@ public class ChameleonGUIActivity
progressDialog = new AlertDialog.Builder(this).create();
progressDialog.setView(ViewUtil.inflate(this, R.layout.dialog_working_msg));
- progressDialog.setTitle(getString(R.string.woring));
+ progressDialog.setTitle(getString(R.string.working));
progressDialog.setCancelable(false);
ListView msgListView = new ListView(this);
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/connect/Proxmark3Rdv4RRGConnectActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/connect/Proxmark3Rdv4RRGConnectActivity.java
index ed9b9494..d0684445 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/connect/Proxmark3Rdv4RRGConnectActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/connect/Proxmark3Rdv4RRGConnectActivity.java
@@ -9,17 +9,15 @@ import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
-import com.termux.app.TermuxActivity;
-
import cn.rrg.rdv.R;
import cn.rrg.rdv.activities.main.PM3FlasherMainActivity;
import cn.rrg.rdv.activities.tools.DeviceConnectActivity;
+import cn.rrg.rdv.activities.tools.Proxmark3NewTerminalInitActivity;
import cn.rrg.rdv.callback.ConnectFailedCtxCallback;
import cn.rrg.rdv.models.AbstractDeviceModel;
import cn.rrg.rdv.models.Proxmark3Rdv4SppModel;
import cn.rrg.rdv.models.Proxmark3Rdv4UsbModel;
import cn.dxl.common.util.PermissionUtil;
-import cn.rrg.rdv.util.Commons;
/**
* 专供RDV4连接设备
@@ -50,18 +48,12 @@ public class Proxmark3Rdv4RRGConnectActivity
@Override
public Class getTarget() {
- //连接成功后将跳转到该界面!
- return TermuxActivity.class;
+ return Proxmark3NewTerminalInitActivity.class;
}
@Override
public String getConnectingMsg() {
- String msg = getString(R.string.progress_msg);
- msg += "\n\nFirmware: ";
- String version = Commons.PM3_CLIENT_VERSION;
- msg += version + "\n\n";
- String tips = getString(R.string.tips_pm3_version);
- return msg + tips;
+ return getString(R.string.tips_view_use_termux);
}
@Override
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java b/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java
index 7b67e307..f5d5c3fa 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/main/AppMain.java
@@ -11,7 +11,6 @@ import androidx.fragment.app.Fragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.iobridges.com.LocalComBridgeAdapter;
-import com.termux.app.TermuxActivity;
import cn.dxl.common.util.DisplayUtil;
import cn.dxl.common.util.FragmentUtil;
@@ -47,8 +46,6 @@ public class AppMain extends BaseActivity {
initActions();
gotoFragment(appMainDevicesFragment);
-
- startActivity(new Intent(this, TermuxActivity.class));
}
private void initViews() {
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/main/BaseActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/main/BaseActivity.java
index 6e01243c..e130e70f 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/main/BaseActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/main/BaseActivity.java
@@ -9,6 +9,7 @@ import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatDelegate;
import android.util.Log;
import android.view.MotionEvent;
@@ -42,21 +43,15 @@ public abstract class BaseActivity
private StdMifareIntent mStdMfUtil = null;
- private ArrayList onTouchListeners;
-
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(LOG_TAG, "Act is create");
- //实例化一个标准NFC设备工具对象!
mStdMfUtil = new StdMifareIntent(this);
- //添加全局的标签状态监听!
NfcTagListenUtils.addListener(this);
- //建立事件观察数列!
- onTouchListeners = new ArrayList<>();
- // 在onCreate()也要设置一下语言,有可能attachBaseContext()不生效。
LanguageUtil.setAppLanguage(this, Commons.getLanguage());
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
@Override
@@ -147,34 +142,6 @@ public abstract class BaseActivity
super.onNewIntent(intent);
}
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- //Log.d(LOG_TAG, "观察者数量: " + onTouchListeners.size());
- //在act获得了event的时候回调!
- if (onTouchListeners.size() == 0) return super.dispatchTouchEvent(ev);
- for (OnTouchListener listener : onTouchListeners) {
- // 进行相关的事件下发!
- if (listener != null) {
- //Log.d(LOG_TAG, "观察者: " + listener.toString());
- try {
- listener.onTouch(ev);
- } catch (Exception ignored) {
- }
- }
- }
- return super.dispatchTouchEvent(ev);
- }
-
- public void addTouchListener(OnTouchListener listener) {
- //Log.d(LOG_TAG, "添加观察者: " + listener.toString());
- onTouchListeners.add(listener);
- }
-
- public void removeTouchListener(OnTouchListener listener) {
- //Log.d(LOG_TAG, "移除观察者: " + listener.toString());
- onTouchListeners.remove(listener);
- }
-
@Override
protected void onStop() {
//Log.d(LOG_TAG, "Act is stop");
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/main/PM3FlasherMainActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/main/PM3FlasherMainActivity.java
index 30900eb6..6cf998fa 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/main/PM3FlasherMainActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/main/PM3FlasherMainActivity.java
@@ -2,7 +2,6 @@ package cn.rrg.rdv.activities.main;
import android.app.AlertDialog;
import android.os.Bundle;
-import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
@@ -16,7 +15,9 @@ import cn.dxl.common.widget.ToastUtil;
import cn.proxgrind.com.DevCallback;
import cn.proxgrind.com.UsbSerialControl;
import cn.rrg.rdv.R;
+import cn.rrg.rdv.util.Commons;
import cn.rrg.rdv.util.Paths;
+import cn.rrg.rdv.util.Proxmark3Installer;
public class PM3FlasherMainActivity extends BaseActivity implements DevCallback {
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/FileListActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/FileListActivity.java
index 8ec4e0f6..314e6824 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/FileListActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/tools/FileListActivity.java
@@ -26,7 +26,6 @@ import cn.rrg.rdv.R;
import cn.rrg.rdv.activities.main.BaseActivity;
import cn.rrg.rdv.binder.FileInfoBinder;
import cn.rrg.rdv.javabean.FileBean;
-import cn.rrg.rdv.util.DumpUtils;
import me.drakeet.multitype.Items;
import me.drakeet.multitype.MultiTypeAdapter;
@@ -81,7 +80,7 @@ public abstract class FileListActivity extends BaseActivity {
rvDumpList.setAdapter(multiTypeAdapter);
workDialog = new AlertDialog.Builder(context)
- .setTitle(R.string.woring)
+ .setTitle(R.string.working)
.setView(View.inflate(context, R.layout.dialog_working_msg, null))
.create();
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java
index 46694b6c..1b854fa8 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java
@@ -27,6 +27,7 @@ import cn.rrg.rdv.R;
import cn.rrg.rdv.activities.main.BaseActivity;
import cn.rrg.rdv.util.Commons;
import cn.rrg.rdv.util.Paths;
+import cn.rrg.rdv.util.Proxmark3Installer;
import cn.rrg.rdv.widget.MaterialAlertDialog;
import cn.rrg.rdv.widget.ProDialog1;
@@ -89,6 +90,10 @@ public class Proxmark3FirmwareActivity extends BaseActivity implements DevCallba
proDialog1 = new ProDialog1(context);
+ if (!Commons.isElfDecompressed()) {
+ Proxmark3Installer.installIfNeed(this, null);
+ }
+
initViews();
initActions();
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3NewTerminalInitActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3NewTerminalInitActivity.java
new file mode 100644
index 00000000..c8d010e7
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3NewTerminalInitActivity.java
@@ -0,0 +1,35 @@
+package cn.rrg.rdv.activities.tools;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+
+import com.termux.app.TermuxActivity;
+
+import cn.rrg.rdv.activities.main.BaseActivity;
+import cn.rrg.rdv.util.Commons;
+import cn.rrg.rdv.util.Proxmark3Installer;
+
+public class Proxmark3NewTerminalInitActivity extends BaseActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (Commons.isPM3ClientDecompressed()) {
+ go();
+ } else {
+ Proxmark3Installer.installIfNeed(this, new Runnable() {
+ @Override
+ public void run() {
+ go();
+ }
+ });
+ }
+ }
+
+ public void go() {
+ startActivity(new Intent(this, TermuxActivity.class));
+ finish();
+ }
+}
diff --git a/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java b/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java
index 6efdcc29..510a4065 100644
--- a/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java
+++ b/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java
@@ -34,6 +34,7 @@ import cn.rrg.rdv.javabean.ItemToggleBean;
import cn.rrg.rdv.javabean.TitleBean;
import cn.rrg.rdv.util.Commons;
import cn.rrg.rdv.util.Paths;
+import cn.rrg.rdv.util.Proxmark3Installer;
import cn.rrg.rdv.widget.ProDialog1;
import me.drakeet.multitype.Items;
import me.drakeet.multitype.MultiTypeAdapter;
@@ -163,25 +164,14 @@ public class MainSettingsFragment
private void pm3ResInit(ItemTextBean item) {
Activity activity = getActivity();
if (activity != null) {
- ProDialog1 proDialog1 = new ProDialog1(activity);
- proDialog1.show(getString(R.string.initializing));
- new Thread(new Runnable() {
+ Proxmark3Installer.installIfNeed(activity, new Runnable() {
@Override
public void run() {
- // move res to /data/xxxx
- new AssetsUtil(activity)
- .copyDirs(new File("pm3"), new File(Paths.TOOLS_DIRECTORY));
- proDialog1.dismiss();
showToast(getString(R.string.finished));
item.setMessage(getString(R.string.initialized));
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- multiTypeAdapter.notifyDataSetChanged();
- }
- });
+ multiTypeAdapter.notifyDataSetChanged();
}
- }).start();
+ });
}
}
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/Commons.java b/app_main/src/main/java/cn/rrg/rdv/util/Commons.java
index 8136975e..764d8501 100644
--- a/app_main/src/main/java/cn/rrg/rdv/util/Commons.java
+++ b/app_main/src/main/java/cn/rrg/rdv/util/Commons.java
@@ -8,8 +8,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
+import android.os.Build;
import android.widget.RadioGroup;
+import com.termux.app.TermuxService;
+
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
@@ -18,6 +21,7 @@ import java.util.Set;
import cn.dxl.common.util.AppUtil;
import cn.dxl.common.util.FileUtils;
+import cn.dxl.common.util.LogUtils;
import cn.rrg.rdv.R;
import cn.rrg.rdv.activities.tools.DumpEditActivity;
import cn.rrg.rdv.application.Properties;
@@ -188,7 +192,7 @@ public class Commons {
}
public static boolean isPM3ResInitialled() {
- File pm3Path = new File(Paths.PM3_DIRECTORY + File.separator + "resources");
+ File pm3Path = new File(TermuxService.HOME_PATH + File.separator + Paths.PM3_PATH);
String[] list = pm3Path.list();
return list != null && list.length > 0;
}
@@ -222,4 +226,35 @@ public class Commons {
.putStringSet(Properties.k_common_rw_keyfile_selected, old)
.apply();
}
+
+ public static String getABISupported(boolean has64So) {
+ if (has64So && Build.SUPPORTED_64_BIT_ABIS.length > 0)
+ return Build.SUPPORTED_64_BIT_ABIS[0];
+ if (!has64So && Build.SUPPORTED_32_BIT_ABIS.length > 0)
+ return Build.SUPPORTED_32_BIT_ABIS[0];
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0)
+ return Build.SUPPORTED_64_BIT_ABIS[0];
+ if (Build.SUPPORTED_32_BIT_ABIS.length > 0)
+ return Build.SUPPORTED_32_BIT_ABIS[0];
+ return null;
+ }
+
+ public static String getPM3ClientPath() {
+ return TermuxService.HOME_PATH +
+ File.separator +
+ Paths.PM3_PATH +
+ File.separator +
+ Paths.PM3_PATH +
+ "_" +
+ getABISupported(true);
+ }
+
+ public static boolean isPM3ClientDecompressed() {
+ return new File(getPM3ClientPath()).exists();
+ }
+
+ public static boolean isElfDecompressed() {
+ return new File(Paths.PM3_IMAGE_OS_FILE).exists() &&
+ new File(Paths.PM3_IMAGE_BOOT_FILE).exists();
+ }
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/Paths.java b/app_main/src/main/java/cn/rrg/rdv/util/Paths.java
index 92b018a0..bad6811c 100644
--- a/app_main/src/main/java/cn/rrg/rdv/util/Paths.java
+++ b/app_main/src/main/java/cn/rrg/rdv/util/Paths.java
@@ -2,6 +2,10 @@ package cn.rrg.rdv.util;
import android.os.Environment;
+import com.termux.app.TermuxService;
+
+import java.io.File;
+
public interface Paths {
String EXTERNAL_STORAGE_DIRECTORY = Environment.getExternalStorageDirectory().getPath();
@@ -12,7 +16,7 @@ public interface Paths {
String HARDNESTED_PATH = "hardnested";
String TABLES_PATH = "tables";
String LOG_PATH = "log";
- String PM3_PATH = "pm3";
+ String PM3_PATH = "proxmark3";
String COMMON_PATH = "common";
String PN53X_PATH = "pn53x";
String DRIVER_PATH = "driver";
@@ -56,8 +60,8 @@ public interface Paths {
//PM3 Easy Button
String PM3_CMD_FILE = PM3_DIRECTORY + "/" + DEFAULT_CMD_NAME;
// PM3 Image
- String PM3_IMAGE_BOOT_FILE = Paths.PM3_DIRECTORY + "/" + PM3_BOOT_FILE_NAME;
- String PM3_IMAGE_OS_FILE = Paths.PM3_DIRECTORY + "/" + PM3_OS_FILE_NAME;
+ String PM3_IMAGE_BOOT_FILE = TermuxService.HOME_PATH + File.separator + PM3_PATH + File.separator + PM3_BOOT_FILE_NAME;
+ String PM3_IMAGE_OS_FILE = TermuxService.HOME_PATH + File.separator + PM3_PATH + File.separator + PM3_OS_FILE_NAME;
String PN53X_FORWARD_O = PN53X_DIRRECTORY + "/" + "pn53x_forward_o.txt";
String PN53X_FORWARD_E = PN53X_DIRRECTORY + "/" + "pn53x_forward_e.txt";
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java b/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java
new file mode 100644
index 00000000..2f9ca932
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java
@@ -0,0 +1,83 @@
+package cn.rrg.rdv.util;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.system.ErrnoException;
+import android.system.Os;
+
+import com.termux.app.TermuxService;
+
+import java.io.File;
+
+import cn.dxl.common.util.AssetsUtil;
+import cn.rrg.rdv.R;
+
+public class Proxmark3Installer {
+
+ /**
+ * Install the pm3 client and resource if need!
+ *
+ * @param activity Current activity
+ * @param whenDone call when task finish.
+ */
+ public static void installIfNeed(Activity activity, Runnable whenDone) {
+ final ProgressDialog progress = new ProgressDialog(activity);
+ progress.setTitle(activity.getString(com.termux.R.string.bootstrap_installer_body));
+ progress.setCancelable(false);
+ progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ progress.show();
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ String zipName = "proxmark3.zip";
+ String zipFile = TermuxService.HOME_PATH + File.separator + zipName;
+ new AssetsUtil(activity).copyFile(zipName, zipFile);
+ try {
+ ZipUtils.UnZipFolder(zipFile, TermuxService.HOME_PATH, new ZipUtils.Progress() {
+ @Override
+ public void onProgress(int max, int current, String file) {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ progress.setMax(max);
+ progress.setProgress(current);
+ }
+ });
+ }
+ });
+ } catch (Exception e) {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ new AlertDialog.Builder(activity)
+ .setTitle(R.string.error)
+ .setMessage(e.getMessage())
+ .show();
+ activity.runOnUiThread(() -> {
+ try {
+ progress.dismiss();
+ } catch (RuntimeException e) {
+ // Activity already dismissed - ignore.
+ }
+ });
+ if (whenDone != null)
+ whenDone.run();
+ }
+ });
+ e.printStackTrace();
+ }
+ activity.runOnUiThread(() -> {
+ try {
+ progress.dismiss();
+ } catch (RuntimeException e) {
+ // Activity already dismissed - ignore.
+ }
+ });
+ if (whenDone != null)
+ activity.runOnUiThread(whenDone);
+ }
+ }).start();
+ }
+}
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java b/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java
new file mode 100644
index 00000000..c6c67ede
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java
@@ -0,0 +1,228 @@
+package cn.rrg.rdv.util;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * @author: lijuan
+ * @description: 解压ZIP文件
+ * @date: 2017-04-11
+ * @time: 09:22
+ */
+public class ZipUtils {
+ public static final String TAG = "ZIP";
+
+ public interface Progress {
+ void onProgress(int max, int current, String file);
+ }
+
+ public ZipUtils() {
+
+ }
+
+ public static int getSize(String zipFileString) {
+ try (ZipFile file = new ZipFile(zipFileString)) {
+ return file.size();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ /**
+ * 解压zip到指定的路径
+ *
+ * @param zipFileString ZIP的名称
+ * @param outPathString 要解压缩路径
+ * @throws Exception
+ */
+ public static void UnZipFolder(String zipFileString, String outPathString, Progress progress) throws Exception {
+ ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
+ ZipEntry zipEntry;
+ String szName = "";
+ int size = getSize(zipFileString);
+ int current = 0;
+ while ((zipEntry = inZip.getNextEntry()) != null) {
+ szName = zipEntry.getName();
+ if (zipEntry.isDirectory()) {
+ //获取部件的文件夹名
+ szName = szName.substring(0, szName.length() - 1);
+ File folder = new File(outPathString + File.separator + szName);
+ folder.mkdirs();
+ } else {
+ // Log.e(TAG, outPathString + File.separator + szName);
+ File file = new File(outPathString + File.separator + szName);
+ if (!file.exists()) {
+ // Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
+ // 获取文件的输出流
+ FileOutputStream out = new FileOutputStream(file);
+ int len;
+ byte[] buffer = new byte[1024 * 1024];
+ // 读取(字节)字节到缓冲区
+ while ((len = inZip.read(buffer)) != -1) {
+ // 从缓冲区(0)位置写入(字节)字节
+ out.write(buffer, 0, len);
+ out.flush();
+ }
+ out.close();
+ if (progress != null) {
+ progress.onProgress(size, ++current, file.getPath());
+ }
+ }
+ }
+ inZip.close();
+ }
+
+ public static void UnZipFolder(String zipFileString, String outPathString, String szName) throws Exception {
+ ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
+ ZipEntry zipEntry;
+ while ((zipEntry = inZip.getNextEntry()) != null) {
+ //szName = zipEntry.getName();
+ if (zipEntry.isDirectory()) {
+ //获取部件的文件夹名
+ szName = szName.substring(0, szName.length() - 1);
+ File folder = new File(outPathString + File.separator + szName);
+ folder.mkdirs();
+ } else {
+ // Log.e(TAG, outPathString + File.separator + szName);
+ File file = new File(outPathString + File.separator + szName);
+ if (!file.exists()) {
+ // Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
+ // 获取文件的输出流
+ FileOutputStream out = new FileOutputStream(file);
+ int len;
+ byte[] buffer = new byte[1024];
+ // 读取(字节)字节到缓冲区
+ while ((len = inZip.read(buffer)) != -1) {
+ // 从缓冲区(0)位置写入(字节)字节
+ out.write(buffer, 0, len);
+ out.flush();
+ }
+ out.close();
+ }
+ }
+ inZip.close();
+ }
+
+ /**
+ * 压缩文件和文件夹
+ *
+ * @param srcFileString 要压缩的文件或文件夹
+ * @param zipFileString 解压完成的Zip路径
+ * @throws Exception
+ */
+ public static void ZipFolder(String srcFileString, String zipFileString) throws Exception {
+ //创建ZIP
+ ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(zipFileString));
+ //创建文件
+ File file = new File(srcFileString);
+ //压缩
+ ZipFiles(file.getParent() + File.separator, file.getName(), outZip);
+ //完成和关闭
+ outZip.finish();
+ outZip.close();
+ }
+
+ /**
+ * 压缩文件
+ *
+ * @param folderString
+ * @param fileString
+ * @param zipOutputSteam
+ * @throws Exception
+ */
+ private static void ZipFiles(String folderString, String fileString, ZipOutputStream zipOutputSteam) throws Exception {
+ if (zipOutputSteam == null)
+ return;
+ File file = new File(folderString + fileString);
+ if (file.isFile()) {
+ ZipEntry zipEntry = new ZipEntry(fileString);
+ FileInputStream inputStream = new FileInputStream(file);
+ zipOutputSteam.putNextEntry(zipEntry);
+ int len;
+ byte[] buffer = new byte[4096];
+ while ((len = inputStream.read(buffer)) != -1) {
+ zipOutputSteam.write(buffer, 0, len);
+ }
+ zipOutputSteam.closeEntry();
+ } else {
+ //文件夹
+ String fileList[] = file.list();
+ //没有子文件和压缩
+ if (fileList.length <= 0) {
+ ZipEntry zipEntry = new ZipEntry(fileString + File.separator);
+ zipOutputSteam.putNextEntry(zipEntry);
+ zipOutputSteam.closeEntry();
+ }
+ //子文件和递归
+ for (int i = 0; i < fileList.length; i++) {
+ ZipFiles(folderString, fileString + File.separator + fileList[i], zipOutputSteam);
+ }
+ }
+ }
+
+ /**
+ * 返回zip的文件输入流
+ *
+ * @param zipFileString zip的名称
+ * @param fileString ZIP的文件名
+ * @return InputStream
+ * @throws Exception
+ */
+ public static InputStream UpZip(String zipFileString, String fileString) throws Exception {
+ ZipFile zipFile = new ZipFile(zipFileString);
+ ZipEntry zipEntry = zipFile.getEntry(fileString);
+ return zipFile.getInputStream(zipEntry);
+ }
+
+ /**
+ * 返回ZIP中的文件列表(文件和文件夹)
+ *
+ * @param zipFileString ZIP的名称
+ * @param bContainFolder 是否包含文件夹
+ * @param bContainFile 是否包含文件
+ * @return
+ * @throws Exception
+ */
+ public static List GetFileList(String zipFileString, boolean bContainFolder, boolean bContainFile) throws Exception {
+ List fileList = new ArrayList();
+ ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
+ ZipEntry zipEntry;
+ String szName = "";
+ while ((zipEntry = inZip.getNextEntry()) != null) {
+ szName = zipEntry.getName();
+ if (zipEntry.isDirectory()) {
+ // 获取部件的文件夹名
+ szName = szName.substring(0, szName.length() - 1);
+ File folder = new File(szName);
+ if (bContainFolder) {
+ fileList.add(folder);
+ }
+ } else {
+ File file = new File(szName);
+ if (bContainFile) {
+ fileList.add(file);
+ }
+ }
+ }
+ inZip.close();
+ return fileList;
+ }
+}
diff --git a/app_main/src/main/res/values-en/strings.xml b/app_main/src/main/res/values-en/strings.xml
index c3295da7..ea9ae0c9 100644
--- a/app_main/src/main/res/values-en/strings.xml
+++ b/app_main/src/main/res/values-en/strings.xml
@@ -241,7 +241,7 @@
Data Dwonload
Data Upload
Data Clear
- Working
+ Working
No data to save!
Failed to create a chameleon-specific key file!
finish
@@ -300,5 +300,6 @@
Custom firmware
Select BootRom
Select FullImage
+ Will use TERMUX implement UI
\ No newline at end of file
diff --git a/app_main/src/main/res/values-zh/strings.xml b/app_main/src/main/res/values-zh/strings.xml
index c813b69d..cd73a149 100644
--- a/app_main/src/main/res/values-zh/strings.xml
+++ b/app_main/src/main/res/values-zh/strings.xml
@@ -237,7 +237,7 @@
数据下载
数据上载
数据清除
- 工作中
+ 工作中
无可用数据可以被保存!
创建变色龙专用的密钥文件失败!
完成
@@ -306,5 +306,6 @@
自定义固件
选择引导器
选择系统固件
+ 将会使用TERMUX实现终端视图
\ No newline at end of file
diff --git a/app_main/src/main/res/values/strings.xml b/app_main/src/main/res/values/strings.xml
index fc92f6fc..2b49e283 100644
--- a/app_main/src/main/res/values/strings.xml
+++ b/app_main/src/main/res/values/strings.xml
@@ -240,7 +240,7 @@
Data Dwonload
Data Upload
Data Clear
- Working
+ Working
No data to save!
Failed to create a chameleon-specific key file!
finish
@@ -299,5 +299,6 @@
Custom firmware
Select BootRom
Select FullImage
+ Will use TERMUX implement UI
\ No newline at end of file