diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..10e76ef0
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "pm3rdv4rrg/src/main/cpp/proxmark3"]
+ path = pm3rdv4rrg/src/main/cpp/proxmark3
+ url = https://github.com/xianglin1998/proxmark3.git
+[submodule "pm3rdv4rrg/src/main/cpp/bzip2"]
+ path = pm3rdv4rrg/src/main/cpp/bzip2
+ url = http://sourceware.org/git/bzip2.git
diff --git a/README.md b/README.md
index 26ab45f2..78ca8809 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,19 @@ Download and flash [Compiled FW 12 August](https://www.dropbox.com/s/416lsrqpr2l
- CMAKE: 3.10
- NDK: 20.0.5594570
+## How to build?
+The RFIDTools have some gitsubmodule
+
+Get the source from GitHub:
+
+ git clone https://github.com/xianglin1998/RFIDtools RFIDtools
+ cd RFIDtools
+ git submodule init
+ git submodule update
+
+
+After clone and init submodule, you can use your AndroidStudio open this project.
+
## App core implementation
Comunication: LocalSocket & LocalServerSocket(Android)
diff --git a/app_main/build.gradle b/app_main/build.gradle
index 20ff5ded..6cc0a466 100644
--- a/app_main/build.gradle
+++ b/app_main/build.gradle
@@ -8,8 +8,8 @@ android {
minSdkVersion 24
targetSdkVersion 28
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
- versionCode 24
- versionName "1.4.6 Termux"
+ versionCode 25
+ versionName "1.4.7 Termux and SimpleView"
}
buildTypes {
release {
@@ -66,8 +66,8 @@ dependencies {
implementation project(':chameleon')
implementation project(':communication')
- testImplementation 'junit:junit:4.12'
implementation project(path: ':pm3flasher')
+ implementation project(':pm3rdv4rrg')
implementation project(path: ':xmodem')
// The dep from TERMUX(A FullTerminal implements.)
diff --git a/app_main/src/main/AndroidManifest.xml b/app_main/src/main/AndroidManifest.xml
index 317fc3b7..3d84091b 100644
--- a/app_main/src/main/AndroidManifest.xml
+++ b/app_main/src/main/AndroidManifest.xml
@@ -77,7 +77,8 @@
-
+
+
diff --git a/app_main/src/main/assets/cmd.json b/app_main/src/main/assets/cmd.json
index 5db010c1..718a1d88 100644
--- a/app_main/src/main/assets/cmd.json
+++ b/app_main/src/main/assets/cmd.json
@@ -13,7 +13,8 @@
{"name": "Mifare 1k Dump", "cmd": "hf mf dump"},
{"name": "Read iclass", "cmd": "hf iclass reader"},
{"name": "Dump iclass legacy", "cmd": "hf iclass dump k afa785a7dab33378"},
- {"name": "Hardware Test", "cmd": "hw tune"}
+ {"name": "Hardware Test", "cmd": "hw tune"},
+ {"name": "Hardware Version", "cmd": "hw version"},
],
[
{"name" : "High Frequency"},
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 d0684445..c646c323 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
@@ -12,7 +12,7 @@ import androidx.appcompat.app.AlertDialog;
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.activities.proxmark3.rdv4_rrg.Proxmark3NewTerminalInitActivity;
import cn.rrg.rdv.callback.ConnectFailedCtxCallback;
import cn.rrg.rdv.models.AbstractDeviceModel;
import cn.rrg.rdv.models.Proxmark3Rdv4SppModel;
@@ -53,7 +53,7 @@ public class Proxmark3Rdv4RRGConnectActivity
@Override
public String getConnectingMsg() {
- return getString(R.string.tips_view_use_termux);
+ return getString(R.string.tips_plz_wait);
}
@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 f5d5c3fa..d802d25e 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
@@ -1,7 +1,6 @@
package cn.rrg.rdv.activities.main;
import android.app.AlertDialog;
-import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
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 e130e70f..996837d5 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
@@ -12,23 +12,19 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import android.util.Log;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import java.util.ArrayList;
-
-import cn.dxl.common.interfaces.OnTouchListener;
import cn.dxl.common.util.DisplayUtil;
import cn.dxl.common.util.HexUtil;
import cn.dxl.common.util.LanguageUtil;
+import cn.dxl.common.util.LogUtils;
import cn.dxl.common.util.StatusBarUtil;
import cn.dxl.common.widget.ToastUtil;
import cn.dxl.common.util.VibratorUtils;
import cn.dxl.mifare.NfcTagListenUtils;
import cn.dxl.mifare.StdMifareIntent;
import cn.rrg.rdv.R;
-import cn.rrg.rdv.application.Properties;
import cn.rrg.rdv.util.Commons;
/**
@@ -95,9 +91,6 @@ public abstract class BaseActivity
protected void onPause() {
Log.d(LOG_TAG, "Act is pause");
super.onPause();
- /*
- * 在这里解注册各大前台事件!
- * */
mStdMfUtil.disableForegroundDispatch(this);
}
@@ -105,10 +98,9 @@ public abstract class BaseActivity
protected void attachBaseContext(Context newBase) {
String language = Commons.getLanguage();
if (language.equals("auto")) {
- //如果value = auto,则设置为跟随系统!
super.attachBaseContext(newBase);
} else {
- //否则国际化!
+ LogUtils.d("New app language: " + language);
super.attachBaseContext(LanguageUtil.setAppLanguage(newBase, language));
}
}
@@ -125,16 +117,12 @@ public abstract class BaseActivity
@Override
protected void onNewIntent(Intent intent) {
- //有新的意图时会启动
Bundle data = intent.getExtras();
if (data != null) {
Tag tag = data.getParcelable(NfcAdapter.EXTRA_TAG);
if (tag != null) {
- //存入全局操作域!
NfcTagListenUtils.setTag(tag);
- //显示 UID!
ToastUtil.show(this, getString(R.string.tips_uid) + HexUtil.toHexString(tag.getId()), true);
- //震动一下!
VibratorUtils.runOneAsDelay(context, 1000);
NfcTagListenUtils.notifyOnNewTag(tag);
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3ConsoleActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3ConsoleActivity.java
new file mode 100644
index 00000000..3be93396
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3ConsoleActivity.java
@@ -0,0 +1,157 @@
+package cn.rrg.rdv.activities.proxmark3.rdv4_rrg;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.CompoundButton;
+
+import androidx.annotation.Nullable;
+
+import java.io.File;
+
+import cn.dxl.common.util.FileUtils;
+import cn.rrg.console.define.ICommandTools;
+import cn.rrg.console.define.ICommandType;
+import cn.rrg.freo.IORedirector;
+import cn.rrg.rdv.R;
+import cn.rrg.rdv.activities.tools.BaseConsoleActivity;
+import cn.rrg.rdv.implement.EntryICommandType;
+import cn.rrg.rdv.util.Paths;
+
+public abstract class Proxmark3ConsoleActivity
+ extends BaseConsoleActivity
+ implements View.OnClickListener,
+ CompoundButton.OnCheckedChangeListener {
+
+ //滞留一个视图实例,可用如GUI,子控件实现!
+ protected View guiView = null;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ //重定向!
+ IORedirector.setStdEO(Paths.PM3_FORWARD_O, IORedirector.STD_OUT);
+ IORedirector.setStdEO(Paths.PM3_FORWARD_E, IORedirector.STD_ERR);
+ IORedirector.setStdIN(Paths.COMMON_FORWARD_I);
+ }
+ }).start();
+
+ //父类先初初始化!
+ super.onCreate(savedInstanceState);
+
+ //默认关闭错误消息输出区域(用不上...)
+ ckBoxOpenOutputError.setChecked(false);
+ //覆盖父类的停止按钮点击实例
+ btnStop.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.btnStop) {//判断当前是否有客户端可终止的任务在执行,是的话则终止!
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ //TODO 此处进行IO,模拟键盘输入!
+ stopPM3Client4KeyBorad();
+ }
+ }).start();
+ }
+ }
+
+ //通过键盘输入结束任务!
+ protected void stopPM3Client4KeyBorad() {
+ FileUtils.writeString(new File(Paths.COMMON_FORWARD_I), "\n", true);
+ }
+
+ @Override
+ protected void onDestroy() {
+ //非常有必要进行相关的结束操作!
+ stopPM3Client4KeyBorad();
+ mCMD.stopExecute();
+ super.onDestroy();
+ }
+
+ /*
+ * 重写视图实例寻找,方便进行控制!
+ * */
+ @Override
+ public T findViewById(int id) {
+ T view = super.findViewById(id);
+ return view != null ? view : guiView != null ? guiView.findViewById(id) : null;
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ //don't need process!!!
+ }
+
+ @Override
+ protected View getCommandGUI() {
+ return guiView;
+ }
+
+ @Override
+ protected File initOutTarget() {
+ return new File(Paths.PM3_FORWARD_O);
+ }
+
+ @Override
+ protected File initErrTarget() {
+ return new File(Paths.PM3_FORWARD_E);
+ }
+
+ @Override
+ protected int startTest(ICommandTools cmd) {
+ mDefaultCMD = "help";
+ if (edtInputCmd.getText().toString().length() > 0) {
+ mDefaultCMD = edtInputCmd.getText().toString();
+ }
+ //此处做出多行执行优化!
+ int ret = -2;
+ //优化,如果是多行命令的操作!
+ if (mDefaultCMD.contains("\n")) {
+ //包含换行,则当作多行处理!
+ String[] cmds = mDefaultCMD.split("\n");
+ Log.d(LOG_TAG, "警告,当前执行的是多行处理操作!");
+ for (String c : cmds) {
+ Log.d(LOG_TAG, "当前执行的命令: " + c);
+ mCMD.startExecute(c);
+ }
+ return ret;
+ } else {
+ //直接执行命令并且在执行命令完成后进行回调!
+ ret = cmd.startExecute(mDefaultCMD);
+ }
+ return ret;
+ }
+
+ @Override
+ protected void onNewOutLine(String line) {
+ }
+
+ @Override
+ protected void onNewErrLine(String line) {
+ }
+
+ @Override
+ protected ICommandType initType() {
+ return new EntryICommandType();
+ }
+
+ @Override
+ protected void onTestEnd() {
+ }
+
+ @Override
+ protected boolean isTesting() {
+ return super.isTesting();
+ }
+
+ @Override
+ protected void stopTest() {
+ //super.stopTest();
+ //TODO 无必要停止PM3的底层线程!
+ }
+}
\ No newline at end of file
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java
new file mode 100644
index 00000000..adcf4048
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java
@@ -0,0 +1,112 @@
+package cn.rrg.rdv.activities.proxmark3.rdv4_rrg;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.RadioGroup;
+
+import androidx.annotation.Nullable;
+
+import com.termux.app.TermuxActivity;
+
+import cn.dxl.common.widget.ToastUtil;
+import cn.rrg.rdv.R;
+import cn.rrg.rdv.activities.main.BaseActivity;
+import cn.rrg.rdv.activities.main.PM3FlasherMainActivity;
+import cn.rrg.rdv.util.Commons;
+import cn.rrg.rdv.util.Proxmark3Installer;
+
+public class Proxmark3NewTerminalInitActivity extends BaseActivity {
+
+ private RadioGroup rdoGroupTerminalSelect;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.act_pm3_terminal_init);
+
+ rdoGroupTerminalSelect = findViewById(R.id.rdoGroupTerminalSelect);
+ rdoGroupTerminalSelect.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ switch (checkedId) {
+ case R.id.rdoBtnFullTerminal:
+ Commons.setTerminalType(0);
+ break;
+ case R.id.rdoBtnSimpleTerminal:
+ Commons.setTerminalType(1);
+ break;
+ }
+ }
+ });
+ rdoGroupTerminalSelect.check(checkTerminalType());
+
+ findViewById(R.id.btnFwFlash).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startActivity(new Intent(activity, PM3FlasherMainActivity.class));
+ }
+ });
+
+ findViewById(R.id.btnGoToTermux).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (rdoGroupTerminalSelect.getCheckedRadioButtonId() == -1) {
+ ToastUtil.show(context, getString(R.string.tips_terminal_select_like), false);
+ return;
+ }
+ if (Commons.isPM3ClientDecompressed()) {
+ go();
+ } else {
+ Proxmark3Installer.installIfNeed(activity, new Runnable() {
+ @Override
+ public void run() {
+ go();
+ }
+ });
+ }
+ }
+ });
+
+ CheckBox box = findViewById(R.id.ckBoxAutoGoTermux);
+ box.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ Commons.setAutoGoToTerminal(isChecked);
+ }
+ });
+ box.setChecked(Commons.getAutoGoToTerminal());
+
+ // Must have init pm3 client and check auto go and have the terminal type selected!
+ if (Commons.getAutoGoToTerminal()
+ && Commons.isPM3ClientDecompressed()
+ && Commons.getTerminalType() != -1) {
+ go();
+ }
+ }
+
+ public void go() {
+ if (Commons.getTerminalType() == 0) {
+ startActivity(new Intent(this, TermuxActivity.class));
+ } else {
+ startActivity(new Intent(this, Proxmark3Rdv4RRGRedTeamConsoleActivity.class));
+ }
+ finish();
+ }
+
+ private int checkTerminalType() {
+ switch (Commons.getTerminalType()) {
+ case -1:
+ default:
+ return -1;
+
+ case 0:
+ return R.id.rdoBtnFullTerminal;
+
+ case 1:
+ return R.id.rdoBtnSimpleTerminal;
+ }
+ }
+}
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3Rdv4RRGConsoleActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3Rdv4RRGConsoleActivity.java
new file mode 100644
index 00000000..ae737546
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3Rdv4RRGConsoleActivity.java
@@ -0,0 +1,14 @@
+package cn.rrg.rdv.activities.proxmark3.rdv4_rrg;
+
+import cn.rrg.console.define.ICommandTools;
+import cn.rrg.natives.Proxmark3RRGRdv4Tools;
+
+public class Proxmark3Rdv4RRGConsoleActivity
+ extends Proxmark3ConsoleActivity {
+
+ @Override
+ protected ICommandTools initCMD() {
+ //替换为rdv4的工具类!
+ return new Proxmark3RRGRdv4Tools();
+ }
+}
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3Rdv4RRGRedTeamConsoleActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3Rdv4RRGRedTeamConsoleActivity.java
new file mode 100644
index 00000000..4d989748
--- /dev/null
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3Rdv4RRGRedTeamConsoleActivity.java
@@ -0,0 +1,209 @@
+package cn.rrg.rdv.activities.proxmark3.rdv4_rrg;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import com.termux.app.TermuxService;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import cn.rrg.freo.IORedirector;
+import cn.rrg.rdv.R;
+import cn.rrg.rdv.adapter.EasyBtnAdapter;
+import cn.rrg.rdv.javabean.EasyCMDEntry;
+import cn.rrg.rdv.util.EasyBtnUtil;
+import cn.dxl.common.widget.DoubleInputDialog;
+import cn.dxl.common.util.ArrayUtils;
+import cn.dxl.common.widget.ToastUtil;
+import cn.dxl.common.util.ViewUtil;
+import cn.rrg.rdv.util.Paths;
+
+public class Proxmark3Rdv4RRGRedTeamConsoleActivity
+ extends Proxmark3Rdv4RRGConsoleActivity {
+
+ private GridView gridViewShowEasyButton;
+ private EasyBtnAdapter adapter;
+ private List easyCMDEntries = new ArrayList<>();
+
+ //构造一个简单的对话框,用于提示需要的操作!
+ private AlertDialog operaDialog;
+ //显示添加按钮!
+ private TextView txtAddEasyBtn;
+ //缓存当前要操作的项目!
+ private int operaPosition;
+ //配置文件操作工具
+ private EasyBtnUtil easyBtnUtil = new EasyBtnUtil();
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ btnGui.setText(getString(R.string.console_dynamic_btn));
+ //隐藏不需要的区域!
+ skBarConsoleViewScale.setProgress(10);
+ //设置pm3的输入提示
+ edtInputCmd.setHint(getString(R.string.pm3_hint));
+
+ //不能让用户关闭通讯!
+ btnStop.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ stopPM3Client4KeyBorad();
+ }
+ });
+
+ initViews();
+ initActions();
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // 更改工作目录!
+ IORedirector.chdir(TermuxService.HOME_PATH + File.separator + Paths.PM3_PATH);
+ }
+ }).start();
+ }
+
+ private void initViews() {
+ //先初始化视图!
+ guiView = ViewUtil.inflate(this, R.layout.easy_button_container);
+
+ gridViewShowEasyButton = findViewById(R.id.gridViewShowEasyButton);
+ adapter = new EasyBtnAdapter(this, R.layout.item_easy__btn, easyCMDEntries);
+ gridViewShowEasyButton.setAdapter(adapter);
+
+ //添加数据!
+ EasyCMDEntry[] buttons = getCMDs();
+ if (buttons != null) {
+ easyCMDEntries.addAll(Arrays.asList(getCMDs()));
+ adapter.notifyDataSetChanged();
+ }
+ txtAddEasyBtn = findViewById(R.id.txtAddEasyBtn);
+ }
+
+ private void initActions() {
+ //列表项单击时执行相应的命令!
+ gridViewShowEasyButton.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ //点击了对应项时,取出对应的实体,进行命令发送!
+ EasyCMDEntry entry = easyCMDEntries.get(position);
+ if (entry != null) {
+ String cmd = entry.getCommand();
+ if (cmd != null) {
+ //先提交命令到输入框
+ putCMDAndClosePop(cmd);
+ }
+ }
+ }
+ });
+ //列表项长按时显示相关的操作项!
+ gridViewShowEasyButton.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
+ operaDialog.show();
+ operaPosition = position;
+ return true;
+ }
+ });
+ //构建一个用于显示操作的对话框!
+ operaDialog = new AlertDialog.Builder(this).setItems(new String[]{getString(R.string.delete), getString(R.string.modify)}, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final EasyCMDEntry entry = easyCMDEntries.get(operaPosition);
+ if (which == 0) {
+ new AlertDialog.Builder(context).setTitle(R.string.warning).setMessage(getString(R.string.enter_delete)
+ + "\n\nItem name: " + entry.getCmdName())
+ .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ //做出删除操作!
+ easyCMDEntries.remove(operaPosition);
+ adapter.notifyDataSetChanged();
+ //TODO 本地配置删除!
+ if (easyBtnUtil.deleteButton(0, operaPosition)) {
+ ToastUtil.show(context, getString(R.string.success), false);
+ } else {
+ ToastUtil.show(context, getString(R.string.failed), false);
+ }
+ }
+ }).setNegativeButton(getString(R.string.no), null).show();
+ } else {
+ //做出修改操作,先取出原来的数据!
+ DoubleInputDialog inputDialog = new DoubleInputDialog(context);
+ inputDialog.setTitle(R.string.button_edit);
+ inputDialog.getHint1().setText(R.string.title_input);
+ inputDialog.getHint2().setText(R.string.command_input);
+ //设置到视图上!
+ inputDialog.getEdtInput1().setText(entry.getCmdName());
+ inputDialog.getEdtInput2().setText(entry.getCommand());
+ //然后设置操作回调并且显示!
+ inputDialog.setSaveListener(new DoubleInputDialog.OnSaveListener() {
+ @Override
+ public void onSave(String[] content) {
+ //操作成功,进行内存更新!
+ entry.setCmdName(content[0]);
+ entry.setCommand(content[1]);
+ adapter.notifyDataSetChanged();
+ //TODO 然后进行本地更新!
+ if (easyBtnUtil.updateButton(0, operaPosition, entry.getCmdName(), entry.getCommand())) {
+ //现在的话已经更新成功
+ ToastUtil.show(context, getString(R.string.success), false);
+ } else {
+ ToastUtil.show(context, getString(R.string.failed), false);
+ }
+ }
+ }).show();
+ }
+ }
+ }).create();
+ //设置添加按钮的动作!
+ txtAddEasyBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //做出增加操作,构建一个实体用于保存!
+ EasyCMDEntry entry = new EasyCMDEntry();
+ DoubleInputDialog inputDialog = new DoubleInputDialog(context);
+ inputDialog.setTitle(R.string.btn_add);
+ inputDialog.getHint1().setText(R.string.title_input);
+ inputDialog.getHint2().setText(R.string.command_input);
+ //然后设置操作回调并且显示!
+ inputDialog.setSaveListener(new DoubleInputDialog.OnSaveListener() {
+ @Override
+ public void onSave(String[] content) {
+ //操作成功,进行内存更新!
+ entry.setCmdName(content[0]);
+ entry.setCommand(content[1]);
+ easyCMDEntries.add(entry);
+ adapter.notifyDataSetChanged();
+ //TODO 然后进行本地更新!
+ if (easyBtnUtil.inertButton(0, entry.getCmdName(), entry.getCommand())) {
+ //现在的话已经更新成功
+ ToastUtil.show(context, getString(R.string.success), false);
+ } else {
+ ToastUtil.show(context, getString(R.string.failed), false);
+ }
+ }
+ }).show();
+ }
+ });
+ }
+
+ private EasyCMDEntry[] getCMDs() {
+ //默认先拿0组的按钮,以后做多组分页的时候再做其他组的处理!
+ List btns = easyBtnUtil.getButtons(0);
+ if (btns == null) return null;
+ return ArrayUtils.list2Arr(btns);
+ }
+}
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
deleted file mode 100644
index 7f96df6c..00000000
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3NewTerminalInitActivity.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package cn.rrg.rdv.activities.tools;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-
-import androidx.annotation.Nullable;
-
-import com.termux.app.TermuxActivity;
-
-import cn.rrg.rdv.R;
-import cn.rrg.rdv.activities.main.BaseActivity;
-import cn.rrg.rdv.activities.main.PM3FlasherMainActivity;
-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);
- setContentView(R.layout.act_pm3_terminal_init);
-
-
- findViewById(R.id.btnFwFlash).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(activity, PM3FlasherMainActivity.class));
- }
- });
-
- findViewById(R.id.btnGoToTermux).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (Commons.isPM3ClientDecompressed()) {
- go();
- } else {
- Proxmark3Installer.installIfNeed(activity, new Runnable() {
- @Override
- public void run() {
- go();
- }
- });
- }
- }
- });
-
- CheckBox box = findViewById(R.id.ckBoxAutoGoTermux);
- box.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- Commons.setAutoGoToTermux(isChecked);
- }
- });
-
- // Must have init pm3 client and check auto go!
- if (Commons.getAutoGoToTermux() && Commons.isPM3ClientDecompressed()) {
- go();
- }
- }
-
- public void go() {
- startActivity(new Intent(this, TermuxActivity.class));
- finish();
- }
-}
diff --git a/app_main/src/main/java/cn/rrg/rdv/application/Properties.java b/app_main/src/main/java/cn/rrg/rdv/application/Properties.java
index d7123d71..52c82227 100644
--- a/app_main/src/main/java/cn/rrg/rdv/application/Properties.java
+++ b/app_main/src/main/java/cn/rrg/rdv/application/Properties.java
@@ -15,6 +15,8 @@ public class Properties {
public static String k_app_language = "language";
//Key files select history!
public static String k_common_rw_keyfile_selected = "commonRWKeyFilesSelected";
- // Auto Goto Termux View
- public static String k_auto_goto_termux = "autoGotoTermuxView";
+ // Auto Goto terminal View
+ public static String k_auto_goto_terminal = "autoGotoTermuxView";
+ // The type of terminal
+ public static String k_terminal_type = "terminal_type";
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/fragment/base/AppMainDevicesFragment.java b/app_main/src/main/java/cn/rrg/rdv/fragment/base/AppMainDevicesFragment.java
index e24867e1..6bde7cac 100644
--- a/app_main/src/main/java/cn/rrg/rdv/fragment/base/AppMainDevicesFragment.java
+++ b/app_main/src/main/java/cn/rrg/rdv/fragment/base/AppMainDevicesFragment.java
@@ -33,7 +33,7 @@ import cn.rrg.rdv.activities.connect.PN53XUsbBulkTransferActivity;
import cn.rrg.rdv.activities.connect.Proxmark3Rdv4RRGConnectActivity;
import cn.rrg.rdv.activities.main.GeneralNfcDeviceMain;
import cn.rrg.rdv.activities.main.PN53XNfcMain;
-import cn.rrg.rdv.activities.tools.Proxmark3NewTerminalInitActivity;
+import cn.rrg.rdv.activities.proxmark3.rdv4_rrg.Proxmark3NewTerminalInitActivity;
import cn.rrg.rdv.binder.BannerImageViewBinder;
import cn.rrg.rdv.binder.DeviceInfoViewBinder;
import cn.rrg.rdv.binder.TitleTextViewBinder;
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 a38bd4a4..cc3214c2 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
@@ -19,15 +19,9 @@ import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.NumberPicker;
-
-import java.io.File;
import cn.dxl.common.util.AppUtil;
-import cn.dxl.common.util.AssetsUtil;
-import cn.dxl.common.util.LogUtils;
import cn.dxl.common.util.RestartUtils;
-import cn.dxl.common.widget.ToastUtil;
import cn.rrg.rdv.R;
import cn.rrg.rdv.binder.ItemSingleTextBean;
import cn.rrg.rdv.binder.ItemTextBinder;
@@ -37,9 +31,7 @@ import cn.rrg.rdv.javabean.ItemTextBean;
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;
@@ -115,7 +107,7 @@ public class MainSettingsFragment
languageItem.setMessage(languageTran());
items.add(languageItem);
- items.add(new TitleBean(getString(R.string.tips_res_init)));
+ items.add(new TitleBean(getString(R.string.tips_pm3_settings)));
ItemTextBean pm3Res = new ItemTextBean(getString(R.string.title_pm3_res_init)) {
@Override
@@ -127,6 +119,36 @@ public class MainSettingsFragment
pm3Res.setMessage(Commons.isPM3ResInitialled() ? getString(R.string.initialized) : getString(R.string.uninitialized));
items.add(pm3Res);
+ ItemToggleBean pm3AutoGo = new ItemToggleBean(getString(R.string.title_pm3_autogo_setting)) {
+ @Override
+ public void onChange(View view, int pos, boolean checked) {
+ Commons.setAutoGoToTerminal(checked);
+ }
+ };
+ pm3AutoGo.setSubTitle(getString(R.string.title_sub_pm3_autogo_setting));
+ pm3AutoGo.setChecked(Commons.getAutoGoToTerminal());
+ items.add(pm3AutoGo);
+
+ ItemTextBean pm3TerminalTypeItem = new ItemTextBean(getString(R.string.title_terminal_type_setting)) {
+ @Override
+ public void onClick(View view, int pos) {
+ String[] languages = new String[]{getString(R.string.item_full_terminal_view), getString(R.string.item_simple_terminal_view)};
+ new AlertDialog.Builder(view.getContext())
+ .setTitle(R.string.tips_terminal_select_like)
+ .setItems(languages, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Commons.setTerminalType(which);
+ setMessage(currentTerminalType());
+ multiTypeAdapter.notifyDataSetChanged();
+ }
+ }).show();
+ }
+ };
+ pm3TerminalTypeItem.setSubTitle(getString(R.string.title_sub_terminal_type_setting));
+ pm3TerminalTypeItem.setMessage(currentTerminalType());
+ items.add(pm3TerminalTypeItem);
+
items.add(new TitleBean(getString(R.string.other)));
ItemTextBean openSourceItem = new ItemTextBean(getString(R.string.title_open_source)) {
@@ -200,4 +222,16 @@ public class MainSettingsFragment
});
}
}
+
+ private String currentTerminalType() {
+ switch (Commons.getTerminalType()) {
+ case -1:
+ default:
+ return getString(R.string.unselected);
+ case 0:
+ return getString(R.string.item_full_terminal_view);
+ case 1:
+ return getString(R.string.item_simple_terminal_view);
+ }
+ }
}
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 dd84da73..8c258808 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
@@ -21,7 +21,6 @@ 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;
@@ -258,13 +257,30 @@ public class Commons {
new File(Paths.PM3_IMAGE_BOOT_FILE).exists();
}
- public static void setAutoGoToTermux(boolean auto) {
+ public static void setAutoGoToTerminal(boolean auto) {
getPrivatePreferences().edit()
- .putBoolean(Properties.k_auto_goto_termux, auto)
+ .putBoolean(Properties.k_auto_goto_terminal, auto)
.apply();
}
- public static boolean getAutoGoToTermux() {
- return getPrivatePreferences().getBoolean(Properties.k_auto_goto_termux, false);
+ public static boolean getAutoGoToTerminal() {
+ return getPrivatePreferences().getBoolean(Properties.k_auto_goto_terminal, false);
+ }
+
+ /**
+ * Set terminal type
+ *
+ * @param type 0 = full terminal view
+ * 1= simple terminal view
+ */
+ public static void setTerminalType(int type) {
+ getPrivatePreferences().edit()
+ .putInt(Properties.k_terminal_type, type)
+ .apply();
+ }
+
+ public static int getTerminalType() {
+ return getPrivatePreferences()
+ .getInt(Properties.k_terminal_type, -1);
}
}
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 bad6811c..97a5bea0 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
@@ -14,7 +14,6 @@ public interface Paths {
String MCT_PATH = "MifareClassicTool";
String MTools_PATH = "MTools";
String HARDNESTED_PATH = "hardnested";
- String TABLES_PATH = "tables";
String LOG_PATH = "log";
String PM3_PATH = "proxmark3";
String COMMON_PATH = "common";
diff --git a/app_main/src/main/res/drawable-hdpi/simple_console_view_example.png b/app_main/src/main/res/drawable-hdpi/simple_console_view_example.png
new file mode 100644
index 00000000..7619eb2f
Binary files /dev/null and b/app_main/src/main/res/drawable-hdpi/simple_console_view_example.png differ
diff --git a/app_main/src/main/res/layout/act_pm3_terminal_init.xml b/app_main/src/main/res/layout/act_pm3_terminal_init.xml
index d36c1605..bba2945a 100644
--- a/app_main/src/main/res/layout/act_pm3_terminal_init.xml
+++ b/app_main/src/main/res/layout/act_pm3_terminal_init.xml
@@ -9,18 +9,63 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
-
+ android:orientation="horizontal"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -29,63 +74,63 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tips_fw_client_version_same"
- android:textColor="@color/colorTextNormal"
- android:textSize="16sp" />
+ android:textColor="@color/colorTextWeaker"
+ android:textSize="14sp" />
+ android:textColor="@color/colorTextWeaker"
+ android:textSize="14sp" />
-
-
-
+ android:textColor="@color/md_blue_800"
+ android:textSize="13sp" />
-
+ android:gravity="end"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp">
-
+
+
+
+
+
diff --git a/app_main/src/main/res/values-en/strings.xml b/app_main/src/main/res/values-en/strings.xml
index 2b11e215..d3d05295 100644
--- a/app_main/src/main/res/values-en/strings.xml
+++ b/app_main/src/main/res/values-en/strings.xml
@@ -278,7 +278,7 @@
Read One Sector
Write One Block
Change the language of app to:
- Resources initialization
+ Proxmark3 Settings
App language
PM3(RDV4 RRG) resource initialization
@@ -300,9 +300,8 @@
Custom firmware
Select BootRom
Select FullImage
- Will use TERMUX implement UI
1. Your FW can\'t than for client version too low or high , you need go flash FW.
- 2. Check \'Auto Go\', it will auto go to termux view.
+ 2. Check \'Auto Go\', it will auto go to terminal view.
Auto Go
Flash Firmware(OTG)
Go Termux
@@ -318,5 +317,16 @@
Send
Console
Use slot alias
+ Full terminal view (TERMUX based)
+ Simple terminal view (TextView based)
+ Please select your preferred terminal view.
+ Proxmark3 auto goto terminal view
+ If checked, will automatically jump to the terminal view after the connection is successful.
+ FullTerminalView(TERMUX)
+ SimpleTerminalView(TextView)
+ Proxmark3 terminal view type
+ The complete terminal view is suitable for developers or masters, while the simple terminal view is suitable for novice users.
+ Unselected
+ 请稍等
\ 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 a1b22284..7b99e2e7 100644
--- a/app_main/src/main/res/values-zh/strings.xml
+++ b/app_main/src/main/res/values-zh/strings.xml
@@ -284,7 +284,7 @@
读取一个扇区
写入一个块
更改APP的语言为:
- 资源初始化
+ Proxmark3设置
App语言
PM3(RDV4 RRG)资源初始化
@@ -306,9 +306,8 @@
自定义固件
选择引导器
选择系统固件
- 将会使用TERMUX实现终端视图
1. 你的固件不能比客户端版本太低或太高,太高或者太低都需要去刷固件。
- 2. 勾选 \'自动跳转\', 将自动转到TERMUX视图。
+ 2. 勾选 \'自动跳转\', 将自动转到终端视图。
自动跳转
刷写固件(OTG)
跳转到Termux
@@ -324,5 +323,16 @@
发送
控制台
使用卡槽别名
+ 完整终端视图(基于TERMUX)
+ 简约终端视图(基于简单文本)
+ 请选择你喜欢的终端视图。
+ Proxmark3自动跳转到终端视图
+ 如果选中,连接成功后将自动跳转到终端视图。
+ 完整终端视图(TERMUX)
+ 简约终端视图(文本视图)
+ Proxmark3终端视图类型
+ 完整的终端视图适合开发人员或大师,而简单终端视图适合新手用户。
+ 未选择
+ 请稍等。
\ 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 d57e5efd..43923b0c 100644
--- a/app_main/src/main/res/values/strings.xml
+++ b/app_main/src/main/res/values/strings.xml
@@ -277,7 +277,7 @@
Read One Sector
Write One Block
Change the language of app to:
- Resources initialization
+ Proxmark3 Settings
App language
PM3(RDV4 RRG) resource initialization
@@ -301,7 +301,7 @@
Select FullImage
Will use TERMUX implement UI
1. Your FW can\'t than for client version too low or high , you need go flash FW.
- 2. Check \'Auto Go\', it will auto go to termux view.
+ 2. Check \'Auto Go\', it will auto go to terminal view.
Auto Go
Flash Firmware(OTG)
Go Termux
@@ -317,5 +317,16 @@
Send
Console
Use slot alias
+ Full terminal view (TERMUX based)
+ Simple terminal view (TextView based)
+ Please select your preferred terminal view.
+ Proxmark3 auto goto terminal view
+ If checked, will automatically jump to the terminal view after the connection is successful.
+ FullTerminalView(TERMUX)
+ SimpleTerminalView(TextView)
+ Proxmark3 terminal view type
+ The complete terminal view is suitable for developers or masters, while the simple terminal view is suitable for novice users.
+ Unselected
+ Please wait.
\ No newline at end of file
diff --git a/pm3rdv4rrg/.gitignore b/pm3rdv4rrg/.gitignore
new file mode 100644
index 00000000..3889eda0
--- /dev/null
+++ b/pm3rdv4rrg/.gitignore
@@ -0,0 +1,62 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# Cmake gen
+.cxx/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+
+# Keystore files
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
diff --git a/pm3rdv4rrg/build.gradle b/pm3rdv4rrg/build.gradle
new file mode 100644
index 00000000..5f310132
--- /dev/null
+++ b/pm3rdv4rrg/build.gradle
@@ -0,0 +1,51 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.2"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ externalNativeBuild {
+ cmake {
+ arguments '-DANDROID_STL=c++_static'
+ abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
+ }
+ }
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles 'consumer-rules.pro'
+ }
+
+ externalNativeBuild {
+ cmake {
+ version '3.10.2'
+ path 'src/main/cpp/CMakeLists.txt'
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.github.xianglin1998:nfctag:1.0'
+ implementation 'com.github.xianglin1998:nfc_console:1.0'
+
+ implementation 'com.github.xianglin1998:ComBridge:1.0.7'
+ // implementation project(path: ':iobridges')
+
+ implementation project(':communication')
+ implementation project(path: ':utils')
+
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+}
\ No newline at end of file
diff --git a/pm3rdv4rrg/consumer-rules.pro b/pm3rdv4rrg/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/pm3rdv4rrg/proguard-rules.pro b/pm3rdv4rrg/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/pm3rdv4rrg/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/pm3rdv4rrg/src/main/AndroidManifest.xml b/pm3rdv4rrg/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..babbbc7e
--- /dev/null
+++ b/pm3rdv4rrg/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/pm3rdv4rrg/src/main/cpp/CMakeLists.txt b/pm3rdv4rrg/src/main/cpp/CMakeLists.txt
new file mode 100644
index 00000000..7c2abdb9
--- /dev/null
+++ b/pm3rdv4rrg/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,7 @@
+# version
+cmake_minimum_required(VERSION 3.4.1)
+
+# bzip2 dep
+include(cmake/bzip2.cmake)
+# pm3 client
+add_subdirectory(proxmark3/client/android)
\ No newline at end of file
diff --git a/pm3rdv4rrg/src/main/cpp/bzip2 b/pm3rdv4rrg/src/main/cpp/bzip2
new file mode 160000
index 00000000..8ca1faa3
--- /dev/null
+++ b/pm3rdv4rrg/src/main/cpp/bzip2
@@ -0,0 +1 @@
+Subproject commit 8ca1faa31f396d94ab927b257f3a05236c84e330
diff --git a/pm3rdv4rrg/src/main/cpp/cmake/bzip2.cmake b/pm3rdv4rrg/src/main/cpp/cmake/bzip2.cmake
new file mode 100644
index 00000000..22b08bd0
--- /dev/null
+++ b/pm3rdv4rrg/src/main/cpp/cmake/bzip2.cmake
@@ -0,0 +1,13 @@
+get_filename_component(BZIP2_ROOT bzip2 ABSOLUTE)
+
+add_library(pm3rrg_rdv4_bzip2 STATIC
+ ${BZIP2_ROOT}/blocksort.c
+ ${BZIP2_ROOT}/bzlib.c
+ ${BZIP2_ROOT}/compress.c
+ ${BZIP2_ROOT}/crctable.c
+ ${BZIP2_ROOT}/decompress.c
+ ${BZIP2_ROOT}/huffman.c
+ ${BZIP2_ROOT}/randtable.c
+ )
+
+target_include_directories(pm3rrg_rdv4_bzip2 INTERFACE bzip2)
diff --git a/pm3rdv4rrg/src/main/cpp/proxmark3 b/pm3rdv4rrg/src/main/cpp/proxmark3
new file mode 160000
index 00000000..64068ba4
--- /dev/null
+++ b/pm3rdv4rrg/src/main/cpp/proxmark3
@@ -0,0 +1 @@
+Subproject commit 64068ba4303e218505e630506b2f66ed7e042122
diff --git a/pm3rdv4rrg/src/main/java/cn/rrg/devices/Proxmark3RRGRdv4.java b/pm3rdv4rrg/src/main/java/cn/rrg/devices/Proxmark3RRGRdv4.java
new file mode 100644
index 00000000..bc576056
--- /dev/null
+++ b/pm3rdv4rrg/src/main/java/cn/rrg/devices/Proxmark3RRGRdv4.java
@@ -0,0 +1,31 @@
+package cn.rrg.devices;
+
+import com.iobridges.com.Communication;
+import com.iobridges.com.DeviceChecker;
+
+import java.io.IOException;
+
+public class Proxmark3RRGRdv4 extends DeviceChecker {
+
+ static {
+ System.loadLibrary("pm3rrg_rdv4");
+ }
+
+ public Proxmark3RRGRdv4(Communication communication) {
+ super(communication);
+ }
+
+ @Override
+ public boolean checkDevice() throws IOException {
+ return testPm3();
+ }
+
+ @Override
+ public void close() throws IOException {
+ closePm3();
+ }
+
+ private native boolean testPm3() throws IOException;
+
+ private native void closePm3();
+}
diff --git a/pm3rdv4rrg/src/main/java/cn/rrg/natives/Proxmark3RRGRdv4Tools.java b/pm3rdv4rrg/src/main/java/cn/rrg/natives/Proxmark3RRGRdv4Tools.java
new file mode 100644
index 00000000..0f866e4f
--- /dev/null
+++ b/pm3rdv4rrg/src/main/java/cn/rrg/natives/Proxmark3RRGRdv4Tools.java
@@ -0,0 +1,20 @@
+package cn.rrg.natives;
+
+import cn.rrg.console.define.ICommandTools;
+
+public class Proxmark3RRGRdv4Tools implements ICommandTools {
+
+ //加载so文件!
+ static {
+ System.loadLibrary("pm3rrg_rdv4");
+ }
+
+ @Override
+ public native int startExecute(String cmd);
+
+ @Override
+ public native boolean isExecuting();
+
+ @Override
+ public native void stopExecute();
+}
diff --git a/pm3rdv4rrg/src/main/res/values/strings.xml b/pm3rdv4rrg/src/main/res/values/strings.xml
new file mode 100644
index 00000000..0b86ae82
--- /dev/null
+++ b/pm3rdv4rrg/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ pm3rdv4rrg
+
diff --git a/settings.gradle b/settings.gradle
index 21d0d736..61d556df 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,4 +1,4 @@
-include ':app_main', ':utils', ':chameleon', ':communication', ':libnfc_pn53x'
-include ':pm3flasher'
-include ':xmodem'
+include ':app_main', ':chameleon', ':communication', ':libnfc_pn53x'
+include ':pm3flasher', ':pm3rdv4rrg'
+include ':xmodem', ':utils'
include ':termux-app', ':terminal-emulator', ':terminal-view'
\ No newline at end of file
diff --git a/utils/src/main/java/cn/dxl/common/util/LanguageUtil.java b/utils/src/main/java/cn/dxl/common/util/LanguageUtil.java
index a3c38874..3484b964 100644
--- a/utils/src/main/java/cn/dxl/common/util/LanguageUtil.java
+++ b/utils/src/main/java/cn/dxl/common/util/LanguageUtil.java
@@ -37,7 +37,7 @@ public class LanguageUtil {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
switch (language) {
case "zh":
- configuration.setLocale(Locale.SIMPLIFIED_CHINESE);
+ configuration.setLocale(Locale.CHINESE);
break;
case "en":
default:
diff --git a/utils/src/main/res/drawable/btn_selector_blue.xml b/utils/src/main/res/drawable/btn_selector_blue.xml
new file mode 100644
index 00000000..78f53f66
--- /dev/null
+++ b/utils/src/main/res/drawable/btn_selector_blue.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/src/main/res/drawable/shape_bg_blue_600.xml b/utils/src/main/res/drawable/shape_bg_blue_600.xml
new file mode 100644
index 00000000..8534a587
--- /dev/null
+++ b/utils/src/main/res/drawable/shape_bg_blue_600.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/src/main/res/drawable/shape_bg_blue_800.xml b/utils/src/main/res/drawable/shape_bg_blue_800.xml
new file mode 100644
index 00000000..96261b0f
--- /dev/null
+++ b/utils/src/main/res/drawable/shape_bg_blue_800.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file