1. PM3 flasher gui add. (on tools)

2. dump merge bug fixed.
This commit is contained in:
dxl
2020-05-22 15:10:09 +08:00
parent de462133cc
commit b29c6d77a3
14 changed files with 690 additions and 95 deletions
+2 -2
View File
@@ -8,8 +8,8 @@ android {
minSdkVersion 19
targetSdkVersion 29
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
versionCode 15
versionName "1.4.2"
versionCode 20
versionName "1.4.4"
}
buildTypes {
release {
@@ -180,11 +180,4 @@ public class PM3FlasherMainActivity extends BaseActivity implements DevCallback<
public void onDetach(String dev) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// LogUtils.d("X: " + event.getRawX());
// LogUtils.d("Y: " + event.getRawY());
return super.onTouchEvent(event);
}
}
@@ -1,12 +1,34 @@
package cn.rrg.rdv.activities.tools;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.iobridges.com.LocalComBridgeAdapter;
import com.proxgrind.pm3flasher.Proxmark3Flasher;
import com.proxgrind.pm3flasher.Target;
import java.io.File;
import cn.dxl.common.util.FileUtils;
import cn.dxl.common.widget.ToastUtil;
import cn.dxl.mifare.NfcTagListenUtils;
import cn.proxgrind.com.DevCallback;
import cn.proxgrind.com.UsbSerialControl;
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.widget.MaterialAlertDialog;
import cn.rrg.rdv.widget.ProDialog1;
/**
* Provide users with an interactive PM3 firmware upgrade interface.
@@ -16,7 +38,41 @@ import cn.rrg.rdv.activities.main.BaseActivity;
* @author DXL
* @version 1.0
*/
public class Proxmark3FirmwareActivity extends BaseActivity {
public class Proxmark3FirmwareActivity extends BaseActivity implements DevCallback<String> {
private TextView txtShowClientVersion;
private RadioGroup rdoGroupImageSource;
private RadioButton rdoBtnFromApp;
private RadioButton rdoBtnFromUser;
private EditText edtShowBootRomName;
private EditText edtShowFullImageName;
private Button btnSelectBootRom;
private Button btnSelectFullImage;
private Button btnFlash;
private View layout_image_select;
private enum MODE {
BOOT, OS
}
private MODE selectImage = MODE.BOOT;
private MODE flashImage = MODE.BOOT;
private UsbSerialControl control = UsbSerialControl.get();
private Proxmark3Flasher flasher = Proxmark3Flasher.getFlasher();
private ProDialog1 proDialog1;
private boolean isFlashing = false;
// The image path for bt & fi.
private String bootRomImagePath;
private String fullImagePath;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -24,11 +80,270 @@ public class Proxmark3FirmwareActivity extends BaseActivity {
setContentView(R.layout.act_pm3_custom_flasher);
NfcTagListenUtils.removeListener(this);
// init and try to connect.
control.register(this);
// start communication forward!
LocalComBridgeAdapter.getInstance()
.startServer(LocalComBridgeAdapter.NAMESPACE_DEFAULT);
proDialog1 = new ProDialog1(context);
initViews();
initActions();
}
private void initViews() {
txtShowClientVersion = findViewById(R.id.txtShowClientVersion);
txtShowClientVersion.setText(Commons.PM3_CLIENT_VERSION);
rdoGroupImageSource = findViewById(R.id.rdoGroupImageSource);
rdoBtnFromApp = findViewById(R.id.rdoBtnFromApp);
rdoBtnFromUser = findViewById(R.id.rdoBtnFromUser);
edtShowBootRomName = findViewById(R.id.edtShowBootRomName);
edtShowFullImageName = findViewById(R.id.edtShowFullImageName);
btnSelectBootRom = findViewById(R.id.btnSelectBootRom);
btnSelectFullImage = findViewById(R.id.btnSelectFullImage);
btnFlash = findViewById(R.id.btnFlash);
layout_image_select = findViewById(R.id.layout_image_select);
}
private void initActions() {
btnFlash.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rdoGroupImageSource.getCheckedRadioButtonId() == R.id.rdoBtnFromApp) {
flashImage = MODE.BOOT;
// init path
bootRomImagePath = Paths.PM3_IMAGE_BOOT_FILE;
fullImagePath = Paths.PM3_IMAGE_OS_FILE;
// init status
isFlashing = true;
connectAndFlash();
} else {
bootRomImagePath = edtShowBootRomName.getText().toString();
fullImagePath = edtShowFullImageName.getText().toString();
if (bootRomImagePath.length() > 0 || fullImagePath.length() > 0) {
// init status
isFlashing = true;
if (bootRomImagePath.length() <= 0) {
flashImage = MODE.OS;
} else {
flashImage = MODE.BOOT;
}
connectAndFlash();
} else {
new MaterialAlertDialog.Builder(context)
.setMessage(getString(R.string.tips_image_select_bt_fi))
.show();
}
}
}
});
btnSelectBootRom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectImage = MODE.BOOT;
selectImage();
}
});
btnSelectFullImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectImage = MODE.OS;
selectImage();
}
});
rdoGroupImageSource.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rdoBtnFromApp:
layout_image_select.setVisibility(View.GONE);
break;
case R.id.rdoBtnFromUser:
layout_image_select.setVisibility(View.VISIBLE);
break;
}
}
});
rdoGroupImageSource.check(R.id.rdoBtnFromApp);
}
private void selectImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, 0x77);
}
private void connectAndFlash() {
// connect device
if (control.connect(null)) {
LocalComBridgeAdapter.getInstance()
.setInputStream(control.getInput())
.setOutputStream(control.getOutput());
flashDefaultFW();
} else {
ToastUtil.show(context, getString(R.string.tips_device_no_found), false);
isFlashing = false;
}
}
private void flashDefaultFW() {
if (!proDialog1.isShowing())
proDialog1.show();
new Thread(new Runnable() {
@Override
public void run() {
if (!flasher.isStart(Target.CLIENT)) {
if (!flasher.start(Target.CLIENT)) {
ToastUtil.show(context, "Client open failed!", false);
proDialog1.dismiss();
return;
}
}
// 如果没有在Bootloader模式下,我们需要先重启设备使其进入Bootloader模式下!
if (flasher.isStart(Target.BOOT)) {
switch (flashImage) {
case BOOT:
if (bootRomImagePath != null && FileUtils.isFile(bootRomImagePath)) {
if (flasher.flashBootRom(bootRomImagePath)) {
ToastUtil.show(context, getString(R.string.tips_boot_flash_success), false);
} else {
ToastUtil.show(context, getString(R.string.tips_boot_flash_failed), false);
}
finishFlash();
if (fullImagePath != null && FileUtils.isFile(fullImagePath)) {
// 开启下一轮!
flashImage = MODE.OS;
proDialog1.setTips(getString(R.string.tips_bootrom_flash_finish));
} else {
isFlashing = false;
proDialog1.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
new MaterialAlertDialog.Builder(context)
.setMessage(getString(R.string.tips_bootrom_flash_successfully))
.show();
}
});
}
}
break;
case OS:
if (fullImagePath != null && FileUtils.isFile(fullImagePath)) {
proDialog1.setTips(getString(R.string.tips_fullimage_flashing));
String msg;
if (flasher.flashFullImg(fullImagePath)) {
msg = getString(R.string.tips_os_flash_success);
} else {
msg = getString(R.string.tips_os_flash_failed);
}
finishFlash();
isFlashing = false;
proDialog1.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
new MaterialAlertDialog.Builder(context)
.setMessage(msg)
.show();
}
});
}
break;
}
} else {
if (!flasher.start(Target.BOOT)) {
ToastUtil.show(context, getString(R.string.tips_pm3_enter_failed), false);
proDialog1.dismiss();
isFlashing = false;
}
// 记得关闭客户端
flasher.close(Target.CLIENT);
}
}
}).start();
}
private void finishFlash() {
flasher.close(Target.BOOT);
flasher.close(Target.CLIENT);
}
private void closeClient() {
new Thread(new Runnable() {
@Override
public void run() {
flasher.close(Target.CLIENT);
}
}).start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0x77) {
if (data != null) {
Uri uri = data.getData();
String name = FileUtils.getFileNameByUri(context, uri, false);
if (resultCode == RESULT_OK) {
// create a temp file.
File tmpImage = Commons.createTmpFile(name);
// copy content to temp file
FileUtils.copy(uri, tmpImage);
// set path to view!
if (selectImage == MODE.BOOT) {
edtShowBootRomName.setText(tmpImage.getPath());
} else {
edtShowFullImageName.setText(tmpImage.getPath());
}
}
if (resultCode == RESULT_CANCELED) {
ToastUtil.show(context, getString(R.string.cancel), false);
}
}
}
}
@Override
public void onAttach(String dev) {
// 自动连接设备!
if (control.connect(dev)) {
// 更新流引用!
LocalComBridgeAdapter.getInstance()
.setInputStream(control.getInput())
.setOutputStream(control.getOutput());
if (isFlashing) {
flashDefaultFW();
}
} else {
ToastUtil.show(context, "Device connect failed!", false);
}
}
@Override
public void onDetach(String dev) {
}
@Override
protected void onDestroy() {
super.onDestroy();
proDialog1.dismiss();
control.unregister();
closeClient();
LocalComBridgeAdapter.getInstance()
.stopClient();
}
}
@@ -116,7 +116,7 @@ public class MainSettingsFragment
ItemTextBean pm3Res = new ItemTextBean(getString(R.string.title_pm3_res_init)) {
@Override
public void onClick(View view, int pos) {
pm3ResInit();
pm3ResInit(this);
}
};
pm3Res.setSubTitle(getString(R.string.title_pm3_res_sub_title));
@@ -160,7 +160,7 @@ public class MainSettingsFragment
}
}
private void pm3ResInit() {
private void pm3ResInit(ItemTextBean item) {
Activity activity = getActivity();
if (activity != null) {
ProDialog1 proDialog1 = new ProDialog1(activity);
@@ -173,6 +173,13 @@ public class MainSettingsFragment
.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();
}
});
}
}).start();
}
@@ -12,12 +12,15 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.proxgrind.pm3flasher.Proxmark3Flasher;
import cn.rrg.rdv.R;
import cn.rrg.rdv.activities.tools.DumpEqualActivity;
import cn.rrg.rdv.activities.tools.DumpListActivity;
import cn.rrg.rdv.activities.tools.FileListActivity;
import cn.rrg.rdv.activities.tools.FormatCovertActivity;
import cn.rrg.rdv.activities.tools.KeyFileListActivity;
import cn.rrg.rdv.activities.tools.Proxmark3FirmwareActivity;
import cn.rrg.rdv.fragment.base.BaseFragment;
public class ToolsAccessFragment
@@ -27,6 +30,7 @@ public class ToolsAccessFragment
private Button btnKeyEditor = null;
private Button btnFormatCovert = null;
private Button btnDiffTools = null;
private Button btnPM3Flasher;
@Nullable
@Override
@@ -47,23 +51,22 @@ public class ToolsAccessFragment
btnKeyEditor = view.findViewById(R.id.btnKeyEditor);
btnFormatCovert = view.findViewById(R.id.btnConvertFormat);
btnDiffTools = view.findViewById(R.id.btnDiffTool);
btnPM3Flasher = view.findViewById(R.id.btnPM3Flasher);
}
private void initActions(Context context) {
//设置数据编辑的按钮的接口实现
btnDataEditor.setOnClickListener(v -> {
startActivity(new Intent(context, DumpListActivity.class).putExtra("mode", DumpListActivity.MODE.EDIT));
});
//数据对比
btnDiffTools.setOnClickListener(v -> startActivity(new Intent(context, DumpEqualActivity.class)));
//格式转换act
btnFormatCovert.setOnClickListener(v -> startActivity(new Intent(context, FormatCovertActivity.class)));
//设置密钥编辑的按钮的接口实现
btnKeyEditor.setOnClickListener(v -> startActivity(
new Intent(context, KeyFileListActivity.class).putExtra("mode", FileListActivity.MODE.EDIT))
);
btnPM3Flasher.setOnClickListener(v -> startActivity(new Intent(context, Proxmark3FirmwareActivity.class)));
}
}
@@ -191,4 +191,11 @@ public class Commons {
String[] list = pm3Path.list();
return list != null && list.length > 0;
}
public static File createTmpFile(String fileName) {
File file = new File(application.getCacheDir(), fileName);
FileUtils.delete(file);
FileUtils.createFile(file);
return file;
}
}
@@ -669,8 +669,7 @@ public class DumpUtils {
String[] datas = new String[aBean.getDatas().length];
//取出块数据
String[] tmpA = aBeanDatas;
String[] tmpB = bBean.getDatas() == null ?
getEmptyM1Bean(bBean.getSector()).getDatas() : bBean.getDatas();
String[] tmpB = bBean.getDatas() == null ? getEmptyM1Bean(bBean.getSector()).getDatas() : bBean.getDatas();
for (int i = 0; i <= last; ++i) {
//先判断两组块数据是否相同
if (tmpA[i].equals(tmpB[i])) {
@@ -678,29 +677,28 @@ public class DumpUtils {
datas[i] = tmpA[i];
} else {
if (i != last) {
//否则判断哪个数据是有效的,如果全部为零则优先考虑其他的情况!
//将有效的数据合并到ret中,优先用KeyB的数据!
//否则是否全都是0,如果全部为零则优先考虑其他的情况!
boolean isADataAllZero = isBlockAllZero(tmpA[i]);
boolean isBDataAllZero = isBlockAllZero(tmpB[i]);
// 两者都是零,说明数据真的是0
if (isADataAllZero && isBDataAllZero) {
// 开始选择用正确的数据
if (DumpUtils.isBlockData(tmpB[i])) {
if (DumpUtils.isValidBlockData(tmpB[i])) {
datas[i] = tmpB[i];
} else if (DumpUtils.isBlockData(tmpA[i])) {
} else if (DumpUtils.isValidBlockData(tmpA[i])) {
datas[i] = tmpA[i];
} else {
//不符合数据规范,填充异常字符,跳过操作
//不符合数据规范,跳过操作
datas[i] = DumpUtils.BLANK_DATA;
}
} else {
// 开始选择用正确的数据
if (DumpUtils.isBlockData(tmpB[i]) && isADataAllZero) {
if (DumpUtils.isValidBlockData(tmpB[i]) && isADataAllZero) {
datas[i] = tmpB[i];
} else if (DumpUtils.isBlockData(tmpA[i]) && isBDataAllZero) {
} else if (DumpUtils.isValidBlockData(tmpA[i]) && isBDataAllZero) {
datas[i] = tmpA[i];
} else {
//不符合数据规范,填充异常字符,跳过操作
//不符合数据规范,跳过操作
datas[i] = DumpUtils.BLANK_DATA;
}
}
@@ -716,10 +714,10 @@ public class DumpUtils {
// 随便填充一个就行了!
datas[i] = tmpA[i];
} else {
if (DumpUtils.isBlockData(tmpB[i]) && isADataTrialerAllDefault) {
if (DumpUtils.isValidBlockData(tmpB[i]) && isADataTrialerAllDefault) {
//有效的尾部块
datas[i] = tmpB[i];
} else if (DumpUtils.isBlockData(tmpA[i]) && isBDataTrialerAllDefault) {
} else if (DumpUtils.isValidBlockData(tmpA[i]) && isBDataTrialerAllDefault) {
datas[i] = tmpA[i];
} else {
//有效的尾部块
@@ -49,6 +49,20 @@
android:text="@string/key_editor"
android:textAllCaps="false" />
<Button
android:id="@+id/btnPM3Flasher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/btn_selectot_white"
android:gravity="start|center"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:text="@string/title_pm3_firmware_flasher"
android:textAllCaps="false" />
<Button
android:id="@+id/btnDiffTool"
android:layout_width="match_parent"
@@ -1,9 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<cn.dxl.common.widget.StatusBarHeightView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:text="@string/tips_basic_info" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tips_client_provider_rrg"
android:textColor="@color/colorTextNormal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:autoLink="web"
android:text="https://github.com/RfidResearchGroup/proxmark3"
android:textColor="@color/colorTextNormal"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tips_client_version"
android:textColor="@color/colorTextNormal"
android:textSize="16sp" />
<TextView
android:id="@+id/txtShowClientVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2020/05/06"
android:textColor="@color/colorTextNormal"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:text="@string/firmware_source" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<!-- BootRom or FullImage select! -->
<RadioGroup
android:id="@+id/rdoGroupImageSource"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:padding="8dp">
<RadioButton
android:id="@+id/rdoBtnFromApp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_supporting_firmware" />
<RadioButton
android:id="@+id/rdoBtnFromUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/custom_firmware" />
</RadioGroup>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/layout_image_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/edtShowBootRomName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:enabled="false"
android:hint="BootRom"
android:inputType="none" />
<Button
android:id="@+id/btnSelectBootRom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:background="@drawable/btn_selector_blue"
android:text="@string/title_select_bootrom"
android:textAllCaps="false"
android:textColor="@color/md_white_1000" />
</LinearLayout>
<include layout="@layout/view_h_line" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<EditText
android:id="@+id/edtShowFullImageName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:enabled="false"
android:hint="FullImage"
android:inputType="none" />
<Button
android:id="@+id/btnSelectFullImage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:background="@drawable/btn_selector_blue"
android:text="@string/select_fullimage"
android:textAllCaps="false"
android:textColor="@color/md_white_1000" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
<Button
android:id="@+id/btnFlash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:background="@drawable/btn_selector_blue"
android:text="@string/flash"
android:textAllCaps="false"
android:textColor="@color/md_white_1000" />
</RelativeLayout>
@@ -287,5 +287,18 @@
<string name="uninitialized">Uninitialized</string>
<string name="initializing">Initializing</string>
<string name="finished">Finished</string>
<string name="title_pm3_firmware_flasher">PM3 Firmware Flasher</string>
<string name="tips_bootrom_flash_finish">BootRom flash finish, next to flash OS.</string>
<string name="tips_bootrom_flash_successfully">BootRom flash successfully</string>
<string name="tips_image_select_bt_fi">Please select BootRom or FullImage or both to flash.</string>
<string name="tips_fullimage_flashing">FullImage flashing.</string>
<string name="tips_basic_info">Basic information</string>
<string name="firmware_source">Firmware source</string>
<string name="tips_client_provider_rrg">Client providerRfidResearchGroup</string>
<string name="tips_client_version">Client version</string>
<string name="app_supporting_firmware">App supporting firmware</string>
<string name="custom_firmware">Custom firmware</string>
<string name="title_select_bootrom">Select BootRom</string>
<string name="select_fullimage">Select FullImage</string>
</resources>
@@ -293,5 +293,18 @@
<string name="uninitialized">未初始化</string>
<string name="initializing">初始化中</string>
<string name="finished">已完成</string>
<string name="title_pm3_firmware_flasher">PM3固件烧写</string>
<string name="tips_bootrom_flash_finish">BootRom烧写完成, 下一步刷写操作系统。</string>
<string name="tips_bootrom_flash_successfully">BootRom烧写成功。</string>
<string name="tips_image_select_bt_fi">请至少要选择BootRom和FullImage其中一个来烧写</string>
<string name="tips_fullimage_flashing">FullImage烧写中</string>
<string name="tips_basic_info">基础信息</string>
<string name="firmware_source">固件来源</string>
<string name="tips_client_provider_rrg">客户端提供者:RfidResearchGroup</string>
<string name="tips_client_version">客户端版本:</string>
<string name="app_supporting_firmware">APP配套固件</string>
<string name="custom_firmware">自定义固件</string>
<string name="title_select_bootrom">选择引导器</string>
<string name="select_fullimage">选择系统固件</string>
</resources>
+13
View File
@@ -286,5 +286,18 @@
<string name="uninitialized">Uninitialized</string>
<string name="initializing">Initializing</string>
<string name="finished">Finished</string>
<string name="title_pm3_firmware_flasher">PM3 Firmware Flasher</string>
<string name="tips_bootrom_flash_finish">BootRom flash finish, next to flash OS.</string>
<string name="tips_bootrom_flash_successfully">BootRom flash successfully</string>
<string name="tips_image_select_bt_fi">Please select BootRom or FullImage or both to flash.</string>
<string name="tips_fullimage_flashing">FullImage flashing.</string>
<string name="tips_basic_info">Basic information</string>
<string name="firmware_source">Firmware source</string>
<string name="tips_client_provider_rrg">Client providerRfidResearchGroup</string>
<string name="tips_client_version">Client version</string>
<string name="app_supporting_firmware">App supporting firmware</string>
<string name="custom_firmware">Custom firmware</string>
<string name="title_select_bootrom">Select BootRom</string>
<string name="select_fullimage">Select FullImage</string>
</resources>
Submodule pm3rdv4rrg/src/main/cpp/proxmark3 updated: 939f830cdf...e9d06e0ec5
@@ -34,7 +34,6 @@ import java.text.DecimalFormat;
import java.util.ArrayList;
import cn.dxl.common.R;
import cn.dxl.common.util.IOUtils;
/*
* 一系列文件操作的封装!
@@ -202,6 +201,10 @@ public class FileUtils {
return mime;
}
public static boolean isFile(String file) {
return new File(file).isFile();
}
//删除文件夹目录下所有的文件
public static boolean delete(File dir) {
if (dir.isDirectory()) {
@@ -222,6 +225,83 @@ public class FileUtils {
}
}
public static boolean move(File file, File path) {
String pathStr = path.getAbsolutePath();
pathStr = pathStr.endsWith(File.separator) ? pathStr : pathStr + File.separator;
String targetFile = pathStr + file.getName();
File tmp = new File(targetFile);
createFile(tmp);
if (tmp.exists() && tmp.isFile()) {
// 开始写入!
return file.renameTo(new File(targetFile));
}
return true;
}
public static boolean copy(Uri source, File target) {
return copy(source, Uri.fromFile(target));
}
public static boolean copy(Uri source, Uri target) {
try {
byte[] data = readBytes(source);
writeBytes(data, target);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static boolean copy(File source, File target) {
if (target == null || source == null) return false;
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
File parentFile = target.getParentFile();
if (parentFile != null) {
createPaths(parentFile);
}
createFile(target);
inputChannel = new FileInputStream(source).getChannel();
outputChannel = new FileOutputStream(target).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.close(inputChannel);
IOUtils.close(outputChannel);
}
return true;
}
public static boolean copy(FileDescriptor descriptor, FileDescriptor target) {
if (target == null || descriptor == null) return false;
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
inputChannel = new FileInputStream(descriptor).getChannel();
outputChannel = new FileOutputStream(target).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.close(inputChannel);
IOUtils.close(outputChannel);
}
return true;
}
public static boolean copy(byte[] rawData, File target) {
try {
writeBytes(rawData, target, false);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
// 調用系統方法分享文件
public static void shareFile(File file) {
LogUtils.d("shareFile path: " + (file != null ? file.toString() : null));
@@ -513,12 +593,10 @@ public class FileUtils {
return ret;
}
//判断文件名是否有效!
public static boolean isValidFileName(String name) {
return !StringUtil.isEmpty(name) && !name.contains("/");
}
//获得so库的地址!
public static String getNativePath() {
String ss = context.getApplicationInfo().nativeLibraryDir;
if (ss == null)
@@ -526,64 +604,6 @@ public class FileUtils {
return ss;
}
public static boolean moveFile(File file, File path) {
String pathStr = path.getAbsolutePath();
pathStr = pathStr.endsWith(File.separator) ? pathStr : pathStr + File.separator;
String targetFile = pathStr + file.getName();
File tmp = new File(targetFile);
createFile(tmp);
if (tmp.exists() && tmp.isFile()) {
// 开始写入!
return file.renameTo(new File(targetFile));
}
return true;
}
public static boolean copy(File source, File target) throws IOException {
if (target == null || source == null) return false;
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
File parentFile = target.getParentFile();
if (parentFile != null) {
createPaths(parentFile);
}
createFile(target);
inputChannel = new FileInputStream(source).getChannel();
outputChannel = new FileOutputStream(target).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} finally {
IOUtils.close(inputChannel);
IOUtils.close(outputChannel);
}
return true;
}
public static boolean copy(FileDescriptor descriptor, FileDescriptor target) throws IOException {
if (target == null || descriptor == null) return false;
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
inputChannel = new FileInputStream(descriptor).getChannel();
outputChannel = new FileOutputStream(target).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} finally {
IOUtils.close(inputChannel);
IOUtils.close(outputChannel);
}
return true;
}
public static boolean copy(byte[] rawData, File target) {
try {
writeBytes(rawData, target, false);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static String getFileCountIfFolder(File[] files) {
if (files == null) files = new File[0];
return files.length + " " + context.getString(R.string.item);