25374a84 by 17205857019@139.com

11

0 parents
Showing 59 changed files with 1771 additions and 0 deletions
1 *.iml
2 .gradle
3 /local.properties
4 /.idea/caches
5 /.idea/libraries
6 /.idea/modules.xml
7 /.idea/workspace.xml
8 /.idea/navEditor.xml
9 /.idea/assetWizardSettings.xml
10 .DS_Store
11 /build
12 /captures
13 .externalNativeBuild
1 # Default ignored files
2 /shelf/
3 /workspace.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="CompilerConfiguration">
4 <bytecodeTargetLevel target="1.8" />
5 </component>
6 </project>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="deploymentTargetSelector">
4 <selectionStates>
5 <SelectionState runConfigName="app">
6 <option name="selectionMode" value="DROPDOWN" />
7 </SelectionState>
8 </selectionStates>
9 </component>
10 </project>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="Encoding" addBOMForNewFiles="with NO BOM" />
4 </project>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="GradleMigrationSettings" migrationVersion="1" />
4 <component name="GradleSettings">
5 <option name="linkedExternalProjectsSettings">
6 <GradleProjectSettings>
7 <option name="externalProjectPath" value="$PROJECT_DIR$" />
8 <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
9 <option name="modules">
10 <set>
11 <option value="$PROJECT_DIR$" />
12 <option value="$PROJECT_DIR$/app" />
13 </set>
14 </option>
15 <option name="resolveExternalAnnotations" value="false" />
16 </GradleProjectSettings>
17 </option>
18 </component>
19 </project>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="ProjectMigrations">
4 <option name="MigrateToGradleLocalJavaHome">
5 <set>
6 <option value="$PROJECT_DIR$" />
7 </set>
8 </option>
9 </component>
10 </project>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="corretto-1.8" project-jdk-type="JavaSDK">
4 <output url="file://$PROJECT_DIR$/build/classes" />
5 </component>
6 <component name="ProjectType">
7 <option name="id" value="Android" />
8 </component>
9 </project>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4">
3 <component name="VcsDirectoryMappings">
4 <mapping directory="$PROJECT_DIR$" vcs="Git" />
5 </component>
6 </project>
...\ No newline at end of file ...\ No newline at end of file
1 # SerialPortHelper(Android串口通信)
2
3 Android串口通讯助手可以用于需要使用串口通信的Android外设,该库有如下特点:
4
5 1. 串口通信部分使用C++实现,在笔者接触的部分设备上实测,使用C++实现与Google官方提供的Demo的方式要快;
6 2. 支持且必须设置串口接收最大数据长度,初始化库时填入该参数,这样设置的原因是考虑在实际使用中,规定的串口通信协议格式一般会固定有最大长度,方便对数据进行处理;
7 3. 支持命令一发一收,通过对串口的读写线程进行同步控制,命令会先加入到队列然后依次发送和接收,前提需要设置超时时间以及超时处理,参考下面第4、5点;
8 4. 支持超时设置,设置超时时间后,如果命令在设置的时间内未反馈,则会根据设置的操作进行重发或退出该命令;
9 5. 支持超时重发(可以N次重发,具体按需设置)与退出,退出会调用接收回调的 **onComplete** 方法。
10
11 ### 1、DEMO演示
12
13 使用该库简单实现的串口调试助手工具,[APK下载](https://github.com/freyskill/SerialPortHelper/blob/master/SerialPortHelperV1.0.1.apk)
14
15 ![image](https://github.com/freyskill/SerialPortHelper/blob/master/SerialPortHelper.png)
16
17
18
19 ### 2、接入方式
20
21 #### Step 1. Add the JitPack repository to your build file
22
23 Add it in your root **build.gradle** at the end of repositories:
24
25 ```groovy
26 allprojects {
27 repositories {
28 ...
29 maven { url 'https://www.jitpack.io' }
30 }
31 }
32 ```
33
34 #### Step 2. Add the dependency
35
36 ```groovy
37 dependencies {
38 implementation 'com.github.freyskill:SerialPortHelper:v1.0.1'
39 }
40 ```
41
42
43
44 ### 3、使用说明
45
46 初始化需要设置maxSize,也可以设置isReceiveMaxSize该参数默认为false,详细说明如下:
47
48 int maxSize; // 设置串口读取的最大数据长度
49
50 boolean isReceiveMaxSize; // 设置是否接收命令按最大长度进行返回,比如串口协议定义的格式长度为16个字节,这样可以设置maxSize为16,然后设置该参数为true,则接收的命令就会返回16个字节的长度。
51
52 **提示:** 设置isReceiveMaxSize为true是为了处理命令返回不完整的情况,例如完整命令长度为16,但是串口读的过程分几次返回。
53
54 ```java
55 SerialPortHelper serialPortHelper = new SerialPortHelper(32);
56 SerialPortHelper serialPortHelper = new SerialPortHelper(32,true);
57 ```
58
59 #### 3.1.初始化串口
60
61 ```java
62 //方式一:快速接入方式,设置好串口地址,或者地址和波特率即可,数据位、停止位、校验类型分别默认为8、1、N。
63 SerialPortHelper serialPortHelper = new SerialPortHelper(32);
64 //serialPortHelper.openDevice("dev/ttyS0");
65 serialPortHelper.openDevice("dev/ttyS0",11520);
66 // 数据接收回调
67 serialPortHelper.setSphResultCallback(new SphResultCallback() {
68 @Override
69 public void onSendData(SphCmdEntity sendCom) {
70 Log.d(TAG, "发送命令:" + sendCom.commandsHex);
71 }
72
73 @Override
74 public void onReceiveData(SphCmdEntity data) {
75 Log.d(TAG, "收到命令:" + data.commandsHex);
76
77 }
78
79 @Override
80 public void onComplete() {
81 Log.d(TAG, "完成");
82 }
83 });
84 ```
85
86 ```java
87 //方式二:通过SerialPortConfig设置相关串口参数
88
89 //串口参数
90 SerialPortConfig serialPortConfig = new SerialPortConfig();
91 serialPortConfig.mode = 0; // 是否使用原始模式(Raw Mode)方式来通讯
92 serialPortConfig.path = path; // 串口地址
93 serialPortConfig.baudRate = baudRate; // 波特率
94 serialPortConfig.dataBits = dataBits; // 数据位 取值 位 7或 8
95 serialPortConfig.parity = checkBits;// 检验类型 取值 N ,E, O
96 serialPortConfig.stopBits = stopBits; // 停止位 取值 1 或者 2
97
98 // 初始化串口
99 serialPortHelper = new SerialPortHelper(16);
100 // 设置串口参数
101 serialPortHelper.setConfigInfo(serialPortConfig);
102 // 开启串口
103 isOpen = serialPortHelper.openDevice();
104 if(!isOpen){
105 Toast.makeText(this,"串口打开失败!",Toast.LENGTH_LONG).show();
106 }
107 // 数据接收回调
108 serialPortHelper.setSphResultCallback(new SphResultCallback() {
109 @Override
110 public void onSendData(SphCmdEntity sendCom) {
111 Log.d(TAG, "发送命令:" + sendCom.commandsHex);
112 }
113
114 @Override
115 public void onReceiveData(SphCmdEntity data) {
116 Log.d(TAG, "收到命令:" + data.commandsHex);
117
118 }
119
120 @Override
121 public void onComplete() {
122 Log.d(TAG, "完成");
123 }
124 });
125 ```
126
127 #### 3.2.数据发送与接收
128
129 ```java
130 // 发送数据
131 serialPortHelper.addCommands(sendHexTxt); // 发送十六进制字符串
132 serialPortHelper.addCommands(sendComBytes); // 发送字节数组
133
134 // 发送数据实体
135 SphCmdEntity comEntry = new SphCmdEntity();
136 comEntry.commands = commands; // 发送命令字节数组
137 comEntry.flag = flag; // 备用标识
138 comEntry.commandsHex = DataConversion.encodeHexString(commands); // 发送十六进制字符串
139 comEntry.timeOut = 100; // 超时时间 ms
140 comEntry.reWriteCom = false; // 超时是否重发 默认false
141 comEntry.reWriteTimes = 5; // 重发次数
142 comEntry.receiveCount = 1; // 接收数据条数,默认为1
143 serialPortHelper.addCommands(comEntry);
144 ```
145
146 ```java
147 // 数据接收回调
148 serialPortHelper.setSphResultCallback(new SphResultCallback() {
149 @Override
150 public void onSendData(SphCmdEntity sendCom) {
151 Log.d(TAG, "发送命令:" + sendCom.commandsHex);
152 }
153
154 @Override
155 public void onReceiveData(SphCmdEntity data) {
156 // 对于接受数据的SphCmdEntity,其中需要使用的有
157 // commandsHex 返回的十六进制数据
158 // commands 返回的字节数组
159 // flag 备用标识,例如标识该命令是相关操作
160 Log.d(TAG, "收到命令:" + data.commandsHex);
161
162 }
163
164 @Override
165 public void onComplete() {
166 Log.d(TAG, "完成");
167 }
168 });
169 ```
170
171 ### 4、关闭串口
172
173 ```java
174 serialPortHelper.closeDevice();
175 ```
No preview for this file type
No preview for this file type
1 apply plugin: 'com.android.application'
2
3 android {
4 compileSdkVersion 28
5 defaultConfig {
6 applicationId "top.keepempty"
7 minSdkVersion 19
8 targetSdkVersion 28
9 versionCode 1
10 versionName "1.0"
11 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 }
13 buildTypes {
14 release {
15 minifyEnabled false
16 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
17 }
18 }
19 }
20
21 dependencies {
22 implementation fileTree(include: ['*.jar'], dir: 'libs')
23 implementation 'com.android.support:appcompat-v7:28.0.0'
24 implementation 'com.android.support.constraint:constraint-layout:1.1.3'
25 testImplementation 'junit:junit:4.12'
26 androidTestImplementation 'com.android.support.test:runner:1.0.2'
27 androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
28 implementation 'com.github.freyskill:SerialPortHelper:v1.0.1'
29 }
1 # Add project specific ProGuard rules here.
2 # You can control the set of applied configuration files using the
3 # proguardFiles setting in build.gradle.
4 #
5 # For more details, see
6 # http://developer.android.com/guide/developing/tools/proguard.html
7
8 # If your project uses WebView with JS, uncomment the following
9 # and specify the fully qualified class name to the JavaScript interface
10 # class:
11 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 # public *;
13 #}
14
15 # Uncomment this to preserve the line number information for
16 # debugging stack traces.
17 #-keepattributes SourceFile,LineNumberTable
18
19 # If you keep the line number information, uncomment this to
20 # hide the original source file name.
21 #-renamesourcefileattribute SourceFile
No preview for this file type
1 [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
...\ No newline at end of file ...\ No newline at end of file
1 package top.keepempty;
2
3 import android.content.Context;
4 import android.support.test.InstrumentationRegistry;
5 import android.support.test.runner.AndroidJUnit4;
6
7 import org.junit.Test;
8 import org.junit.runner.RunWith;
9
10 import static org.junit.Assert.*;
11
12 /**
13 * Instrumented test, which will execute on an Android device.
14 *
15 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
16 */
17 @RunWith(AndroidJUnit4.class)
18 public class ExampleInstrumentedTest {
19 @Test
20 public void useAppContext() {
21 // Context of the app under test.
22 Context appContext = InstrumentationRegistry.getTargetContext();
23
24 assertEquals("aidesudi.sph", appContext.getPackageName());
25 }
26 }
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="top.keepempty">
4
5 <application
6 android:allowBackup="true"
7 android:icon="@mipmap/ic_launcher"
8 android:label="@string/app_name"
9 android:roundIcon="@mipmap/ic_launcher_round"
10 android:supportsRtl="true"
11 android:theme="@style/AppTheme">
12 <activity android:name=".MainActivity"
13 >
14 <intent-filter>
15 <action android:name="android.intent.action.MAIN" />
16
17 <category android:name="android.intent.category.LAUNCHER" />
18 </intent-filter>
19 </activity>
20 </application>
21
22 </manifest>
...\ No newline at end of file ...\ No newline at end of file
1 package top.keepempty;
2
3 import android.os.Bundle;
4 import android.support.v4.content.ContextCompat;
5 import android.support.v7.app.AppCompatActivity;
6 import android.text.TextUtils;
7 import android.util.Log;
8 import android.view.View;
9 import android.widget.AdapterView;
10 import android.widget.ArrayAdapter;
11 import android.widget.Button;
12 import android.widget.EditText;
13 import android.widget.Spinner;
14 import android.widget.TextView;
15 import android.widget.Toast;
16
17 import top.keepempty.sph.library.SerialPortConfig;
18 import top.keepempty.sph.library.SerialPortFinder;
19 import top.keepempty.sph.library.SerialPortHelper;
20 import top.keepempty.sph.library.SphCmdEntity;
21 import top.keepempty.sph.library.SphResultCallback;
22
23 public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
24
25
26 private static final String TAG = "SerialPortHelper";
27
28 private SerialPortHelper serialPortHelper;
29
30 private TextView mShowReceiveTxt;
31
32 private Button mSendBtn;
33 private Button mOpenBtn;
34
35 private EditText mSendDataEt;
36
37 private Spinner mPathSpinner;
38 private Spinner mBaudRateSpinner;
39 private Spinner mDataSpinner;
40 private Spinner mCheckSpinner;
41 private Spinner mStopSpinner;
42
43 private int baudRate = 9600;
44 private int dataBits = 8;
45 private char checkBits = 'N';
46 private int stopBits = 1;
47 private String path;
48
49 private SerialPortFinder mSerialPortFinder;
50 private String[] entryValues;
51 private boolean isOpen;
52 private StringBuilder receiveTxt = new StringBuilder();
53
54 @Override
55 protected void onCreate(Bundle savedInstanceState) {
56 super.onCreate(savedInstanceState);
57 setContentView(R.layout.activity_main);
58 init();
59 final EditText et = findViewById(R.id.et);
60 final EditText et2 = findViewById(R.id.et2);
61 final EditText et3 = findViewById(R.id.et3);
62 final EditText et4 = findViewById(R.id.et4);
63 Button bt = findViewById(R.id.bt);
64
65 bt.setOnClickListener(new View.OnClickListener() {
66 @Override
67 public void onClick(View view) {
68 String ett =getFinalHex(String.valueOf(et.getText(),String.valueOf(et2.getText(),String.valueOf(et3.getText(),String.valueOf(et4.getText());
69 mSendDataEt.setText(ett);
70 }
71 });
72 }
73
74 public String getFinalHex(String pizhong,String zhongliang,String danjia,String zongjia){
75 return (chineseToHexStr("皮重","10 00") +
76 chineseToHexStr(pizhong,"20 00") +
77 chineseToHexStr("重量","30 00")
78 + chineseToHexStr(zhongliang,"40 00")
79 + chineseToHexStr("单价 元","50 00") +
80 chineseToHexStr(danjia,"60 00")
81 + chineseToHexStr("总价 元","70 00")
82 + chineseToHexStr(zongjia,"80 00") + " 00 00 00").replace(" ","");
83 }
84
85
86
87 public String chineseToHexStr(String text, String number) {
88 try {
89 // 将中文文本编码为 UTF-16 BE 字节数据
90 byte[] bytesData = text.getBytes("UTF-16BE");
91 // 将字节数据转换为十六进制字符串
92 StringBuilder hexStrBuilder = new StringBuilder(" 82 ");
93 hexStrBuilder.append(number).append(" ");
94 for (byte b : bytesData) {
95 hexStrBuilder.append(String.format("%02X ", b));
96 }
97 hexStrBuilder.append(" 00 00 ");
98 String hexStr = hexStrBuilder.toString();
99
100 // 移除空格并计算长度
101 String hexStrWithoutSpaces = hexStr.replace(" ", "");
102 int length = hexStrWithoutSpaces.length() / 2;
103
104 // 将长度转换为十六进制字符串,不足两位补 0
105 String lengthHexStr = String.format(" %02X", length);
106
107 return ("5A A5" + lengthHexStr + hexStr).replace(" ","");
108 } catch (Exception e) {
109 e.printStackTrace();
110 return null;
111 }
112 }
113
114
115 private void init() {
116 mPathSpinner = findViewById(R.id.sph_path);
117 mBaudRateSpinner = findViewById(R.id.sph_baudRate);
118 mDataSpinner = findViewById(R.id.sph_data);
119 mCheckSpinner = findViewById(R.id.sph_check);
120 mStopSpinner = findViewById(R.id.sph_stop);
121 mOpenBtn = findViewById(R.id.sph_openBtn);
122 mSendBtn = findViewById(R.id.sph_sendBtn);
123 mShowReceiveTxt = findViewById(R.id.sph_showReceiveTxt);
124 mSendDataEt = findViewById(R.id.sph_sendDataEt);
125
126 mBaudRateSpinner.setSelection(13);
127 mDataSpinner.setSelection(3);
128 mCheckSpinner.setSelection(0);
129 mStopSpinner.setSelection(0);
130
131 mPathSpinner.setOnItemSelectedListener(this);
132 mBaudRateSpinner.setOnItemSelectedListener(this);
133 mDataSpinner.setOnItemSelectedListener(this);
134 mCheckSpinner.setOnItemSelectedListener(this);
135 mStopSpinner.setOnItemSelectedListener(this);
136
137 mSerialPortFinder = new SerialPortFinder();
138 entryValues = mSerialPortFinder.getAllDevicesPath();
139 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
140 this, android.R.layout.simple_spinner_item,
141 entryValues);
142 mPathSpinner.setAdapter(adapter);
143
144 mSendBtn = findViewById(R.id.sph_sendBtn);
145 mSendBtn.setOnClickListener(new View.OnClickListener() {
146 @Override
147 public void onClick(View v) {
148 String sendTxt = mSendDataEt.getText().toString().trim();
149 if(TextUtils.isEmpty(sendTxt)){
150 Toast.makeText(MainActivity.this,"请输入发送命令!",Toast.LENGTH_LONG).show();
151 return;
152 }
153 if (sendTxt.length() % 2 == 1) {
154 Toast.makeText(MainActivity.this,"命令错误!",Toast.LENGTH_LONG).show();
155 return;
156 }
157 serialPortHelper.addCommands(sendTxt);
158 }
159 });
160
161 mOpenBtn.setOnClickListener(new View.OnClickListener() {
162 @Override
163 public void onClick(View v) {
164 if(isOpen){
165 serialPortHelper.closeDevice();
166 isOpen = false;
167 }else{
168 openSerialPort();
169 }
170 showState();
171 }
172 });
173 }
174
175 /**
176 * 打开串口
177 */
178 private void openSerialPort(){
179
180 /**
181 * 串口参数
182 */
183 SerialPortConfig serialPortConfig = new SerialPortConfig();
184 serialPortConfig.mode = 0;
185 serialPortConfig.path = path;
186 serialPortConfig.baudRate = baudRate;
187 serialPortConfig.dataBits = dataBits;
188 serialPortConfig.parity = checkBits;
189 serialPortConfig.stopBits = stopBits;
190
191
192 // 初始化串口
193 serialPortHelper = new SerialPortHelper(16);
194 // 设置串口参数
195 serialPortHelper.setConfigInfo(serialPortConfig);
196 // 开启串口
197 isOpen = serialPortHelper.openDevice();
198 if(!isOpen){
199 Toast.makeText(this,"串口打开失败!",Toast.LENGTH_LONG).show();
200 }
201 serialPortHelper.setSphResultCallback(new SphResultCallback() {
202 @Override
203 public void onSendData(SphCmdEntity sendCom) {
204 Log.d(TAG, "发送命令:" + sendCom.commandsHex);
205 }
206
207 @Override
208 public void onReceiveData(SphCmdEntity data) {
209 Log.d(TAG, "收到命令:" + data.commandsHex);
210 receiveTxt.append(data.commandsHex).append("\n");
211 mShowReceiveTxt.setText(receiveTxt.toString());
212 }
213
214 @Override
215 public void onComplete() {
216 Log.d(TAG, "完成");
217 }
218 });
219 }
220
221 @Override
222 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
223 switch (parent.getId()) {
224 case R.id.sph_path:
225 path = entryValues[position];
226 break;
227 case R.id.sph_baudRate:
228 String[] baud_rates = getResources().getStringArray(R.array.baud_rate_arr);
229 baudRate = Integer.parseInt(baud_rates[position]);
230 break;
231 case R.id.sph_data:
232 String[] data_rates = getResources().getStringArray(R.array.data_bits_arr);
233 dataBits = Integer.parseInt(data_rates[position]);
234 break;
235 case R.id.sph_check:
236 String[] check_rates = getResources().getStringArray(R.array.check_digit_arr);
237 checkBits = check_rates[position].charAt(0);
238 break;
239 case R.id.sph_stop:
240 String[] stop_rates = getResources().getStringArray(R.array.stop_bits_arr);
241 stopBits = Integer.parseInt(stop_rates[position]);
242 break;
243 default:
244 break;
245 }
246 }
247
248 @Override
249 public void onNothingSelected(AdapterView<?> parent) {
250
251 }
252
253 private void showState(){
254 if(isOpen){
255 Toast.makeText(this,"串口打开成功!",Toast.LENGTH_LONG).show();
256 mOpenBtn.setText("关闭串口");
257 mOpenBtn.setTextColor(ContextCompat.getColor(this,R.color.org));
258 mOpenBtn.setBackgroundResource(R.drawable.button_style_stroke);
259 }else {
260 mOpenBtn.setText("打开串口");
261 mOpenBtn.setTextColor(ContextCompat.getColor(this,R.color.white));
262 mOpenBtn.setBackgroundResource(R.drawable.button_style_org);
263 }
264 }
265
266
267 public void clearSend(View view) {
268 mSendDataEt.setText("");
269 }
270
271 public void clearReceive(View view) {
272 receiveTxt = new StringBuilder();
273 mShowReceiveTxt.setText("");
274 }
275 }
1 <vector xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:aapt="http://schemas.android.com/aapt"
3 android:width="108dp"
4 android:height="108dp"
5 android:viewportWidth="108"
6 android:viewportHeight="108">
7 <path
8 android:fillType="evenOdd"
9 android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
10 android:strokeWidth="1"
11 android:strokeColor="#00000000">
12 <aapt:attr name="android:fillColor">
13 <gradient
14 android:endX="78.5885"
15 android:endY="90.9159"
16 android:startX="48.7653"
17 android:startY="61.0927"
18 android:type="linear">
19 <item
20 android:color="#44000000"
21 android:offset="0.0" />
22 <item
23 android:color="#00000000"
24 android:offset="1.0" />
25 </gradient>
26 </aapt:attr>
27 </path>
28 <path
29 android:fillColor="#FFFFFF"
30 android:fillType="nonZero"
31 android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
32 android:strokeWidth="1"
33 android:strokeColor="#00000000" />
34 </vector>
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3 <corners android:radius="8dp" />
4 <solid android:color="#e17808" />
5 <stroke android:color="#e17808" android:width="1dp"/>
6 </shape>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3 <corners android:radius="8dp" />
4 <solid android:color="#fffef9" />
5 <stroke android:color="#e17808" android:width="1dp"/>
6 </shape>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3 <corners android:radius="8dp" />
4 <solid android:color="#fffef9" />
5 <stroke android:color="#303030" android:width="1dp"/>
6 </shape>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <vector xmlns:android="http://schemas.android.com/apk/res/android"
3 android:width="108dp"
4 android:height="108dp"
5 android:viewportWidth="108"
6 android:viewportHeight="108">
7 <path
8 android:fillColor="#008577"
9 android:pathData="M0,0h108v108h-108z" />
10 <path
11 android:fillColor="#00000000"
12 android:pathData="M9,0L9,108"
13 android:strokeWidth="0.8"
14 android:strokeColor="#33FFFFFF" />
15 <path
16 android:fillColor="#00000000"
17 android:pathData="M19,0L19,108"
18 android:strokeWidth="0.8"
19 android:strokeColor="#33FFFFFF" />
20 <path
21 android:fillColor="#00000000"
22 android:pathData="M29,0L29,108"
23 android:strokeWidth="0.8"
24 android:strokeColor="#33FFFFFF" />
25 <path
26 android:fillColor="#00000000"
27 android:pathData="M39,0L39,108"
28 android:strokeWidth="0.8"
29 android:strokeColor="#33FFFFFF" />
30 <path
31 android:fillColor="#00000000"
32 android:pathData="M49,0L49,108"
33 android:strokeWidth="0.8"
34 android:strokeColor="#33FFFFFF" />
35 <path
36 android:fillColor="#00000000"
37 android:pathData="M59,0L59,108"
38 android:strokeWidth="0.8"
39 android:strokeColor="#33FFFFFF" />
40 <path
41 android:fillColor="#00000000"
42 android:pathData="M69,0L69,108"
43 android:strokeWidth="0.8"
44 android:strokeColor="#33FFFFFF" />
45 <path
46 android:fillColor="#00000000"
47 android:pathData="M79,0L79,108"
48 android:strokeWidth="0.8"
49 android:strokeColor="#33FFFFFF" />
50 <path
51 android:fillColor="#00000000"
52 android:pathData="M89,0L89,108"
53 android:strokeWidth="0.8"
54 android:strokeColor="#33FFFFFF" />
55 <path
56 android:fillColor="#00000000"
57 android:pathData="M99,0L99,108"
58 android:strokeWidth="0.8"
59 android:strokeColor="#33FFFFFF" />
60 <path
61 android:fillColor="#00000000"
62 android:pathData="M0,9L108,9"
63 android:strokeWidth="0.8"
64 android:strokeColor="#33FFFFFF" />
65 <path
66 android:fillColor="#00000000"
67 android:pathData="M0,19L108,19"
68 android:strokeWidth="0.8"
69 android:strokeColor="#33FFFFFF" />
70 <path
71 android:fillColor="#00000000"
72 android:pathData="M0,29L108,29"
73 android:strokeWidth="0.8"
74 android:strokeColor="#33FFFFFF" />
75 <path
76 android:fillColor="#00000000"
77 android:pathData="M0,39L108,39"
78 android:strokeWidth="0.8"
79 android:strokeColor="#33FFFFFF" />
80 <path
81 android:fillColor="#00000000"
82 android:pathData="M0,49L108,49"
83 android:strokeWidth="0.8"
84 android:strokeColor="#33FFFFFF" />
85 <path
86 android:fillColor="#00000000"
87 android:pathData="M0,59L108,59"
88 android:strokeWidth="0.8"
89 android:strokeColor="#33FFFFFF" />
90 <path
91 android:fillColor="#00000000"
92 android:pathData="M0,69L108,69"
93 android:strokeWidth="0.8"
94 android:strokeColor="#33FFFFFF" />
95 <path
96 android:fillColor="#00000000"
97 android:pathData="M0,79L108,79"
98 android:strokeWidth="0.8"
99 android:strokeColor="#33FFFFFF" />
100 <path
101 android:fillColor="#00000000"
102 android:pathData="M0,89L108,89"
103 android:strokeWidth="0.8"
104 android:strokeColor="#33FFFFFF" />
105 <path
106 android:fillColor="#00000000"
107 android:pathData="M0,99L108,99"
108 android:strokeWidth="0.8"
109 android:strokeColor="#33FFFFFF" />
110 <path
111 android:fillColor="#00000000"
112 android:pathData="M19,29L89,29"
113 android:strokeWidth="0.8"
114 android:strokeColor="#33FFFFFF" />
115 <path
116 android:fillColor="#00000000"
117 android:pathData="M19,39L89,39"
118 android:strokeWidth="0.8"
119 android:strokeColor="#33FFFFFF" />
120 <path
121 android:fillColor="#00000000"
122 android:pathData="M19,49L89,49"
123 android:strokeWidth="0.8"
124 android:strokeColor="#33FFFFFF" />
125 <path
126 android:fillColor="#00000000"
127 android:pathData="M19,59L89,59"
128 android:strokeWidth="0.8"
129 android:strokeColor="#33FFFFFF" />
130 <path
131 android:fillColor="#00000000"
132 android:pathData="M19,69L89,69"
133 android:strokeWidth="0.8"
134 android:strokeColor="#33FFFFFF" />
135 <path
136 android:fillColor="#00000000"
137 android:pathData="M19,79L89,79"
138 android:strokeWidth="0.8"
139 android:strokeColor="#33FFFFFF" />
140 <path
141 android:fillColor="#00000000"
142 android:pathData="M29,19L29,89"
143 android:strokeWidth="0.8"
144 android:strokeColor="#33FFFFFF" />
145 <path
146 android:fillColor="#00000000"
147 android:pathData="M39,19L39,89"
148 android:strokeWidth="0.8"
149 android:strokeColor="#33FFFFFF" />
150 <path
151 android:fillColor="#00000000"
152 android:pathData="M49,19L49,89"
153 android:strokeWidth="0.8"
154 android:strokeColor="#33FFFFFF" />
155 <path
156 android:fillColor="#00000000"
157 android:pathData="M59,19L59,89"
158 android:strokeWidth="0.8"
159 android:strokeColor="#33FFFFFF" />
160 <path
161 android:fillColor="#00000000"
162 android:pathData="M69,19L69,89"
163 android:strokeWidth="0.8"
164 android:strokeColor="#33FFFFFF" />
165 <path
166 android:fillColor="#00000000"
167 android:pathData="M79,19L79,89"
168 android:strokeWidth="0.8"
169 android:strokeColor="#33FFFFFF" />
170 </vector>
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 android:orientation="horizontal"
6 android:focusableInTouchMode="true"
7 android:focusable="true">
8
9
10 <LinearLayout
11 android:layout_width="0dp"
12 android:layout_height="match_parent"
13 android:layout_weight="1.0"
14 android:orientation="vertical"
15 android:padding="10dp">
16
17 <TextView
18 android:layout_width="wrap_content"
19 android:layout_height="wrap_content"
20 android:layout_marginBottom="10dp"
21 android:text="串口设置"/>
22
23 <LinearLayout
24 android:layout_width="match_parent"
25 android:layout_height="wrap_content"
26 android:background="@drawable/button_style_stroke2"
27 android:orientation="vertical"
28 android:layout_marginRight="15dp"
29 android:padding="10dp">
30
31 <LinearLayout
32 android:layout_width="match_parent"
33 android:layout_height="wrap_content"
34 android:gravity="center_vertical"
35 android:orientation="horizontal">
36
37
38 <TextView
39 android:layout_width="wrap_content"
40 android:layout_height="wrap_content"
41 android:text="串口地址:" />
42
43 <Spinner
44 android:id="@+id/sph_path"
45 android:layout_width="wrap_content"
46 android:layout_height="wrap_content"
47 android:layout_weight="1" />
48
49 </LinearLayout>
50
51 <LinearLayout
52 android:layout_width="match_parent"
53 android:layout_height="wrap_content"
54 android:layout_marginTop="10dp"
55 android:gravity="center_vertical"
56 android:orientation="horizontal">
57
58
59 <TextView
60 android:layout_width="wrap_content"
61 android:layout_height="wrap_content"
62 android:text="波特率:" />
63
64 <Spinner
65 android:id="@+id/sph_baudRate"
66 android:layout_width="wrap_content"
67 android:layout_height="wrap_content"
68 android:layout_weight="1"
69 android:entries="@array/baud_rate_arr"/>
70
71 </LinearLayout>
72
73 <LinearLayout
74 android:layout_width="match_parent"
75 android:layout_height="wrap_content"
76 android:layout_marginTop="10dp"
77 android:gravity="center_vertical"
78 android:orientation="horizontal">
79
80
81 <TextView
82 android:layout_width="wrap_content"
83 android:layout_height="wrap_content"
84 android:text="数据位:" />
85
86 <Spinner
87 android:id="@+id/sph_data"
88 android:layout_width="wrap_content"
89 android:layout_height="wrap_content"
90 android:layout_weight="1"
91 android:entries="@array/data_bits_arr"/>
92
93 </LinearLayout>
94
95
96 <LinearLayout
97 android:layout_width="match_parent"
98 android:layout_height="wrap_content"
99 android:layout_marginTop="10dp"
100 android:gravity="center_vertical"
101 android:orientation="horizontal">
102
103 <TextView
104 android:layout_width="wrap_content"
105 android:layout_height="wrap_content"
106 android:text="校验位:" />
107
108 <Spinner
109 android:id="@+id/sph_check"
110 android:layout_width="wrap_content"
111 android:layout_height="wrap_content"
112 android:layout_weight="1"
113 android:entries="@array/check_digit_arr"/>
114
115 </LinearLayout>
116
117 <LinearLayout
118 android:layout_width="match_parent"
119 android:layout_height="wrap_content"
120 android:layout_marginTop="10dp"
121 android:gravity="center_vertical"
122 android:orientation="horizontal">
123
124
125 <TextView
126 android:layout_width="wrap_content"
127 android:layout_height="wrap_content"
128 android:text="停止位:" />
129
130 <Spinner
131 android:id="@+id/sph_stop"
132 android:layout_width="wrap_content"
133 android:layout_height="wrap_content"
134 android:layout_weight="1"
135 android:entries="@array/stop_bits_arr"/>
136
137 </LinearLayout>
138 </LinearLayout>
139
140
141 <Button
142 android:id="@+id/sph_openBtn"
143 android:layout_width="wrap_content"
144 android:layout_height="wrap_content"
145 android:layout_marginTop="10dp"
146 android:background="@drawable/button_style_org"
147 android:text="打开串口" />
148 <LinearLayout
149 android:id="@+id/ll"
150 android:layout_width="match_parent"
151 android:layout_height="wrap_content"
152 android:orientation="vertical">
153
154 <TextView
155 android:layout_width="wrap_content"
156 android:layout_height="wrap_content"
157 android:text="输入皮重" />
158
159 <EditText
160 android:id="@+id/et"
161 android:layout_width="match_parent"
162 android:layout_height="50dp"
163 android:hint="输入皮重"
164 android:text="1" />
165
166 <TextView
167 android:layout_width="wrap_content"
168 android:layout_height="wrap_content"
169 android:text="输入重量" />
170
171 <EditText
172 android:id="@+id/et2"
173 android:layout_width="match_parent"
174 android:layout_height="50dp"
175 android:hint="输入重量"
176 android:text="2.00" />
177
178 <TextView
179 android:layout_width="wrap_content"
180 android:layout_height="wrap_content"
181 android:text="输入单价" />
182
183 <EditText
184 android:id="@+id/et3"
185 android:layout_width="match_parent"
186 android:layout_height="50dp"
187 android:hint="输入单价"
188 android:text="3" />
189
190 <TextView
191 android:layout_width="wrap_content"
192 android:layout_height="wrap_content"
193 android:text="输入总价" />
194
195 <EditText
196 android:id="@+id/et4"
197 android:layout_width="match_parent"
198 android:layout_height="50dp"
199 android:hint="输入总价"
200 android:text="4.55" />
201
202
203
204 <Button
205 android:id="@+id/bt"
206 android:layout_width="wrap_content"
207 android:layout_height="wrap_content"
208 android:layout_gravity="center"
209 android:background="#000fff"
210 android:padding="10dp"
211 android:text="生成"
212 android:textColor="@color/white" />
213
214 </LinearLayout>
215
216 </LinearLayout>
217
218 <View
219 android:layout_width="1dp"
220 android:layout_height="match_parent"
221 android:background="#303030" />
222
223
224 <LinearLayout
225 android:layout_width="0dp"
226 android:layout_height="match_parent"
227 android:layout_marginLeft="20dp"
228 android:layout_weight="1.0"
229 android:orientation="vertical"
230 android:padding="10dp">
231
232 <LinearLayout
233 android:layout_width="match_parent"
234 android:layout_height="wrap_content"
235 android:layout_marginBottom="10dp"
236 android:orientation="horizontal"
237 android:gravity="center_vertical">
238 <TextView
239 android:layout_width="wrap_content"
240 android:layout_height="wrap_content"
241 android:layout_weight="1.0"
242 android:text="接收数据:" />
243
244 <Button
245 android:layout_width="wrap_content"
246 android:layout_height="wrap_content"
247 android:background="@drawable/button_style_org"
248 android:onClick="clearReceive"
249 android:textColor="#fffef9"
250 android:text="清空" />
251
252 </LinearLayout>
253
254 <ScrollView
255 android:layout_width="match_parent"
256 android:layout_height="0dp"
257 android:layout_weight="1.0"
258 android:padding="5dp"
259 android:background="@drawable/button_style_stroke">
260 <TextView
261 android:id="@+id/sph_showReceiveTxt"
262 android:layout_width="match_parent"
263 android:layout_height="match_parent"
264 />
265 </ScrollView>
266
267
268
269
270 <LinearLayout
271 android:layout_width="match_parent"
272 android:layout_height="wrap_content"
273 android:layout_marginTop="25dp"
274 android:layout_marginBottom="10dp"
275 android:orientation="horizontal"
276 android:gravity="center_vertical">
277
278 <TextView
279 android:layout_width="wrap_content"
280 android:layout_height="wrap_content"
281 android:layout_weight="1.0"
282 android:text="发送数据:" />
283
284 <Button
285 android:layout_width="wrap_content"
286 android:layout_height="wrap_content"
287 android:background="@drawable/button_style_org"
288 android:onClick="clearSend"
289 android:textColor="#fffef9"
290 android:text="清空" />
291
292 </LinearLayout>
293
294 <EditText
295 android:id="@+id/sph_sendDataEt"
296 android:layout_width="match_parent"
297 android:layout_height="wrap_content"
298 android:background="@drawable/button_style_stroke"
299 android:lines="2" />
300
301 <Button
302 android:id="@+id/sph_sendBtn"
303 android:layout_width="match_parent"
304 android:layout_height="wrap_content"
305 android:layout_marginTop="10dp"
306 android:background="@drawable/button_style_org"
307 android:text="发送"
308 android:textColor="#fffef9" />
309
310 </LinearLayout>
311
312
313
314 </LinearLayout>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3 <background android:drawable="@drawable/ic_launcher_background" />
4 <foreground android:drawable="@drawable/ic_launcher_foreground" />
5 </adaptive-icon>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3 <background android:drawable="@drawable/ic_launcher_background" />
4 <foreground android:drawable="@drawable/ic_launcher_foreground" />
5 </adaptive-icon>
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3
4 <string-array name="baud_rate_arr">
5 <item>0</item>
6 <item>50</item>
7 <item>75</item>
8 <item>110</item>
9 <item>134</item>
10 <item>150</item>
11 <item>200</item>
12 <item>300</item>
13 <item>600</item>
14 <item>1200</item>
15 <item>1800</item>
16 <item>2400</item>
17 <item>4800</item>
18 <item>9600</item>
19 <item>19200</item>
20 <item>38400</item>
21 <item>57600</item>
22 <item>115200</item>
23 <item>230400</item>
24 <item>460800</item>
25 <item>500000</item>
26 <item>576000</item>
27 <item>921600</item>
28 <item>1000000</item>
29 <item>1152000</item>
30 <item>1500000</item>
31 <item>2000000</item>
32 <item>2500000</item>
33 <item>3000000</item>
34 <item>3500000</item>
35 <item>4000000</item>
36 </string-array>
37
38
39 <string-array name="check_digit_arr">
40 <item>N</item>
41 <item>E</item>
42 <item>O</item>
43 </string-array>
44
45
46 <string-array name="data_bits_arr">
47 <item>5</item>
48 <item>6</item>
49 <item>7</item>
50 <item>8</item>
51 </string-array>
52
53
54 <string-array name="stop_bits_arr">
55 <item>1</item>
56 <item>2</item>
57 </string-array>
58 </resources>
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <color name="colorPrimary">#008577</color>
4 <color name="colorPrimaryDark">#00574B</color>
5 <color name="colorAccent">#D81B60</color>
6
7
8 <color name="white">#fffef9</color>
9 <color name="org">#e17808</color>
10
11 </resources>
1 <resources>
2 <string name="app_name">SerialPortHelper</string>
3 </resources>
1 <resources>
2
3 <!-- Base application theme. -->
4 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
5 <!-- Customize your theme here. -->
6 <item name="colorPrimary">@color/colorPrimary</item>
7 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
8 <item name="colorAccent">@color/colorAccent</item>
9 </style>
10
11 </resources>
1 package top.keepempty;
2
3 import org.junit.Test;
4
5
6 /**
7 * Example local unit test, which will execute on the development machine (host).
8 *
9 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
10 */
11 public class ExampleUnitTest {
12 @Test
13 public void addition_isCorrect() {
14 System.out.println(decodeHexString("A"));
15 System.out.println(decToHex(13));
16 }
17
18 public static String decToHex(int dec
19 ){
20 String hex = Integer.toHexString(dec);
21 if (hex.length() == 1) {
22 hex = '0' + hex;
23 }
24 return hex.toLowerCase();
25 }
26
27
28 public static byte[] decodeHexString(String hexString) {
29 if (hexString.length() % 2 == 1) {
30 throw new IllegalArgumentException(
31 "Invalid hexadecimal String supplied.");
32 }
33 byte[] bytes = new byte[hexString.length() / 2];
34 for (int i = 0; i < hexString.length(); i += 2) {
35 bytes[i / 2] = hexToByte(hexString.substring(i, i + 2));
36 }
37 return bytes;
38 }
39
40
41 public static byte hexToByte(String hexString) {
42 int firstDigit = toDigit(hexString.charAt(0));
43 int secondDigit = toDigit(hexString.charAt(1));
44 return (byte) ((firstDigit << 4) + secondDigit);
45 }
46
47 private static int toDigit(char hexChar) {
48 int digit = Character.digit(hexChar, 16);
49 if(digit == -1) {
50 throw new IllegalArgumentException(
51 "Invalid Hexadecimal Character: "+ hexChar);
52 }
53 return digit;
54 }
55
56 }
...\ No newline at end of file ...\ No newline at end of file
1 // Top-level build file where you can add configuration options common to all sub-projects/modules.
2
3 buildscript {
4 repositories {
5 google()
6 jcenter()
7 mavenCentral()
8 }
9 dependencies {
10 classpath 'com.android.tools.build:gradle:3.4.2'
11 classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
12 // NOTE: Do not place your application dependencies here; they belong
13 // in the individual module build.gradle files
14 }
15 }
16
17 allprojects {
18 repositories {
19 google()
20 jcenter()
21 mavenCentral()
22 maven { url 'https://www.jitpack.io' }
23 }
24 }
25
26 task clean(type: Delete) {
27 delete rootProject.buildDir
28 }
1 /build
...\ No newline at end of file ...\ No newline at end of file
1 plugins {
2 id 'com.android.library'
3 }
4
5 android {
6 namespace 'com.example.ddtest'
7 compileSdkVersion 28
8
9 defaultConfig {
10 minSdkVersion 19
11 }
12
13 buildTypes {
14 release {
15 minifyEnabled false
16 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
17 }
18 }
19 compileOptions {
20 sourceCompatibility JavaVersion.VERSION_1_8
21 targetCompatibility JavaVersion.VERSION_1_8
22 }
23 }
24
25 dependencies {
26 }
...\ No newline at end of file ...\ No newline at end of file
File mode changed
1 # Add project specific ProGuard rules here.
2 # You can control the set of applied configuration files using the
3 # proguardFiles setting in build.gradle.
4 #
5 # For more details, see
6 # http://developer.android.com/guide/developing/tools/proguard.html
7
8 # If your project uses WebView with JS, uncomment the following
9 # and specify the fully qualified class name to the JavaScript interface
10 # class:
11 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 # public *;
13 #}
14
15 # Uncomment this to preserve the line number information for
16 # debugging stack traces.
17 #-keepattributes SourceFile,LineNumberTable
18
19 # If you keep the line number information, uncomment this to
20 # hide the original source file name.
21 #-renamesourcefileattribute SourceFile
...\ No newline at end of file ...\ No newline at end of file
1 package com.example.ddtest;
2
3 import android.content.Context;
4 import android.support.test.InstrumentationRegistry;
5 import android.support.test.runner.AndroidJUnit4;
6
7 import org.junit.Test;
8 import org.junit.runner.RunWith;
9
10 import static org.junit.Assert.*;
11
12 /**
13 * Instrumented test, which will execute on an Android device.
14 *
15 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
16 */
17 @RunWith(AndroidJUnit4.class)
18 public class ExampleInstrumentedTest {
19 @Test
20 public void useAppContext() {
21 // Context of the app under test.
22 Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
23 assertEquals("com.example.ddtest.test", appContext.getPackageName());
24 }
25 }
...\ No newline at end of file ...\ No newline at end of file
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
4 </manifest>
...\ No newline at end of file ...\ No newline at end of file
1 package top.keepempty.utils;
2
3 import java.io.UnsupportedEncodingException;
4
5 public class HexTool {
6
7 private static final String UTF_16BE = "UTF-16BE";
8 private static final String PREFIX = "5A A5";
9 private static final String TERMINATOR = "00 00";
10
11 // 构建标准指令
12 public static String buildCommand(String text, String commandCode) {
13 try {
14 byte[] bytes = text.getBytes(UTF_16BE);
15 StringBuilder hexBuilder = new StringBuilder();
16
17 hexBuilder.append(PREFIX)
18 .append(getHexBytes(bytes))
19 .append(" 00 00 ")
20 .append(getLengthHex(bytes.length));
21
22 return hexBuilder.toString().replace(" ", "");
23 } catch (UnsupportedEncodingException e) {
24 e.printStackTrace();
25 return "";
26 }
27 }
28
29 private static String getHexBytes(byte[] bytes) {
30 StringBuilder sb = new StringBuilder();
31 for (byte b : bytes) {
32 sb.append(String.format("%02X", b));
33 }
34 return sb.toString();
35 }
36
37 private static String getLengthHex(int length) {
38 return String.format(" %02X", length);
39 }
40
41 // 生成最终指令
42 public static String generateFinalHex(
43 String pizhong, String zhongliang,
44 String danjia, String zongjia) {
45 return buildCommand("皮重", "10 00") +
46 buildCommand(pizhong, "20 00") +
47 buildCommand("重量", "30 00") +
48 buildCommand(zhongliang, "40 00") +
49 buildCommand("单价 元", "50 00") +
50 buildCommand(danjia, "60 00") +
51 buildCommand("总价 元", "70 00") +
52 buildCommand(zongjia, "80 00") +
53 "0000";
54 }
55 }
...\ No newline at end of file ...\ No newline at end of file
1 package com.example.ddtest;
2
3 import org.junit.Test;
4
5 import static org.junit.Assert.*;
6
7 /**
8 * Example local unit test, which will execute on the development machine (host).
9 *
10 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
11 */
12 public class ExampleUnitTest {
13 @Test
14 public void addition_isCorrect() {
15 assertEquals(4, 2 + 2);
16 }
17 }
...\ No newline at end of file ...\ No newline at end of file
1 # Project-wide Gradle settings.
2 # IDE (e.g. Android Studio) users:
3 # Gradle settings configured through the IDE *will override*
4 # any settings specified in this file.
5 # For more details on how to configure your build environment visit
6 # http://www.gradle.org/docs/current/userguide/build_environment.html
7 # Specifies the JVM arguments used for the daemon process.
8 # The setting is particularly useful for tweaking memory settings.
9 org.gradle.jvmargs=-Xmx1536m
10 # When configured, Gradle will run in incubating parallel mode.
11 # This option should only be used with decoupled projects. More details, visit
12 # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 # org.gradle.parallel=true
14
15
No preview for this file type
1 #Wed Jul 10 10:10:04 CST 2019
2 distributionBase=GRADLE_USER_HOME
3 distributionPath=wrapper/dists
4 zipStoreBase=GRADLE_USER_HOME
5 zipStorePath=wrapper/dists
6 distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
1 #!/usr/bin/env sh
2
3 ##############################################################################
4 ##
5 ## Gradle start up script for UN*X
6 ##
7 ##############################################################################
8
9 # Attempt to set APP_HOME
10 # Resolve links: $0 may be a link
11 PRG="$0"
12 # Need this for relative symlinks.
13 while [ -h "$PRG" ] ; do
14 ls=`ls -ld "$PRG"`
15 link=`expr "$ls" : '.*-> \(.*\)$'`
16 if expr "$link" : '/.*' > /dev/null; then
17 PRG="$link"
18 else
19 PRG=`dirname "$PRG"`"/$link"
20 fi
21 done
22 SAVED="`pwd`"
23 cd "`dirname \"$PRG\"`/" >/dev/null
24 APP_HOME="`pwd -P`"
25 cd "$SAVED" >/dev/null
26
27 APP_NAME="Gradle"
28 APP_BASE_NAME=`basename "$0"`
29
30 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 DEFAULT_JVM_OPTS=""
32
33 # Use the maximum available, or set MAX_FD != -1 to use that value.
34 MAX_FD="maximum"
35
36 warn () {
37 echo "$*"
38 }
39
40 die () {
41 echo
42 echo "$*"
43 echo
44 exit 1
45 }
46
47 # OS specific support (must be 'true' or 'false').
48 cygwin=false
49 msys=false
50 darwin=false
51 nonstop=false
52 case "`uname`" in
53 CYGWIN* )
54 cygwin=true
55 ;;
56 Darwin* )
57 darwin=true
58 ;;
59 MINGW* )
60 msys=true
61 ;;
62 NONSTOP* )
63 nonstop=true
64 ;;
65 esac
66
67 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68
69 # Determine the Java command to use to start the JVM.
70 if [ -n "$JAVA_HOME" ] ; then
71 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 # IBM's JDK on AIX uses strange locations for the executables
73 JAVACMD="$JAVA_HOME/jre/sh/java"
74 else
75 JAVACMD="$JAVA_HOME/bin/java"
76 fi
77 if [ ! -x "$JAVACMD" ] ; then
78 die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79
80 Please set the JAVA_HOME variable in your environment to match the
81 location of your Java installation."
82 fi
83 else
84 JAVACMD="java"
85 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86
87 Please set the JAVA_HOME variable in your environment to match the
88 location of your Java installation."
89 fi
90
91 # Increase the maximum file descriptors if we can.
92 if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 MAX_FD_LIMIT=`ulimit -H -n`
94 if [ $? -eq 0 ] ; then
95 if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 MAX_FD="$MAX_FD_LIMIT"
97 fi
98 ulimit -n $MAX_FD
99 if [ $? -ne 0 ] ; then
100 warn "Could not set maximum file descriptor limit: $MAX_FD"
101 fi
102 else
103 warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 fi
105 fi
106
107 # For Darwin, add options to specify how the application appears in the dock
108 if $darwin; then
109 GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 fi
111
112 # For Cygwin, switch paths to Windows format before running java
113 if $cygwin ; then
114 APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 JAVACMD=`cygpath --unix "$JAVACMD"`
117
118 # We build the pattern for arguments to be converted via cygpath
119 ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 SEP=""
121 for dir in $ROOTDIRSRAW ; do
122 ROOTDIRS="$ROOTDIRS$SEP$dir"
123 SEP="|"
124 done
125 OURCYGPATTERN="(^($ROOTDIRS))"
126 # Add a user-defined pattern to the cygpath arguments
127 if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 fi
130 # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 i=0
132 for arg in "$@" ; do
133 CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135
136 if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 else
139 eval `echo args$i`="\"$arg\""
140 fi
141 i=$((i+1))
142 done
143 case $i in
144 (0) set -- ;;
145 (1) set -- "$args0" ;;
146 (2) set -- "$args0" "$args1" ;;
147 (3) set -- "$args0" "$args1" "$args2" ;;
148 (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 esac
155 fi
156
157 # Escape application args
158 save () {
159 for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 echo " "
161 }
162 APP_ARGS=$(save "$@")
163
164 # Collect all arguments for the java command, following the shell quoting and substitution rules
165 eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166
167 # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 cd "$(dirname "$0")"
170 fi
171
172 exec "$JAVACMD" "$@"
1 @if "%DEBUG%" == "" @echo off
2 @rem ##########################################################################
3 @rem
4 @rem Gradle startup script for Windows
5 @rem
6 @rem ##########################################################################
7
8 @rem Set local scope for the variables with windows NT shell
9 if "%OS%"=="Windows_NT" setlocal
10
11 set DIRNAME=%~dp0
12 if "%DIRNAME%" == "" set DIRNAME=.
13 set APP_BASE_NAME=%~n0
14 set APP_HOME=%DIRNAME%
15
16 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 set DEFAULT_JVM_OPTS=
18
19 @rem Find java.exe
20 if defined JAVA_HOME goto findJavaFromJavaHome
21
22 set JAVA_EXE=java.exe
23 %JAVA_EXE% -version >NUL 2>&1
24 if "%ERRORLEVEL%" == "0" goto init
25
26 echo.
27 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 echo.
29 echo Please set the JAVA_HOME variable in your environment to match the
30 echo location of your Java installation.
31
32 goto fail
33
34 :findJavaFromJavaHome
35 set JAVA_HOME=%JAVA_HOME:"=%
36 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
38 if exist "%JAVA_EXE%" goto init
39
40 echo.
41 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 echo.
43 echo Please set the JAVA_HOME variable in your environment to match the
44 echo location of your Java installation.
45
46 goto fail
47
48 :init
49 @rem Get command-line arguments, handling Windows variants
50
51 if not "%OS%" == "Windows_NT" goto win9xME_args
52
53 :win9xME_args
54 @rem Slurp the command line arguments.
55 set CMD_LINE_ARGS=
56 set _SKIP=2
57
58 :win9xME_args_slurp
59 if "x%~1" == "x" goto execute
60
61 set CMD_LINE_ARGS=%*
62
63 :execute
64 @rem Setup the command line
65
66 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
68 @rem Execute Gradle
69 "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
71 :end
72 @rem End local scope for the variables with windows NT shell
73 if "%ERRORLEVEL%"=="0" goto mainEnd
74
75 :fail
76 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 rem the _cmd.exe /c_ return code!
78 if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 exit /b 1
80
81 :mainEnd
82 if "%OS%"=="Windows_NT" endlocal
83
84 :omega
1 include ':app'
2 include ':ddtest'
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!