Browse Source

存储小板喷漆拉毛二合一app

master 喷漆拉毛二合一
DESKTOP-1PDT1EL\10564 3 weeks ago
commit
92d7be4db3
  1. 15
      .gitignore
  2. 3
      .idea/.gitignore
  3. 1
      .idea/.name
  4. 6
      .idea/compiler.xml
  5. 10
      .idea/deploymentTargetDropDown.xml
  6. 18
      .idea/deploymentTargetSelector.xml
  7. 20
      .idea/gradle.xml
  8. 10
      .idea/migrations.xml
  9. 9
      .idea/misc.xml
  10. 6
      .idea/render.experimental.xml
  11. 17
      .idea/runConfigurations.xml
  12. 6
      .idea/vcs.xml
  13. 0
      README.md
  14. 1
      app/.gitignore
  15. 58
      app/build.gradle
  16. 21
      app/proguard-rules.pro
  17. 20
      app/release/output-metadata.json
  18. 26
      app/src/androidTest/java/com/example/paint_rough_inone_appv1_0/ExampleInstrumentedTest.java
  19. 59
      app/src/main/AndroidManifest.xml
  20. BIN
      app/src/main/assets/fonts/font_you_yuan.ttf
  21. 41
      app/src/main/java/bsp_Error.proto
  22. 2
      app/src/main/java/bsp_IV.options
  23. 23
      app/src/main/java/bsp_IV.proto
  24. 19
      app/src/main/java/bsp_PV.proto
  25. 50
      app/src/main/java/com/example/paint_rough_inone_appv1_0/BaseChildActivity.java
  26. 185
      app/src/main/java/com/example/paint_rough_inone_appv1_0/DataExchangeService.java
  27. 21
      app/src/main/java/com/example/paint_rough_inone_appv1_0/IVDataReceivedEvent.java
  28. 45
      app/src/main/java/com/example/paint_rough_inone_appv1_0/MainActivity.java
  29. 322
      app/src/main/java/com/example/paint_rough_inone_appv1_0/PaintActivity.java
  30. 384
      app/src/main/java/com/example/paint_rough_inone_appv1_0/RoughActivity.java
  31. 1678
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/BspError.java
  32. 1718
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/BspIV.java
  33. 1535
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/BspPV.java
  34. 50
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/DisplayIV.java
  35. 90
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/DisplayPV.java
  36. 44
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/ErrorModel.java
  37. 43
      app/src/main/java/com/example/paint_rough_inone_appv1_0/models/ScrollBottomScrollView.java
  38. 26
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ConvertHelper.java
  39. 22
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/CustomProber.java
  40. 71
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/DecimalDigitsInputFilter.java
  41. 42
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ErrorDeocdeHelper.java
  42. 39
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/LogUtil.java
  43. 72
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ModbusCRC.java
  44. 368
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/MyDataHelper.java
  45. 736
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/PopupHelper.java
  46. 373
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ReceiivedIVHandler.java
  47. 63
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/RobotDataHanlder.java
  48. 53
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ToggleRadioButton.java
  49. 528
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/USBSerialPortHelper.java
  50. 27
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/VideoPlayerHelper.java
  51. 85
      app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ttySerialPortHelper.java
  52. 185
      app/src/main/java/com/example/paint_rough_inone_appv1_0/viewmodels/DataExchangeService.java
  53. 11
      app/src/main/java/com/example/paint_rough_inone_appv1_0/viewmodels/MainViewModel.java
  54. 2
      app/src/main/java/generate_java.bat
  55. BIN
      app/src/main/java/protoc.exe
  56. 25
      app/src/main/res/drawable/background.xml
  57. BIN
      app/src/main/res/drawable/bgr.png
  58. 25
      app/src/main/res/drawable/blue_rounded_rectangle.xml
  59. 10
      app/src/main/res/drawable/border.xml
  60. 8
      app/src/main/res/drawable/border_active.xml
  61. 8
      app/src/main/res/drawable/border_inactive.xml
  62. 24
      app/src/main/res/drawable/borderblue.xml
  63. 24
      app/src/main/res/drawable/borderbluegreen.xml
  64. 31
      app/src/main/res/drawable/borderlog.xml
  65. 24
      app/src/main/res/drawable/borderorange.xml
  66. 24
      app/src/main/res/drawable/borderwhite.xml
  67. 18
      app/src/main/res/drawable/button_active.xml
  68. 11
      app/src/main/res/drawable/button_inactive.xml
  69. 24
      app/src/main/res/drawable/buttonborderwhite.xml
  70. 6
      app/src/main/res/drawable/container_active.xml
  71. 6
      app/src/main/res/drawable/container_inactive.xml
  72. 14
      app/src/main/res/drawable/dash_line.xml
  73. 170
      app/src/main/res/drawable/ic_launcher_background.xml
  74. 30
      app/src/main/res/drawable/ic_launcher_foreground.xml
  75. 26
      app/src/main/res/drawable/message_rounded_rectangle_red.xml
  76. 9
      app/src/main/res/drawable/my_cursor.xml
  77. 25
      app/src/main/res/drawable/orange_rounded_rectangle.xml
  78. 15
      app/src/main/res/drawable/radio_button_selected.xml
  79. 8
      app/src/main/res/drawable/radio_button_textcolor.xml
  80. 8
      app/src/main/res/drawable/radio_button_unselected.xml
  81. 5
      app/src/main/res/drawable/radiobutton_background.xml
  82. 28
      app/src/main/res/drawable/rounded_edittext.xml
  83. BIN
      app/src/main/res/drawable/squrelogo.png
  84. 24
      app/src/main/res/drawable/submenu.xml
  85. BIN
      app/src/main/res/font/font_you_yuan.ttf
  86. 78
      app/src/main/res/layout/activity_main.xml
  87. 549
      app/src/main/res/layout/activity_paint.xml
  88. 773
      app/src/main/res/layout/activity_rough.xml
  89. 31
      app/src/main/res/layout/log_item_paint.xml
  90. 31
      app/src/main/res/layout/log_item_rough.xml
  91. 145
      app/src/main/res/layout/paint_manualmodepopup.xml
  92. 207
      app/src/main/res/layout/parameters_call_paint.xml
  93. 207
      app/src/main/res/layout/parameters_call_rough.xml
  94. 210
      app/src/main/res/layout/rough_automodepopup.xml
  95. 159
      app/src/main/res/layout/rough_manualmodepopup.xml
  96. 6
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  97. 6
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  98. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.webp
  99. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
  100. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.webp

15
.gitignore

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

3
.idea/.gitignore

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
.idea/.name

@ -0,0 +1 @@
paintRoughInOneAPP_UDPV1_0

6
.idea/compiler.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

10
.idea/deploymentTargetDropDown.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
</entry>
</value>
</component>
</project>

18
.idea/deploymentTargetSelector.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-09-03T08:20:54.753159800Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=4b6bd490" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>

20
.idea/gradle.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

10
.idea/migrations.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

9
.idea/misc.xml

@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/render.experimental.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="showDecorations" value="true" />
</component>
</project>

17
.idea/runConfigurations.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

0
README.md

1
app/.gitignore

@ -0,0 +1 @@
/build

58
app/build.gradle

@ -0,0 +1,58 @@
plugins {
id 'com.android.application'
}
android {
namespace 'com.example.paint_rough_inone_appv1_0'
compileSdk 35
viewBinding
{
enabled true
}
// //add this feature
dataBinding
{
enabled true
}
defaultConfig {
applicationId "com.example.paint_rough_inone_appv1_0"
minSdk 24
targetSdk 35
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
buildFeatures{
buildConfig true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.activity:activity:1.8.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'com.github.mik3y:usb-serial-for-android:3.7.0'
implementation 'com.google.protobuf:protobuf-java:4.27.2'
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20")
implementation 'com.github.nodemedia:nodemediaclient-android:2.9.20'
implementation 'io.github.xmaihh:serialport:2.1.1'
implementation 'org.greenrobot:eventbus:3.3.1'
}

21
app/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

20
app/release/output-metadata.json

@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.example.rougheningapp",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}

26
app/src/androidTest/java/com/example/paint_rough_inone_appv1_0/ExampleInstrumentedTest.java

@ -0,0 +1,26 @@
package com.example.paint_rough_inone_appv1_0;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.example.rougheningapp", appContext.getPackageName());
}
}

59
app/src/main/AndroidManifest.xml

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-feature
android:name="android.hardware.usb.accessory"
android:required="false" />
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/squrelogo"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.RougheningApp"
tools:targetApi="31">
<activity
android:name=".PaintActivity"
android:exported="false"
android:launchMode="singleTop"/>
<!-- 添加RoughActivity的声明 -->
<activity
android:name=".RoughActivity"
android:exported="false"
android:launchMode="singleTop"/> <!-- 如果不需要被其他应用启动,设为false -->
<meta-data
android:name="com.google.android.actions"
android:resource="@xml/check_boxs" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
<service android:name=".DataExchangeService" />
</application>
</manifest>

BIN
app/src/main/assets/fonts/font_you_yuan.ttf

Binary file not shown.

41
app/src/main/java/bsp_Error.proto

@ -0,0 +1,41 @@
syntax = "proto3";
option java_multiple_files = false;
option java_package = "com.example.paint_rough_inone_appv1_0.models";
message ErrorDataInfo
{
int32 Error_Value = 1;
bytes Error_Name=4;
}
message ErrorData
{
int32 ErrorCode=1;
int32 Motor_1_Error=21;
int32 Motor_2_Error=22;
int32 Motor_3_Error=23;
int32 Motor_4_Error=24;
int32 Motor_5_Error=25;
int32 Motor_6_Error=26;
int32 Motor_7_Error=27;
}
enum ComError //
{
MK32_SBus = 0;
TL720D = 1;
LS_LeftMotor = 2;
LS_RightMotor = 3;
Remote_Button_Reset_State = 4;
CMCU06_Force_sensor = 5;
}
//protoc --nanopb_out=. *.proto

2
app/src/main/java/bsp_IV.options

@ -0,0 +1,2 @@
# lock.options
IV_struct_define.Buff_Data max_size:30 fixed_length:true

23
app/src/main/java/bsp_IV.proto

@ -0,0 +1,23 @@
syntax = "proto3";
option java_multiple_files = false;
option java_package = "com.example.paint_rough_inone_appv1_0.models";
message IV_struct_define
{
int32 Press=1;//
int32 RunMode=2;//
int32 LeftCompensation= 3; //0.01°
int32 RightCompensation= 4; //0.01°
int32 CurrentAngle= 5; //0.01°
int32 RobotMoveSpeed= 6; //m/min
int32 SystemError=7; //
int32 Left_Motor_Err=8;//
int32 Right_Motor_Err=9;//
int32 SBUS_State=10; //0 1
int32 CurrentSpeed=11;//
int64 TimeStamp=12;//
int32 IsRestart=13;//
int32 IsWorking=14;//
};

19
app/src/main/java/bsp_PV.proto

@ -0,0 +1,19 @@
syntax = "proto3";
option java_multiple_files = false;
option java_package = "com.example.paint_rough_inone_appv1_0.models";
message PV_struct_define{
//
int32 WorkMode=1; // 0 1 2
int32 RunMode = 2; // 1 2 3 4 5
int32 RobotSpeed=3; //0-30m/min
int32 LaneChangeDistance= 4; //1-100cm
double HorizontalDistanceMeters=5; // 0-200m
double VerticalDistanceMeters=6; // 0-200m
double Vertical_Calibration=7; //
int32 LeftCompensation= 8; //
int32 RightCompensation= 9; //
int32 PressSet=10; //
int32 IV_IsRestart_Notified=11;// IV restart flag
int64 TimeStamp=12;//
};

50
app/src/main/java/com/example/paint_rough_inone_appv1_0/BaseChildActivity.java

@ -0,0 +1,50 @@
package com.example.paint_rough_inone_appv1_0;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import androidx.appcompat.app.AppCompatActivity;
public abstract class BaseChildActivity extends AppCompatActivity {
protected DataExchangeService myService;
protected boolean isBound = false;
private final ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
DataExchangeService.ServiceBinder binder = (DataExchangeService.ServiceBinder) service;
myService = binder.getService();
isBound = true;
onServiceBound();
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 绑定服务
bindService(new Intent(this, DataExchangeService.class),
serviceConnection, Context.BIND_AUTO_CREATE);
}
protected abstract void onServiceBound();
@Override
protected void onDestroy() {
super.onDestroy();
// 解绑服务
if (isBound) {
unbindService(serviceConnection);
isBound = false;
}
}
}

185
app/src/main/java/com/example/paint_rough_inone_appv1_0/DataExchangeService.java

@ -0,0 +1,185 @@
package com.example.paint_rough_inone_appv1_0;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.example.paint_rough_inone_appv1_0.models.BspPV;
import com.example.paint_rough_inone_appv1_0.services.ModbusCRC;
import com.example.paint_rough_inone_appv1_0.services.USBSerialPortHelper;
import com.example.paint_rough_inone_appv1_0.services.ttySerialPortHelper;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.logging.Handler;
public class DataExchangeService extends Service {
//USB 串口服务
public USBSerialPortHelper serialPortHelper;
private static final String TAG = "UDPMyService";
// 服务中存储的数据
private static BspPV.PV_struct_define _toSendPV;
// 绑定服务通信接口
public class ServiceBinder extends Binder {
DataExchangeService getService() {
return DataExchangeService.this;
}
}
private final IBinder binder = new ServiceBinder();
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "服务被绑定");
return binder;
}
//首次启动时,会执行 onCreate() → onStartCommand();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "服务已启动");
//Intialize("192.168.18.30", 8006, 9006);
Intialize("192.168.144.98", 8006, 9006);
_toSendPV = BspPV.PV_struct_define.newBuilder()
.setWorkMode(0)
.build();
ttySerialPortHelper.Open();//启动串口
// 模拟后台任务
return START_STICKY;
}
//UDP Region
private static Thread receiveThread;
private static Thread sendThread;
private static boolean running = false;
private static boolean send_running = false;
private static DatagramSocket sendSocket;
private static DatagramSocket receiveSocket;
private static Handler handler;// = new Handler(Looper.getMainLooper());
private static String target_ip;
private static int target_port;
private static int listening_port;
public static void Intialize(String targetip, int targetPort, int listentingPort) {
try {
target_ip = targetip;
target_port = targetPort;
listening_port = listentingPort; //本地监听端口
sendSocket = new DatagramSocket(10000);// 创建发送套接字(绑定本地端口 10000)
//sendSocket.setBroadcast(true);
receiveSocket = new DatagramSocket(listening_port);// 创建接收套接字(绑定指定监听端口)
receiveSocket.setBroadcast(true);// 允许接收广播数据
running = true;
receiveThread = new Thread(() -> {
byte[] buffer = new byte[1024];// 数据缓冲区
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);//将数据打包成网络传输的数据包。
while (running) {
try {
receiveSocket.receive(packet);// 阻塞等待接收数据
byte[] receivedArray = new byte[packet.getLength()];// 提取有效数据(剔除缓冲区冗余部分)
System.arraycopy(packet.getData(), 0, receivedArray, 0, receivedArray.length);
// 通过 EventBus 发送事件,通知其他组件(如 Activity)
EventBus.getDefault().post(new IVDataReceivedEvent.IVReceived(receivedArray));
} catch (IOException e) {
if (running) {
}
}
}
});
receiveThread.start();
send_running=true;
sendThread= new Thread(() -> {
while (send_running) {
try {
Thread.sleep(200);
_toSendPV = _toSendPV.toBuilder().setTimeStamp(System.currentTimeMillis()).build();
SendPV(_toSendPV);
} catch (Exception e) {
}
}
});
sendThread.start();
} catch (IOException e) {
// tvOutput.setText("Socket error: " + e.getMessage());
}
}
public static void SendRawData(byte[] buffer) {
new Thread(() ->
{
DatagramSocket socket = null;
try {
InetAddress address = InetAddress.getByName(target_ip);
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, target_port);
sendSocket.send(packet);
} catch (Exception e) {
}
}).start();
ttySerialPortHelper.SendData(buffer);
}
private static void SendPV(BspPV.PV_struct_define toSendPV) {
byte[] byteArray = toSendPV.toByteArray();
byte[] sendbyteArray = new byte[byteArray.length + 4];
byte[] sendbyteArray3 = new byte[byteArray.length + 6];
if (byteArray.length != 0) {
System.arraycopy(byteArray, 0, sendbyteArray, 4, byteArray.length);
}
sendbyteArray[0] = (byte) 0x55;
sendbyteArray[1] = (byte) 0x55;
sendbyteArray[2] = (byte) 0x01;
sendbyteArray[3] = (byte) 0x01;
byte[] byteArray2 = ModbusCRC.calculateCRC(sendbyteArray);
System.arraycopy(sendbyteArray, 0, sendbyteArray3, 0, sendbyteArray.length);
System.arraycopy(byteArray2, 0, sendbyteArray3, sendbyteArray3.length - 2, 2);
SendRawData(sendbyteArray3);
}
// 供Activity调用的方法
public BspPV.PV_struct_define getPVData() {
return _toSendPV;
}
public void setPVData(BspPV.PV_struct_define newPV) {
_toSendPV = newPV;
//SendPV(_toSendPV);
// Log.d(TAG, "服务数据已更新: ");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "服务已停止");
running = false;
send_running=false;
//receiveThread.destroy();
if (receiveSocket != null && !receiveSocket.isClosed()) {
receiveSocket.close();
}
if (sendSocket != null && !sendSocket.isClosed()) {
sendSocket.close();
}
}
}

21
app/src/main/java/com/example/paint_rough_inone_appv1_0/IVDataReceivedEvent.java

@ -0,0 +1,21 @@
package com.example.paint_rough_inone_appv1_0;
import com.example.paint_rough_inone_appv1_0.models.BspIV;
public class IVDataReceivedEvent {
public static class IVReceived {
public final byte[] receivedBytes;
public IVReceived(byte[] newIv) {
this.receivedBytes = newIv;
}
}
public static class IVChanged {
public final BspIV.IV_struct_define changedIV;
public IVChanged(BspIV.IV_struct_define changedIV) {
this.changedIV = changedIV;
}
}
}

45
app/src/main/java/com/example/paint_rough_inone_appv1_0/MainActivity.java

@ -0,0 +1,45 @@
package com.example.paint_rough_inone_appv1_0;
import android.content.Intent;
import android.os.Bundle;
import android.view.WindowManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import com.example.paint_rough_inone_appv1_0.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
public ActivityMainBinding mainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
mainBinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
mainBinding.btnPaint.setOnClickListener( v -> startActivity(new Intent(this, PaintActivity.class))
);
mainBinding.btnRough.setOnClickListener(v -> startActivity(new Intent(this, RoughActivity.class)));
startService(new Intent(this, DataExchangeService.class));
}
// 新增:当界面可见时调用(如从辅助界面返回时)
@Override
protected void onResume() {
super.onResume();
}
// 新增:当界面不可见时调用(如跳转到辅助界面时)
@Override
protected void onPause() {
super.onPause();
}
// 界面销毁时彻底释放资源
@Override
protected void onDestroy() {
super.onDestroy();
stopService(new Intent(this, DataExchangeService.class));
}
}

322
app/src/main/java/com/example/paint_rough_inone_appv1_0/PaintActivity.java

@ -0,0 +1,322 @@
package com.example.paint_rough_inone_appv1_0;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.example.paint_rough_inone_appv1_0.databinding.ActivityPaintBinding;
import com.example.paint_rough_inone_appv1_0.models.BspPV;
import com.example.paint_rough_inone_appv1_0.models.DisplayPV;
import com.example.paint_rough_inone_appv1_0.services.DecimalDigitsInputFilter;
import com.example.paint_rough_inone_appv1_0.services.MyDataHelper;
import com.example.paint_rough_inone_appv1_0.services.PopupHelper;
import com.example.paint_rough_inone_appv1_0.services.ReceiivedIVHandler;
import com.example.paint_rough_inone_appv1_0.services.USBSerialPortHelper;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class PaintActivity extends BaseChildActivity {
public ActivityPaintBinding mainBinding;//通过Binding可以获取界面数据
//USB 串口服务
public USBSerialPortHelper serialPortHelper;//串口接收类
private BspPV.PV_struct_define _toSendPV;
Timer timer = new Timer();
public MyDataHelper myDataHelper = new MyDataHelper(this);//数据库类
public PopupHelper popupHelper = new PopupHelper(this);//对话框类,把主界面实例传过去
public static int sendStopDataCount = 0;
public String _parameters_Call_Value = "1"; //默认1
public String _Manual_Mode_Call_Value = "无"; // 默认为手动模式 无 模式值1-4
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_paint);
mainBinding.MaintvVerticalAdjustTo32.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()}); //editext 一位小数限制
// //程序初始化,读取数据库,进行界面显示
myDataHelper.IntializeDataBasePaint();
String parame = mainBinding.MaintvParameterCallTo32.getText().toString(); //获取界面参数调用值
//读取数据
int paraIndex = Integer.parseInt(parame);
List<DisplayPV> pvList = myDataHelper.getDisplayDataPaint(paraIndex); //按id查询数据赋值给界面
mainBinding.MaintvLaneChangeDistanceTo32.setText(String.valueOf(pvList.get(0).getLaneChangeDistance()));
mainBinding.MaintvVerticalAdjustTo32.setText(String.valueOf(pvList.get(0).getVerticalAdjust()));
_toSendPV = BspPV.PV_struct_define.newBuilder()
.setWorkMode(0)
.build();
EventBus.getDefault().register(this);
/*发往32*/
timer.schedule(new TimerTask() {
@Override
public void run() {
// 使用 Handler 或 runOnUiThread 更新 UI
runOnUiThread(new Runnable() {
@Override
public void run() {
ReceiivedIVHandler.receiveMeasurePaint++;
if( ReceiivedIVHandler.receiveMeasurePaint>=100)
{
showToast("接收信息异常,请重启软件或遥控器");
ReceiivedIVHandler.receiveMeasurePaint=0;
}
// 更新 UI 的代码
_toSendPV = BspPV.PV_struct_define.newBuilder().
build();
//单片机重启发1,安卓接收向单片机发送收到重启通知1,当单片机收到进而转为为 非重启状态
if(ReceiivedIVHandler._toReceiveIV_Variable.getIsRestart()==1)
{
_toSendPV=_toSendPV.toBuilder().setIVIsRestartNotified(1).build();
}else
{
_toSendPV=_toSendPV.toBuilder().setIVIsRestartNotified(0).build();
}
//发送时间戳 ms
_toSendPV = _toSendPV.toBuilder().setTimeStamp(System.currentTimeMillis()).build();
String ChangeLaneDistanceStr = mainBinding.MaintvLaneChangeDistanceTo32.getText().toString();
String VeticalAdjustStr = mainBinding.MaintvVerticalAdjustTo32.getText().toString();
//换道距离
if (ChangeLaneDistanceStr.isEmpty()) {
_toSendPV = _toSendPV.toBuilder().setLaneChangeDistance(1).build();
} else {
_toSendPV = _toSendPV.toBuilder()
.setLaneChangeDistance((Integer.parseInt(String.valueOf(mainBinding.MaintvLaneChangeDistanceTo32.getText())))).build();
}
//竖直微调--小数 *10
try {
if (VeticalAdjustStr.isEmpty()) {
_toSendPV = _toSendPV.toBuilder().setVerticalCalibration(0).build();
} else {
_toSendPV = _toSendPV.toBuilder()
.setVerticalCalibration( (Double.parseDouble(String.valueOf(mainBinding.MaintvVerticalAdjustTo32.getText())) * 100)).build();
}
} catch (Exception e) {
}
//发送手动模式值
if (_Manual_Mode_Call_Value.equals("无")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(1).build();
} else if (_Manual_Mode_Call_Value.equals("竖直\n向左")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(3).build();
} else if (_Manual_Mode_Call_Value.equals("竖直\n向右")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(4).build();
}
_toSendPV = _toSendPV.toBuilder().setWorkMode(1).build();
if (isBound) {
myService.setPVData(_toSendPV);
}
}
});
}
}, 0, 1000); // 延迟 0 毫秒,每隔 1000 毫秒执行一次
//手动喷漆弹窗选择界面
mainBinding.setManualModeBtnPaint.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupHelper.Paint_ManualModePopup(this);
}
});
//喷漆参数保存
mainBinding.setcallParametersBtnPaint.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupHelper.ParametersCallPopup_Paint(this, myDataHelper);
}
});
/*喷漆错误事件*/
mainBinding.mainViewErrMessageBtnPaint.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupHelper.RobotErrorListPopUp_Paint(this);
}
});
//换道距离事件
mainBinding.MaintvLaneChangeDistanceTo32.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
// 文本变化后的回调,在这里进行范围检查
String input = s.toString();
if (!input.isEmpty()) {
try {
int value = Integer.parseInt(input);
// 检查输入值是否在 -50 到 100 范围内
if (value < 0 || value > 250) {
showToast("请输入 0 到 250 之间的数字");
// 可以选择清除输入或限制在范围内
mainBinding.MaintvLaneChangeDistanceTo32.setText("");
} else {
showToast("输入有效: " + value);
}
} catch (NumberFormatException e) {
showToast("请输入有效的数字");
}
}
}
});
//竖直微调
mainBinding.MaintvVerticalAdjustTo32.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
String input = s.toString().trim();
// 1. 允许空输入(用户正在删除)
if (TextUtils.isEmpty(input)) {
return;
}
// 2. 允许合法的中间状态(如"-10.")
if (input.matches("^-?\\d*(\\.\\d*)?$")) {
// 合法格式:整数、负数、小数、小数点开头
try {
int value = Integer.parseInt(input);
// 检查输入值是否在 -50 到 100 范围内
if (value < -10 || value > 10) {
showToast("请输入 -10 到 10 之间的数字");
// 可以选择清除输入或限制在范围内
mainBinding.MaintvVerticalAdjustTo32.setText("");
} else {
showToast("输入有效: " + value);
}
// 尝试转换为double(处理小数)
//lastValidValue = Double.parseDouble(input);
} catch (NumberFormatException e) {
// 中间状态,忽略
}
}
}
});
} //oncreate
// 接收数据变化事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDataChanged(IVDataReceivedEvent.IVReceived event) {
ReceiivedIVHandler.HandleDataPaint(this, event.receivedBytes);
}
@Override
protected void onServiceBound() {
// 服务绑定后自动更新UI
// tvData.setText("服务数据: " + myService.getServiceData());
//EventBus.getDefault().unregister(this);
}
//函数定义放create外
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
protected void onStart() {
super.onStart();
// serialPortHelper.onStart();
}
@Override
public void onStop() {
// serialPortHelper.onStop();
super.onStop();
}
@Override
public void onResume() {
super.onResume();
// serialPortHelper.onResume();
}
@Override
public void onPause() {
// serialPortHelper.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
}
//设置模式为0
_toSendPV = _toSendPV.toBuilder()
.setWorkMode(0)
.build();
myService.setPVData(_toSendPV);
EventBus.getDefault().unregister(this);
}
}

384
app/src/main/java/com/example/paint_rough_inone_appv1_0/RoughActivity.java

@ -0,0 +1,384 @@
package com.example.paint_rough_inone_appv1_0;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.databinding.DataBindingUtil;
import com.example.paint_rough_inone_appv1_0.databinding.ActivityRoughBinding;
import com.example.paint_rough_inone_appv1_0.models.BspPV;
import com.example.paint_rough_inone_appv1_0.models.DisplayPV;
import com.example.paint_rough_inone_appv1_0.services.DecimalDigitsInputFilter;
import com.example.paint_rough_inone_appv1_0.services.MyDataHelper;
import com.example.paint_rough_inone_appv1_0.services.PopupHelper;
import com.example.paint_rough_inone_appv1_0.services.ReceiivedIVHandler;
import com.example.paint_rough_inone_appv1_0.services.USBSerialPortHelper;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class RoughActivity extends BaseChildActivity {
public ActivityRoughBinding mainBinding;//通过Binding可以获取界面数据
//USB 串口服务
public USBSerialPortHelper serialPortHelper;//串口接收类
private BspPV.PV_struct_define _toSendPV;
Timer timer = new Timer();
public MyDataHelper myDataHelper = new MyDataHelper(this);//数据库类
public PopupHelper popupHelper = new PopupHelper(this);//对话框类,把主界面实例传过去
public static int sendStopDataCount = 0;
public String _parameters_Call_Value = "1"; //默认1
public String _Manual_Mode_Call_Value = "无"; // 默认为手动模式 无 模式值1-4
public String _Auto_Mode_Call_Value = "未启用"; // 默认为未启用 模式值6 7
public String HorizontalDistance = "0.0"; //自动模式下水平作业长度----->变量存储
public String VerticalDistance = "0.0"; ////自动模式下竖直作业宽度----->变量存储
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_rough);
mainBinding.MaintvVerticalAdjustTo32.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()}); //editext 一位小数限制
// //程序初始化,读取数据库,进行界面显示
myDataHelper.IntializeDataBaseRough();
String parame = mainBinding.MaintvParameterCallTo32.getText().toString(); //获取界面参数调用值
//读取数据
int paraIndex = Integer.parseInt(parame);
List<DisplayPV> pvList = myDataHelper.getDisplayDataRough(paraIndex); //按id查询数据赋值给界面
mainBinding.MaintvLaneChangeDistanceTo32.setText(String.valueOf(pvList.get(0).getLaneChangeDistance()));
mainBinding.MaintvPressTo32.setText(String.valueOf(pvList.get(0).getPressSet()));
mainBinding.MaintvVerticalAdjustTo32.setText(String.valueOf(pvList.get(0).getVerticalAdjust()));
HorizontalDistance = String.valueOf(pvList.get(0).getHorizontalDistance());
VerticalDistance = String.valueOf(pvList.get(0).getVerticalDistance());
_toSendPV = BspPV.PV_struct_define.newBuilder()
.setWorkMode(0)
.build();
EventBus.getDefault().register(this);
/*发往32*/
timer.schedule(new TimerTask() {
@Override
public void run() {
// 使用 Handler 或 runOnUiThread 更新 UI
runOnUiThread(new Runnable() {
@Override
public void run() {
ReceiivedIVHandler.receiveMeasureRough++;
if( ReceiivedIVHandler.receiveMeasureRough>=100)
{
showToast("接收信息异常,请重启软件或遥控器");
ReceiivedIVHandler.receiveMeasureRough=0;
//
}
// 更新 UI 的代码
//单片机重启发1,安卓接收向单片机发送收到重启通知1,当单片机收到进而转为为 非重启状态
if(ReceiivedIVHandler._toReceiveIV_Variable.getIsRestart()==1)
{
_toSendPV=_toSendPV.toBuilder().setIVIsRestartNotified(1).build();
}else
{
_toSendPV=_toSendPV.toBuilder().setIVIsRestartNotified(0).build();
}
//发送时间戳 ms
String ChangeLaneDistanceStr = mainBinding.MaintvLaneChangeDistanceTo32.getText().toString();
String PressStr = mainBinding.MaintvPressTo32.getText().toString();
String VeticalAdjustStr = mainBinding.MaintvVerticalAdjustTo32.getText().toString();
//换道距离
if (ChangeLaneDistanceStr.isEmpty()) {
_toSendPV = _toSendPV.toBuilder().setLaneChangeDistance(1).build();
} else {
_toSendPV = _toSendPV.toBuilder()
.setLaneChangeDistance((Integer.parseInt(String.valueOf(mainBinding.MaintvLaneChangeDistanceTo32.getText())))).build();
}
_toSendPV = _toSendPV.toBuilder().setVerticalDistanceMeters(Double.parseDouble(VerticalDistance)).build(); //作业长度
_toSendPV = _toSendPV.toBuilder().setHorizontalDistanceMeters(Double.parseDouble(HorizontalDistance)).build(); //作业宽度
//压力设定
if (PressStr.isEmpty()) {
_toSendPV = _toSendPV.toBuilder().setPressSet(1).build();
} else {
_toSendPV = _toSendPV.toBuilder()
.setPressSet((Integer.parseInt(String.valueOf(mainBinding.MaintvPressTo32.getText())))).build();
}
//竖直微调--小数 *10
try {
if (VeticalAdjustStr.isEmpty()) {
_toSendPV = _toSendPV.toBuilder().setVerticalCalibration(0).build();
} else {
_toSendPV = _toSendPV.toBuilder()
.setVerticalCalibration( (Double.parseDouble(String.valueOf(mainBinding.MaintvVerticalAdjustTo32.getText())) * 100)).build();
}
} catch (Exception e) {
}
//自动手动模式发送
if (_Manual_Mode_Call_Value.equals("未启用")) //手动模式未启用
{
//发送自动模式值
if (_Auto_Mode_Call_Value.equals("水平")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(5).build();
}
}
else if (_Auto_Mode_Call_Value.equals("未启用")) //自动模式未启用
{
//发送手动模式值
if (_Manual_Mode_Call_Value.equals("无")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(1).build();
}
else if (_Manual_Mode_Call_Value.equals("水平")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(2).build();
}else if (_Manual_Mode_Call_Value.equals("竖直\n向左")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(3).build();
}
else if (_Manual_Mode_Call_Value.equals("竖直\n向右")) {
_toSendPV = _toSendPV.toBuilder().setRunMode(4).build();
}
}
_toSendPV = _toSendPV.toBuilder().setWorkMode(2).build();
if (isBound) {
myService.setPVData(_toSendPV);
}
}
});
}
}, 0, 1000); // 延迟 0 毫秒,每隔 1000 毫秒执行一次
//三个弹窗选择界面
mainBinding.setManualModeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupHelper.Rough_ManualModePopup(this);
}
});
mainBinding.setAutoModeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupHelper.Rough_AutoModePopup(this);
}
});
mainBinding.setcallParametersBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupHelper.ParametersCallPopup_Rough(this, myDataHelper);
}
});
mainBinding.mainViewErrMessageBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupHelper.RobotErrorListPopUp_Rough(this);
}
});
//换道距离事件
mainBinding.MaintvLaneChangeDistanceTo32.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
// 文本变化后的回调,在这里进行范围检查
String input = s.toString();
if (!input.isEmpty()) {
try {
int value = Integer.parseInt(input);
// 检查输入值是否在 -50 到 100 范围内
if (value < 0 || value > 250) {
showToast("请输入 0 到 250 之间的数字");
// 可以选择清除输入或限制在范围内
mainBinding.MaintvLaneChangeDistanceTo32.setText("");
} else {
showToast("输入有效: " + value);
}
} catch (NumberFormatException e) {
showToast("请输入有效的数字");
}
}
}
});
//压力设定
mainBinding.MaintvPressTo32.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
// 文本变化后的回调,在这里进行范围检查
String input = s.toString();
if (!input.isEmpty()) {
try {
int value = Integer.parseInt(input);
// 检查输入值是否在 -50 到 100 范围内
if (value < -3000 || value > 3000) {
showToast("请输入 -3000 到 3000 之间的数字");
// 可以选择清除输入或限制在范围内
mainBinding.MaintvPressTo32.setText("");
} else {
showToast("输入有效: " + value);
}
} catch (NumberFormatException e) {
showToast("请输入有效的数字");
}
}
}
});
//竖直微调
mainBinding.MaintvVerticalAdjustTo32.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
String input = s.toString().trim();
// 1. 允许空输入(用户正在删除)
if (TextUtils.isEmpty(input)) {
return;
}
// 2. 允许合法的中间状态(如"-10.")
if (input.matches("^-?\\d*(\\.\\d*)?$")) {
// 合法格式:整数、负数、小数、小数点开头
try {
int value = Integer.parseInt(input);
// 检查输入值是否在 -50 到 100 范围内
if (value < -10 || value > 10) {
showToast("请输入 -10 到 10 之间的数字");
// 可以选择清除输入或限制在范围内
mainBinding.MaintvVerticalAdjustTo32.setText("");
} else {
showToast("输入有效: " + value);
}
// 尝试转换为double(处理小数)
//lastValidValue = Double.parseDouble(input);
} catch (NumberFormatException e) {
// 中间状态,忽略
}
}
}
});
} //oncreate
// 接收数据变化事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDataChanged(IVDataReceivedEvent.IVReceived event)
{
ReceiivedIVHandler.HandleDataRough(this,event.receivedBytes);
}
@Override
protected void onServiceBound() {
// 服务绑定后自动更新UI
// tvData.setText("服务数据: " + myService.getServiceData());
}
//函数定义放create外
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
protected void onStart() {
super.onStart();
// serialPortHelper.onStart();
}
@Override
public void onStop() {
// serialPortHelper.onStop();
super.onStop();
}
@Override
public void onResume() {
super.onResume();
// serialPortHelper.onResume();
}
@Override
public void onPause() {
// serialPortHelper.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
}
//设置模式为0
_toSendPV = _toSendPV.toBuilder()
.setWorkMode(0)
.build();
myService.setPVData(_toSendPV);
EventBus.getDefault().unregister(this);
}
}

1678
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/BspError.java

File diff suppressed because it is too large

1718
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/BspIV.java

File diff suppressed because it is too large

1535
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/BspPV.java

File diff suppressed because it is too large

50
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/DisplayIV.java

@ -0,0 +1,50 @@
package com.example.paint_rough_inone_appv1_0.models;
import androidx.databinding.BaseObservable;
public class DisplayIV extends BaseObservable {
private double leftCompensation;
private double rightCompensation;
private double currentAngle;
public double getLeftCompensation() {
return leftCompensation;
}
public void setLeftCompensation(double leftCompensation) {
this.leftCompensation = leftCompensation;
}
public double getRightCompensation() {
return rightCompensation;
}
public void setRightCompensation(double rightCompensation) {
this.rightCompensation = rightCompensation;
}
public double getCurrentAngle() {
return currentAngle;
}
public void setCurrentAngle(double currentAngle) {
this.currentAngle = currentAngle;
}
public double getRobotMoveSpeed() {
return robotMoveSpeed;
}
public void setRobotMoveSpeed(double robotMoveSpeed) {
this.robotMoveSpeed = robotMoveSpeed;
}
private double robotMoveSpeed;
public DisplayIV(double leftCompensation, double rightCompensation, double currentAngle, double robotMoveSpeed) {
this.leftCompensation = leftCompensation;
this.rightCompensation = rightCompensation;
this.currentAngle = currentAngle;
this.robotMoveSpeed = robotMoveSpeed;
}
}

90
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/DisplayPV.java

@ -0,0 +1,90 @@
package com.example.paint_rough_inone_appv1_0.models;
import androidx.databinding.BaseObservable;
public class DisplayPV extends BaseObservable {
private int id;
private int laneChangeDistance;
private double horizontalDistance;
private double verticalDistance;
private double verticalAdjust;
private double leftCompensation;
private double rightCompensation;
private int pressSet;
public DisplayPV(int id, int laneChangeDistance, double horizontalDistance, double verticalDistance, double verticalAdjust, double leftCompensation, double rightCompensation ,int pressSet) {
this.id = id;
this.laneChangeDistance=laneChangeDistance;
this.horizontalDistance = horizontalDistance;
this.verticalDistance = verticalDistance;
this.verticalAdjust=verticalAdjust;
this.leftCompensation = leftCompensation;
this.rightCompensation=rightCompensation;
this.pressSet=pressSet;
}
public int getId() { return id; }
public void setId(int id) {
this.id = id;
}
public int getLaneChangeDistance() {
return laneChangeDistance;
}
public void setLaneChangeDistance(int laneChangeDistance) { this.laneChangeDistance = laneChangeDistance;}
public double getHorizontalDistance() {
return horizontalDistance;
}
public void setHorizontalDistance(double horizontalDistance) { this.horizontalDistance = horizontalDistance;}
public double getVerticalDistance() {
return verticalDistance;
}
public void setVerticalDistance(double verticalDistance) {
this.verticalDistance = verticalDistance;
}
public double getVerticalAdjust(){
return verticalAdjust;
}
public void setVerticalAdjust(double verticalAdjust) {
this.verticalAdjust = verticalAdjust;
}
public double getLeftCompensation() {
return leftCompensation;
}
public void setLeftCompensation(double leftCompensation) {
this.leftCompensation = leftCompensation;
}
public double getRightCompensation() {
return rightCompensation;
}
public void setRightCompensation(double rightCompensation) {
this.rightCompensation = rightCompensation;
}
public int getPressSet() {
return pressSet;
}
public void setPressSet(int pressSet) {
this.pressSet = pressSet;
}
}

44
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/ErrorModel.java

@ -0,0 +1,44 @@
package com.example.paint_rough_inone_appv1_0.models;
public class ErrorModel {
public ErrorModel(long timeID, String errorInfo) {
this.timeID = timeID;
this.errorInfo = errorInfo;
}
private long timeID;
public void setDateTimeBJ(String dateTimeUTC) {
this.dateTimeBJ = dateTimeUTC;
}
private String errorInfo;
public String getDateTimeBJ() {
return dateTimeBJ;
}
private String dateTimeBJ;
@Override
public String toString() {
return String.valueOf(dateTimeBJ + errorInfo);
}
public void setTimeID(long timeID) {
this.timeID = timeID;
}
public void setErrorInfo(String errorInfo) {
this.errorInfo = errorInfo;
}
public long getTimeID() {
return timeID;
}
public String getErrorInfo() {
return errorInfo;
}
}

43
app/src/main/java/com/example/paint_rough_inone_appv1_0/models/ScrollBottomScrollView.java

@ -0,0 +1,43 @@
package com.example.paint_rough_inone_appv1_0.models;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ScrollView;
public class ScrollBottomScrollView extends ScrollView {
private OnScrollBottomListener listener;
private int calCount;
public interface OnScrollBottomListener {
void scrollToBottom();
}
public void onScrollViewScrollToBottom(OnScrollBottomListener l) {
listener = l;
}
public void unRegisterOnScrollViewScrollToBottom() {
listener = null;
}
public ScrollBottomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
View view = this.getChildAt(0);
if (this.getHeight() + this.getScrollY() == view.getHeight()) {
calCount++;
if (calCount == 1) {
if (listener != null) {
listener.scrollToBottom();
}
}
} else {
calCount = 0;
}
}
}

26
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ConvertHelper.java

@ -0,0 +1,26 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.widget.EditText;
import android.widget.TextView;
public class ConvertHelper {
public static int convertEditTextToInt(TextView editText) {
// 获取 EditText 中的文本
String input = editText.getText().toString().trim();
try {
// 尝试将字符串转换为整数
return Integer.parseInt(input);
} catch (NumberFormatException e) {
// 输入不是有效的整数格式,返回 -1 表示转换失败
return -1;
}
}
public static boolean isEditTextNullOrEmpty(EditText editText) {
String str = String.valueOf(editText.getText());
return str == null || str.isEmpty();
}
}

22
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/CustomProber.java

@ -0,0 +1,22 @@
package com.example.paint_rough_inone_appv1_0.services;
import com.hoho.android.usbserial.driver.FtdiSerialDriver;
import com.hoho.android.usbserial.driver.ProbeTable;
import com.hoho.android.usbserial.driver.UsbSerialProber;
/**
* add devices here, that are not known to DefaultProber
*
* if the App should auto start for these devices, also
* add IDs to app/src/main/res/xml/device_filter.xml
*/
public class CustomProber {
public static UsbSerialProber getCustomProber() {
ProbeTable customTable = new ProbeTable();
customTable.addProduct(0x1234, 0x0001, FtdiSerialDriver.class); // e.g. device with custom VID+PID
customTable.addProduct(0x1234, 0x0002, FtdiSerialDriver.class); // e.g. device with custom VID+PID
return new UsbSerialProber(customTable);
}
}

71
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/DecimalDigitsInputFilter.java

@ -0,0 +1,71 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.text.InputFilter;
import android.text.Spanned;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
自定义 InputFilter 用于限制输入格式
支持整数负数和最多一位小数的输入
使用方法editText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()});
*/
public class DecimalDigitsInputFilter implements InputFilter {
// 最终验证的正则表达式
private final Pattern mFinalPattern;
// 中间状态允许的正则表达式
private final Pattern mIntermediatePattern;
public DecimalDigitsInputFilter() {
// 最终验证:必须是完整的数字格式
mFinalPattern = Pattern.compile("^-?(0|[1-9]\\d*)(\\.\\d)?$");
// 中间状态:允许临时的不完整格式(如 "-"、"0."、"-2.")
mIntermediatePattern = Pattern.compile("^-?(0|[1-9]\\d*)?(\\.)?$");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
// 处理删除操作
if (end - start == 0) {
return null;
}
// 拼接新的输入内容
String newText = dest.toString().substring(0, dstart) +
source.toString().substring(start, end) +
dest.toString().substring(dend);
// 允许空字符串或单独的负号
if (newText.isEmpty() || newText.equals("-")) {
return null;
}
// 防止前导零(除非是 0 或 0.x)
if (newText.startsWith("0") && newText.length() > 1 &&
!newText.startsWith("0.") && !newText.equals("0")) {
return "";
}
// 防止多个负号
if (newText.indexOf('-') > 0) {
return "";
}
// 防止多个小数点
if (newText.indexOf('.') != newText.lastIndexOf('.')) {
return "";
}
// 检查是否匹配最终模式或中间模式
Matcher finalMatcher = mFinalPattern.matcher(newText);
Matcher intermediateMatcher = mIntermediatePattern.matcher(newText);
if (finalMatcher.matches() || intermediateMatcher.matches()) {
return null; // 匹配成功,允许输入
}
return ""; // 匹配失败,阻止输入
}
}

42
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ErrorDeocdeHelper.java

@ -0,0 +1,42 @@
package com.example.paint_rough_inone_appv1_0.services;
import com.example.paint_rough_inone_appv1_0.models.BspError;
public class ErrorDeocdeHelper {
//private static Map<String, Integer> flagMap = new HashMap<>();
// public static void AddMap(String errorName, Integer bitPosition)
// {
// flagMap.put(errorName,bitPosition);
// }
private static String ErrorResult;
private static String addErrorResult;
public static String ErrorDeocde(int data)
{
ErrorResult="";
/*访问每个枚举变量*/
for (BspError.ComError err : BspError.ComError.values()) {
int bitPosiiton = err.ordinal();//返回枚举值序号
if (err.toString().equals("UNRECOGNIZED")) continue;
if (err.toString().equals("TL720D"))
addErrorResult = " 作业模式已切换至手动";
else
addErrorResult = " ";
// 使用左移操作生成要检查的标志位
int bitToCheck = 1 << bitPosiiton;
// 判断该位置是否有对应的标志位
if ((data & bitToCheck) != 0) {
if (err.toString().equals("Remote_Button_Reset_State")) {
ErrorResult = "未复位";
}
}
}
return ErrorResult;
}
}

39
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/LogUtil.java

@ -0,0 +1,39 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.util.Log;
public class LogUtil {
private String TAG;
private boolean isRelease = false;
private boolean isDebug;
public LogUtil(Class c, boolean isDebug) {
this.TAG = c.getName();
this.isDebug = isDebug;
}
public void d(String msg) {
if (!isRelease && isDebug) {
Log.d(TAG, "--------->" + msg);
}
}
public void i(String msg) {
if (!isRelease && isDebug) {
Log.i(TAG, "--------->" + msg);
}
}
public void w(String msg) {
if (!isRelease && isDebug) {
Log.w(TAG, "--------->" + msg);
}
}
public void e(String msg) {
if (!isRelease && isDebug) {
Log.e(TAG, "--------->" + msg);
}
}
}

72
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ModbusCRC.java

@ -0,0 +1,72 @@
package com.example.paint_rough_inone_appv1_0.services;
public class ModbusCRC {
// /**
// * 一个字节包含位的数量 8
// */
// private static final int BITS_OF_BYTE = 8;
// /**
// * 多项式
// */
// private static final int POLYNOMIAL = 0xA001;
// /**
// * 初始值
// */
// private static final int INITIAL_VALUE = 0xFFFF;
//
// /**
// * CRC16 编码
// *
// * @param bytes 编码内容
// * @return 编码结果
// */
// public static int crc16(byte[] bytes) {
// int res = INITIAL_VALUE;
// for (int data : bytes) {
// res = res ^ data;
// for (int i = 0; i < BITS_OF_BYTE; i++) {
// res = (res & 0x0001) == 1 ? (res >> 1) ^ POLYNOMIAL : res >> 1;
// }
// }
// return revert(res);
// }
//
// /**
// * 翻转16位的高八位和低八位字节
// *
// * @param src 翻转数字
// * @return 翻转结果
// */
// private static int revert(int src) {
// int lowByte = (src & 0xFF00) >> 8;
// int highByte = (src & 0x00FF) << 8;
// return lowByte | highByte;
// }
/**
* 计算 Modbus CRC 校验值
* @param data 要计算校验值的字节数组
* @return CRC 校验值 2 字节的数组形式返回
*/
public static byte[] calculateCRC(byte[] data) {
int crc = 0xFFFF;
for (byte b : data) {
crc ^= (b & 0xFF);
for (int i = 0; i < 8; i++) {
if ((crc & 0x0001) != 0) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
// 将 CRC 结果拆分为两个字节
byte[] crcBytes = new byte[2];
crcBytes[0] = (byte) (crc & 0xFF);
crcBytes[1] = (byte) ((crc >> 8) & 0xFF);
return crcBytes;
}
}

368
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/MyDataHelper.java

@ -0,0 +1,368 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;//具体进行数据库、数据表的一个操作
import android.database.sqlite.SQLiteOpenHelper;//用来创建数据库和对数据库进行版本管理
import android.util.Log;
import androidx.annotation.Nullable;
import com.example.paint_rough_inone_appv1_0.models.DisplayPV;
import com.example.paint_rough_inone_appv1_0.models.ErrorModel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
public class MyDataHelper extends SQLiteOpenHelper {
//定义字段
public static final String COLUMN_ID = "id";//参数调用
public static final String TABLE_NAME_PAINT = "paint";
public static final String COLUMN_LANE_CHANGE_DISTANCE = "laneChangeDistance";//换道距离
public static final String COLUMN_VERTICAL_ADJUST = "verticalAdjust";//Maintv_VerticalAdjustTo32 竖直微调
/*************************************************************************************************/
public static final String TABLE_NAME_ROUGH = "rough";
public static final String COLUMN_PRESS_SET = "pressSet";//Maintv_PressTo32 压力设定
public static final String COLUMN_HORIZONTAL_DISTANCE = "horizontalDistance";/*横向距离*/
public static final String COLUMN_VERTICAL_DISTANCE = "verticalDistance"; /*纵向距离*/
public static final String COLUMN_LEFT_COMPENSATION = "leftCompensation"; /*左补偿*/
public static final String COLUMN_RIGHT_COMPENSATION = "rightCompensation"; /*右补偿*/
/************************************************************************************************/
public static final String Error_TABLE_NAME_PAINT = "errorPaint";
public static final String Error_TABLE_NAME_ROUGH = "errorRough";
public static final String Error_COLUMN_TimeStamp = "timeID";
public static final String Error_COLUMN_ERROR_INFO = "errorInfo";
public MyDataHelper(@Nullable Context context) {
super(context, "bingbot.db", null, 9); //数据库名称为 bingbot.db,数据库版本为 1。存放两个表
}
@Override
public void onCreate(SQLiteDatabase db) {
//INTEGER前加空格
String sql = "CREATE TABLE " + TABLE_NAME_PAINT + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_VERTICAL_ADJUST + " DOUBLE, " +
COLUMN_LANE_CHANGE_DISTANCE + " INTEGER);" ;
db.execSQL(sql); //执行sql语句
sql = "CREATE TABLE " + TABLE_NAME_ROUGH + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_LEFT_COMPENSATION + " DOUBLE, " +
COLUMN_RIGHT_COMPENSATION + " DOUBLE, " +
COLUMN_HORIZONTAL_DISTANCE + " DOUBLE, " +
COLUMN_VERTICAL_DISTANCE + " DOUBLE, " +
COLUMN_VERTICAL_ADJUST + " DOUBLE, " +
COLUMN_PRESS_SET + " INTEGER, " +
COLUMN_LANE_CHANGE_DISTANCE + " INTEGER);" ;
db.execSQL(sql); //执行sql语句
sql = "CREATE TABLE " + Error_TABLE_NAME_PAINT + "(" + Error_COLUMN_TimeStamp + " INTEGER PRIMARY KEY ,"
+ Error_COLUMN_ERROR_INFO + " STRING " + ")";
db.execSQL(sql); //创建喷漆错误表
sql = "CREATE TABLE " + Error_TABLE_NAME_ROUGH + "(" + Error_COLUMN_TimeStamp + " INTEGER PRIMARY KEY ,"
+ Error_COLUMN_ERROR_INFO + " STRING " + ")";
db.execSQL(sql); //创建拉毛错误表
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_PAINT); // 喷漆表
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_ROUGH); //拉毛表
db.execSQL("DROP TABLE IF EXISTS " + Error_TABLE_NAME_PAINT); //喷漆错误表
db.execSQL("DROP TABLE IF EXISTS " + Error_TABLE_NAME_ROUGH); //拉毛错误表
onCreate(db);
}
//增 删 改 查
public String addOrUpdateDisplayDataPaint(DisplayPV pv) {
ContentValues cv = new ContentValues(); //键值对的类
cv.put(COLUMN_ID, pv.getId());
cv.put(COLUMN_LANE_CHANGE_DISTANCE, pv.getLaneChangeDistance());
cv.put(COLUMN_VERTICAL_ADJUST, pv.getVerticalAdjust());
SQLiteDatabase sqliteDatabase = this.getWritableDatabase();//获取数据库实例以实现增上查改等,如果没有就新建 并把sqliteDatabase作为参数传给oncreate方法
long insert = sqliteDatabase.insertWithOnConflict(TABLE_NAME_PAINT, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
sqliteDatabase.close();
if (insert == -1) {
return "failed";
}
return "success";
}
//增 删 改 查
public String addOrUpdateDisplayDataRough(DisplayPV pv) {
ContentValues cv = new ContentValues(); //键值对的类
cv.put(COLUMN_ID, pv.getId());
cv.put(COLUMN_LANE_CHANGE_DISTANCE, pv.getLaneChangeDistance());
cv.put(COLUMN_HORIZONTAL_DISTANCE, pv.getHorizontalDistance());
cv.put(COLUMN_VERTICAL_DISTANCE, pv.getVerticalDistance());
cv.put(COLUMN_VERTICAL_ADJUST, pv.getVerticalAdjust());
cv.put(COLUMN_LEFT_COMPENSATION, pv.getLeftCompensation());
cv.put(COLUMN_RIGHT_COMPENSATION, pv.getRightCompensation());
cv.put(COLUMN_PRESS_SET, pv.getPressSet());
SQLiteDatabase sqliteDatabase = this.getWritableDatabase();//获取数据库实例以实现增上查改等,如果没有就新建 并把sqliteDatabase作为参数传给oncreate方法
long insert = sqliteDatabase.insertWithOnConflict(TABLE_NAME_ROUGH, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
sqliteDatabase.close();
if (insert == -1) {
return "failed";
}
return "success";
}
// public String deleteAll() {
// SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
// int delete = sqLiteDatabase.delete(TABLE_NAME, null, null);
//
// sqLiteDatabase.close();
// if (delete == 0) {
// return "failed";
// }
// return "success";
//
// }
public void IntializeDataBasePaint() {
for (int i = 1; i < 6; i++) {
List<DisplayPV> list = getDisplayDataPaint(i); //从数据库中读
if (list.size() == 0) {
DisplayPV pv = new DisplayPV(i, 0, 0, 0, 0, 0, 0,0);
addOrUpdateDisplayDataPaint(pv);//一行一行添加
}
}
}
public void IntializeDataBaseRough() {
for (int i = 1; i < 6; i++) {
List<DisplayPV> list = getDisplayDataRough(i); //从数据库中读
if (list.size() == 0) {
DisplayPV pv = new DisplayPV(i, 0, 0, 0, 0, 0, 0,0);
addOrUpdateDisplayDataRough(pv);//一行一行添加
}
}
}
public List<DisplayPV> getDisplayDataPaint(int id) { //初始化
List<DisplayPV> list = new ArrayList<>();
String sql = "SELECT * FROM " + TABLE_NAME_PAINT + " WHERE " + COLUMN_ID + " = " + String.valueOf(id);
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();//获取可写数据库实例
Cursor cursor = sqLiteDatabase.rawQuery(sql, null); //按id查询
int idIndex = cursor.getColumnIndex(COLUMN_ID);
int _laneChangeDistanceIndex = cursor.getColumnIndex(COLUMN_LANE_CHANGE_DISTANCE);
int _verticalAdjustIndex = cursor.getColumnIndex(COLUMN_VERTICAL_ADJUST);
while (cursor.moveToNext()) {
DisplayPV pv = new DisplayPV(cursor.getInt(idIndex), cursor.getInt(_laneChangeDistanceIndex),
0,0, cursor.getDouble(_verticalAdjustIndex),0,0,0
);
list.add(pv);
}
cursor.close();
sqLiteDatabase.close();
return list;
}
public List<DisplayPV> getDisplayDataRough(int id) { //初始化
List<DisplayPV> list = new ArrayList<>();
String sql = "SELECT * FROM " + TABLE_NAME_ROUGH + " WHERE " + COLUMN_ID + " = " + String.valueOf(id);
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();//获取可写数据库实例
Cursor cursor = sqLiteDatabase.rawQuery(sql, null); //按id查询
int idIndex = cursor.getColumnIndex(COLUMN_ID);
int _laneChangeDistanceIndex = cursor.getColumnIndex(COLUMN_LANE_CHANGE_DISTANCE);
int _verticalAdjustIndex = cursor.getColumnIndex(COLUMN_VERTICAL_ADJUST);
int _pressSetIndex = cursor.getColumnIndex(COLUMN_PRESS_SET);
int _leftCompensationIndex=cursor.getColumnIndex(COLUMN_LEFT_COMPENSATION);
int _rightCompensationIndex=cursor.getColumnIndex(COLUMN_RIGHT_COMPENSATION);
int _horizontalDistanceIndex=cursor.getColumnIndex(COLUMN_HORIZONTAL_DISTANCE);
int _verticalDistanceIndex=cursor.getColumnIndex(COLUMN_VERTICAL_DISTANCE);
while (cursor.moveToNext()) {
DisplayPV pv = new DisplayPV(cursor.getInt(idIndex), cursor.getInt(_laneChangeDistanceIndex),
cursor.getDouble(_horizontalDistanceIndex), cursor.getDouble(_verticalDistanceIndex), cursor.getDouble(_verticalAdjustIndex),cursor.getDouble(_leftCompensationIndex), cursor.getDouble(_rightCompensationIndex),
cursor.getInt(_pressSetIndex)
);
list.add(pv);
}
cursor.close();
sqLiteDatabase.close();
return list;
}
public String AddOrUpdateErrorModelPaint(ErrorModel em) {
ContentValues cv = new ContentValues();
cv.put(Error_COLUMN_TimeStamp, em.getTimeID());
cv.put(Error_COLUMN_ERROR_INFO, em.getErrorInfo());
SQLiteDatabase sqliteDatabase = this.getWritableDatabase();
long insert = sqliteDatabase.insertWithOnConflict(Error_TABLE_NAME_PAINT, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
if (insert == -1) {
// 插入失败,按时间戳删除最早的100行
try {
// 开始事务
sqliteDatabase.beginTransaction();
String deleteQuery = "DELETE FROM error WHERE timeID IN (SELECT timeID FROM error ORDER BY timeID ASC LIMIT 100)";
sqliteDatabase.execSQL(deleteQuery);
// 标记事务成功
sqliteDatabase.setTransactionSuccessful();
Log.d("DB_OPERATION", "插入失败,已按时间戳删除最早的100行数据");
} catch (SQLException e) {
Log.e("DB_ERROR", "删除时发生错误: " + e.getMessage());
} finally {
// 结束事务(若setTransactionSuccessful()被调用则提交,否则回滚)
sqliteDatabase.endTransaction();
}
sqliteDatabase.close();
return "failed";
}
sqliteDatabase.close();
return "success";
}
public String AddOrUpdateErrorModelRough(ErrorModel em) {
ContentValues cv = new ContentValues();
cv.put(Error_COLUMN_TimeStamp, em.getTimeID());
cv.put(Error_COLUMN_ERROR_INFO, em.getErrorInfo());
SQLiteDatabase sqliteDatabase = this.getWritableDatabase();
long insert = sqliteDatabase.insertWithOnConflict(Error_TABLE_NAME_ROUGH, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
if (insert == -1) {
// 插入失败,按时间戳删除最早的100行
try {
// 开始事务
sqliteDatabase.beginTransaction();
String deleteQuery = "DELETE FROM error WHERE timeID IN (SELECT timeID FROM error ORDER BY timeID ASC LIMIT 100)";
sqliteDatabase.execSQL(deleteQuery);
// 标记事务成功
sqliteDatabase.setTransactionSuccessful();
Log.d("DB_OPERATION", "插入失败,已按时间戳删除最早的100行数据");
} catch (SQLException e) {
Log.e("DB_ERROR", "删除时发生错误: " + e.getMessage());
} finally {
// 结束事务(若setTransactionSuccessful()被调用则提交,否则回滚)
sqliteDatabase.endTransaction();
}
sqliteDatabase.close();
return "failed";
}
sqliteDatabase.close();
return "success";
}
public String DeleteAllErrorModelsPaint() {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
int delete = sqLiteDatabase.delete(Error_TABLE_NAME_PAINT, null,
null);
sqLiteDatabase.close();
if (delete == 0) {
return "failed";
}
return "success";
}
public String DeleteAllErrorModelRough() {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
int delete = sqLiteDatabase.delete(Error_TABLE_NAME_ROUGH, null,
null);
sqLiteDatabase.close();
if (delete == 0) {
return "failed";
}
return "success";
}
public List<ErrorModel> GetAllErrorModelsPaint() {
List<ErrorModel> list = new ArrayList<>();
String sql = "SELECT * FROM " + Error_TABLE_NAME_PAINT;
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
int _time_id_Index = cursor.getColumnIndex(Error_COLUMN_TimeStamp);
int _error_Index = cursor.getColumnIndex(Error_COLUMN_ERROR_INFO);
while (cursor.moveToNext()) {
ErrorModel em = new ErrorModel(cursor.getLong(_time_id_Index), cursor.getString(_error_Index));
Date date = new Date(em.getTimeID()); // 将时间戳转换为Date对象
// 创建SimpleDateFormat实例,并设置时区为UTC
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 设置为UTC时区
// 格式化日期
String utcTime = sdf.format(date);
// System.out.println("UTC时间: " + utcTime);
em.setDateTimeBJ(utcTime);
list.add(em);
}
cursor.close();
sqLiteDatabase.close();
return list;
}
public List<ErrorModel> GetAllErrorModelsRough() {
List<ErrorModel> list = new ArrayList<>();
String sql = "SELECT * FROM " + Error_TABLE_NAME_ROUGH;
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
int _time_id_Index = cursor.getColumnIndex(Error_COLUMN_TimeStamp);
int _error_Index = cursor.getColumnIndex(Error_COLUMN_ERROR_INFO);
while (cursor.moveToNext()) {
ErrorModel em = new ErrorModel(cursor.getLong(_time_id_Index), cursor.getString(_error_Index));
Date date = new Date(em.getTimeID()); // 将时间戳转换为Date对象
// 创建SimpleDateFormat实例,并设置时区为UTC
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 设置为UTC时区
// 格式化日期
String utcTime = sdf.format(date);
// System.out.println("UTC时间: " + utcTime);
em.setDateTimeBJ(utcTime);
list.add(em);
}
cursor.close();
sqLiteDatabase.close();
return list;
}
}

736
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/PopupHelper.java

@ -0,0 +1,736 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.app.Dialog;
import android.text.InputFilter;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.paint_rough_inone_appv1_0.RoughActivity;
import com.example.paint_rough_inone_appv1_0.models.ErrorModel;
import com.example.paint_rough_inone_appv1_0.models.ScrollBottomScrollView;
import com.example.paint_rough_inone_appv1_0.PaintActivity;
import com.example.paint_rough_inone_appv1_0.R;
import com.example.paint_rough_inone_appv1_0.models.DisplayPV;
import java.util.List;
public class PopupHelper {
private PaintActivity paintActivity;
private RoughActivity roughActivity;
String result="1";
public PopupHelper(PaintActivity paintActivity)
{
this.paintActivity = paintActivity;
}
public PopupHelper(RoughActivity roughActivity)
{
this.roughActivity = roughActivity;
}
//喷漆手动模式弹窗
public void Paint_ManualModePopup(View.OnClickListener context) { //手动模式弹窗
Dialog dialog = new Dialog(paintActivity);
dialog.setContentView(R.layout.paint_manualmodepopup); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
// 获取布局中的视图
Button cancelButton = dialog.findViewById(R.id.manualModeCancel_Paint);
Button confirmButton = dialog.findViewById(R.id.manualModeApply_Paint);
//获取按钮组
RadioGroup radioGroup = (RadioGroup) dialog.findViewById(R.id.manualModeSelectorGroup_Paint);
//4种模式
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
if (radioButton != null)
{
paintActivity._Manual_Mode_Call_Value = radioButton.getText().toString();
}
}
});
//下次进来保证是选中状态或者未选中
String ii= paintActivity.mainBinding.manualModeDisplay.getText().toString();
switch (ii)
{
case "无": { radioGroup.check(R.id.rb_one_paint);
break;
}
case "竖直\n向左": { radioGroup.check(R.id.rb_two_paint);
break;
}
case "竖直\n向右": { radioGroup.check(R.id.rb_three_paint);
break;
}
default:
radioGroup.clearCheck();
break;
}
// 设置确定按钮点击事件
confirmButton.setOnClickListener(v -> { //手动模式弹窗确认
if (radioGroup.getCheckedRadioButtonId() != -1) { //有按钮选中时按确定 更新值
paintActivity.mainBinding.manualModeDisplay.setText(paintActivity._Manual_Mode_Call_Value);
Toast.makeText(paintActivity, "设置成功", Toast.LENGTH_SHORT).show();
}
dialog.dismiss(); // 关闭弹窗
});
// 设置取消按钮点击事件
cancelButton.setOnClickListener(v -> {
Toast.makeText(paintActivity, "点击了取消", Toast.LENGTH_SHORT).show();
dialog.dismiss(); // 关闭弹窗
});
// 显示弹窗
dialog.show();
}
//拉毛手动模式弹窗
public void Rough_ManualModePopup(View.OnClickListener context) { //手动模式弹窗
Dialog dialog = new Dialog(roughActivity);
dialog.setContentView(R.layout.rough_manualmodepopup); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
// 获取布局中的视图
Button cancelButton = dialog.findViewById(R.id.manualModeCancel_Rough);
Button confirmButton = dialog.findViewById(R.id.manualModeApply_Rough);
//获取按钮组
RadioGroup radioGroup = (RadioGroup) dialog.findViewById(R.id.manualModeSelectorGroup_Rough);
//4种模式
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
if (radioButton!=null)
{
roughActivity._Manual_Mode_Call_Value = radioButton.getText().toString();
}
}
});
//下次进来保证是选中状态或者未选中
String ii= roughActivity.mainBinding.manualModeDisplay.getText().toString();
switch (ii)
{
case "无": { radioGroup.check(R.id.rb_one_rough);
break;
}
case "水平": { radioGroup.check(R.id.rb_two_rough);
break;
}
case "竖直\n向左": { radioGroup.check(R.id.rb_three_rough);
break;
}
case "竖直\n向右": { radioGroup.check(R.id.rb_four_rough);
break;
}
default:
radioGroup.clearCheck();
break;
}
// 设置确定按钮点击事件
confirmButton.setOnClickListener(v -> { //手动模式弹窗确认
if (radioGroup.getCheckedRadioButtonId() != -1) { //有按钮选中时按确定 更新值
roughActivity.mainBinding.manualModeDisplay.setText(roughActivity._Manual_Mode_Call_Value);
//失能自动模式
roughActivity._Auto_Mode_Call_Value="未启用";
roughActivity.mainBinding.autoModeDisplay.setText("未启用");
Toast.makeText(roughActivity, "设置成功", Toast.LENGTH_SHORT).show();
}
dialog.dismiss(); // 关闭弹窗
});
// 设置取消按钮点击事件
cancelButton.setOnClickListener(v -> {
Toast.makeText(roughActivity, "点击了取消", Toast.LENGTH_SHORT).show();
dialog.dismiss(); // 关闭弹窗
});
// 显示弹窗
dialog.show();
}
//拉毛自动模式弹窗
public void Rough_AutoModePopup(View.OnClickListener context) {
Dialog dialog = new Dialog(roughActivity);
dialog.setContentView(R.layout.rough_automodepopup); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
// 获取布局中的视图
Button cancelButton = dialog.findViewById(R.id.autoModeCancel_Rough);
Button confirmButton = dialog.findViewById(R.id.autoModeApply_Rough);
EditText HorizontalDistance_Edit=dialog.findViewById(R.id.HorizontalDistance_input);
EditText VerticalDistance_Edit=dialog.findViewById(R.id.VerticalDistance_input);
HorizontalDistance_Edit.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()}); //editext 一位小数限制
VerticalDistance_Edit.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()}); //editext 一位小数限制
/*进入显示文本*/
HorizontalDistance_Edit.setText(roughActivity.HorizontalDistance);
VerticalDistance_Edit.setText(roughActivity.VerticalDistance);
RadioGroup radioGroup = (RadioGroup) dialog.findViewById(R.id.autoModeSelectorGroup_Rough);
//2种模式
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
if(radioButton!=null){
roughActivity._Auto_Mode_Call_Value = radioButton.getText().toString();
}
}
});
String ii= roughActivity.mainBinding.autoModeDisplay.getText().toString();
switch (ii)
{
case "水平": { radioGroup.check(R.id.rb_autoHorizontal);
break;
}
default:
radioGroup.clearCheck();//清除选中,此时触发radioGroup事件,自动模式值被改为未启用
break;
}
// 设置确定按钮点击事件
confirmButton.setOnClickListener(v -> {
if (radioGroup.getCheckedRadioButtonId() != -1) { //有按钮选中时按确定 更新值
roughActivity.mainBinding.autoModeDisplay.setText(roughActivity._Auto_Mode_Call_Value);
//失能手动模式
roughActivity._Manual_Mode_Call_Value="未启用";
roughActivity.mainBinding.manualModeDisplay.setText("未启用");
Toast.makeText(roughActivity, "设置成功", Toast.LENGTH_SHORT).show();
}
//检查作业宽度 长度 范围
double value1=0; double value2=0;
try {
value1=Double.parseDouble(String.valueOf(HorizontalDistance_Edit.getText()));
value2=Double.parseDouble(String.valueOf(VerticalDistance_Edit.getText()));
}
catch(Exception e)
{
Toast.makeText(roughActivity, "输入不能为空", Toast.LENGTH_SHORT).show();
return;
}
if(value1>=0 && value1<=50)
{
roughActivity.HorizontalDistance=String.valueOf(value1);
}else{
Toast.makeText(roughActivity, "请输入0-50的数字", Toast.LENGTH_SHORT).show();
HorizontalDistance_Edit.setText("0.0");
return;
}
if(value2>=0 && value2<=50)
{
roughActivity.VerticalDistance=String.valueOf(value2);
}else{
Toast.makeText(roughActivity, "请输入0-50的数字", Toast.LENGTH_SHORT).show();
VerticalDistance_Edit.setText("0.0");
return;
}
dialog.dismiss(); // 关闭弹窗
});
// 设置取消按钮点击事件
cancelButton.setOnClickListener(v -> {
Toast.makeText(roughActivity, "点击了取消", Toast.LENGTH_SHORT).show();
dialog.dismiss(); // 关闭弹窗
});
/*显示弹窗*/
dialog.show();
}
public void ParametersCallPopup_Paint(View.OnClickListener context,MyDataHelper myDataHelper ) {
Dialog dialog = new Dialog(paintActivity);
dialog.setContentView(R.layout.parameters_call_paint); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
// 获取布局中的视图
Button exitButton = dialog.findViewById(R.id.parametersExitPaint);
Button confirmButton = dialog.findViewById(R.id.parametersApplyPaint);
Button saveButton=dialog.findViewById(R.id.parametersSavebtnPaint);
Button clearButton=dialog.findViewById(R.id.parametersClearBtnPaint);
RadioGroup radioGroup = (RadioGroup) dialog.findViewById(R.id.parameters_call_group_paint);
Integer ii= ConvertHelper.convertEditTextToInt(paintActivity.mainBinding.MaintvParameterCallTo32);
switch (ii)
{
case 1: { radioGroup.check(R.id.rb_paraOnePaint);
break;
}
case 2: { radioGroup.check(R.id.rb_paraTwoPaint);
break;
}
case 3: { radioGroup.check(R.id.rb_paraThreePaint);
break;
}
case 4: { radioGroup.check(R.id.rb_paraFourPaint);
break;
}
case 5: { radioGroup.check(R.id.rb_paraFivePaint);
break;
}
default:
radioGroup.clearCheck();
break;
}
dialog.show(); // 显示弹窗
//调用值更新
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
try {
RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
result = radioButton.getText().toString();
// mainActivity._parameters_Call_Value = result;
}
catch (Exception e) {
/* 按钮都未选中*/
}
}
});
//保存按钮 获取界面参数 存入数据库
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int selectedId = radioGroup.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(paintActivity, "未选中参数,无法保存", Toast.LENGTH_SHORT).show();
return;
}
//获取界面参数以写进数据库
int paraIndex = Integer.parseInt(paintActivity.mainBinding.MaintvParameterCallTo32.getText().toString());
int laneChangeDistance = Integer.parseInt(paintActivity.mainBinding.MaintvLaneChangeDistanceTo32.getText().toString());
double verticalAdjust = Double.parseDouble(paintActivity.mainBinding.MaintvVerticalAdjustTo32.getText().toString());
// 把界面中的值放进PV类的变量中
DisplayPV displayPV = new DisplayPV(paraIndex, laneChangeDistance,0,0, verticalAdjust,0,0, 0 );
myDataHelper.addOrUpdateDisplayDataPaint(displayPV); //创建数据库的实例在这里 PV传进去保存到数据库
Toast.makeText(dialog.getContext(), "保存成功", Toast.LENGTH_SHORT).show();
}
});
//清除按钮 界面显示设为默认值 并存入数据库
clearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int selectedId = radioGroup.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(paintActivity, "未选中参数,无法清除", Toast.LENGTH_SHORT).show();
return;
}
paintActivity.mainBinding.MaintvLaneChangeDistanceTo32.setText(String.valueOf(1));
paintActivity.mainBinding.MaintvVerticalAdjustTo32.setText(String.valueOf(0));
//获取界面参数以写进数据库
int paraIndex = Integer.parseInt(paintActivity.mainBinding.MaintvParameterCallTo32.getText().toString());
int laneChangeDistance = Integer.parseInt(paintActivity.mainBinding.MaintvLaneChangeDistanceTo32.getText().toString());
double verticalAdjust =Double.parseDouble(paintActivity.mainBinding.MaintvVerticalAdjustTo32.getText().toString());
//把界面中的值放进PV类的变量中
DisplayPV displayPV = new DisplayPV(paraIndex, laneChangeDistance,0,0, verticalAdjust,0, 0, 0 );
myDataHelper.addOrUpdateDisplayDataPaint(displayPV); //创建数据库的实例在这里 PV传进去保存到数据库
Toast.makeText(dialog.getContext(), "清除成功", Toast.LENGTH_SHORT).show();
}
});
// 使用按钮 点击事件 //把主界面 调用值显示 改了 并从数据库中读赋值给界面
confirmButton.setOnClickListener(v -> {
/*未选中时设为无*/
int selectedId = radioGroup.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(paintActivity, "未使用预设参数", Toast.LENGTH_SHORT).show();
paintActivity.mainBinding.MaintvParameterCallTo32.setText("无");
return;
}
paintActivity._parameters_Call_Value = result;
paintActivity.mainBinding.MaintvParameterCallTo32.setText(paintActivity._parameters_Call_Value);//把主界面 调用值显示 改了
//读取数据
int paraIndex = Integer.parseInt(paintActivity._parameters_Call_Value);
List<DisplayPV> pvList = paintActivity.myDataHelper.getDisplayDataPaint(paraIndex);//从数据库中读,,并对其他控件进行赋值
paintActivity.mainBinding.MaintvLaneChangeDistanceTo32.setText(String.valueOf(pvList.get(0).getLaneChangeDistance()));
paintActivity.mainBinding.MaintvVerticalAdjustTo32.setText(String.valueOf(pvList.get(0).getVerticalAdjust()));
//读取数据库,并对其他控件进行赋值
Toast.makeText(dialog.getContext(), "调用成功", Toast.LENGTH_SHORT).show();
// dialog.dismiss(); // 关闭弹窗
});
// 退出按钮点击事件
exitButton.setOnClickListener(v -> {
Toast.makeText(dialog.getContext(), "点击了退出", Toast.LENGTH_SHORT).show();
dialog.dismiss(); // 关闭弹窗
});
}
public void ParametersCallPopup_Rough(View.OnClickListener context,MyDataHelper myDataHelper ) {
Dialog dialog = new Dialog(roughActivity);
dialog.setContentView(R.layout.parameters_call_rough); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
// 获取布局中的视图
Button exitButton = dialog.findViewById(R.id.parametersExitRough);
Button confirmButton = dialog.findViewById(R.id.parametersApplyRough);
Button saveButton=dialog.findViewById(R.id.parametersSavebtnRough);
Button clearButton=dialog.findViewById(R.id.parametersClearBtnRough);
RadioGroup radioGroup = (RadioGroup) dialog.findViewById(R.id.parameters_call_group_rough);
Integer ii= ConvertHelper.convertEditTextToInt(roughActivity.mainBinding.MaintvParameterCallTo32);
switch (ii)
{
case 1: { radioGroup.check(R.id.rb_paraOneRough);
break;
}
case 2: { radioGroup.check(R.id.rb_paraTwoRough);
break;
}
case 3: { radioGroup.check(R.id.rb_paraThreeRough);
break;
}
case 4: { radioGroup.check(R.id.rb_paraFourRough);
break;
}
case 5: { radioGroup.check(R.id.rb_paraFiveRough);
break;
}
default:
radioGroup.clearCheck();
break;
}
dialog.show(); // 显示弹窗
//参数调用值更新
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
try {
RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
result = radioButton.getText().toString();
// mainActivity._parameters_Call_Value = result;
} catch (Exception e) {
//**/
}
}
});
//保存按钮 获取界面参数 存入数据库
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int selectedId = radioGroup.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(roughActivity, "未选中参数,无法保存", Toast.LENGTH_SHORT).show();
return;
}
//获取界面参数以写进数据库
int paraIndex = Integer.parseInt(roughActivity.mainBinding.MaintvParameterCallTo32.getText().toString());
int laneChangeDistance = Integer.parseInt(roughActivity.mainBinding.MaintvLaneChangeDistanceTo32.getText().toString());
double verticalAdjust = Double.parseDouble(roughActivity.mainBinding.MaintvVerticalAdjustTo32.getText().toString());
double horizontalDistance = Double.parseDouble(roughActivity.HorizontalDistance);
double verticalDistance = Double.parseDouble(roughActivity.VerticalDistance);
double leftCompensation=Double.parseDouble(roughActivity.mainBinding.tvLCompensationFrom32.getText().toString());
double rightCompensation=Double.parseDouble(roughActivity.mainBinding.tvRCopmpensationFrom32.getText().toString());
int pressSet=Integer.parseInt(roughActivity.mainBinding.MaintvPressTo32.getText().toString());
//把界面中的值放进PV类的变量中
DisplayPV displayPV = new DisplayPV(paraIndex, laneChangeDistance,horizontalDistance,verticalDistance,verticalAdjust ,leftCompensation,rightCompensation, pressSet );
myDataHelper.addOrUpdateDisplayDataRough(displayPV); //创建数据库的实例在这里 PV传进去保存到数据库
Toast.makeText(dialog.getContext(), "保存成功", Toast.LENGTH_SHORT).show();
}
});
//清除按钮 界面显示设为默认值 并存入数据库
clearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int selectedId = radioGroup.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(roughActivity, "未选中参数,无法清除", Toast.LENGTH_SHORT).show();
return;
}
roughActivity.mainBinding.MaintvLaneChangeDistanceTo32.setText(String.valueOf(1));
roughActivity.mainBinding.MaintvVerticalAdjustTo32.setText(String.valueOf(0));
roughActivity.mainBinding.MaintvPressTo32.setText(String.valueOf(0));
roughActivity.mainBinding.tvLCompensationFrom32.setText(String.valueOf(0));
roughActivity.mainBinding.tvRCopmpensationFrom32.setText(String.valueOf(0));
roughActivity.HorizontalDistance=String.valueOf(0);
roughActivity.VerticalDistance=String.valueOf(0);
//获取界面参数以写进数据库
int paraIndex = Integer.parseInt(roughActivity.mainBinding.MaintvParameterCallTo32.getText().toString());
int laneChangeDistance = Integer.parseInt(roughActivity.mainBinding.MaintvLaneChangeDistanceTo32.getText().toString());
double verticalAdjust = Double.parseDouble(roughActivity.mainBinding.MaintvVerticalAdjustTo32.getText().toString());
double horizontalDistance = Double.parseDouble(roughActivity.HorizontalDistance);
double verticalDistance = Double.parseDouble(roughActivity.VerticalDistance);
double leftCompensation=Double.parseDouble(roughActivity.mainBinding.tvLCompensationFrom32.getText().toString());
double rightCompensation=Double.parseDouble(roughActivity.mainBinding.tvRCopmpensationFrom32.getText().toString());
int pressSet=Integer.parseInt(roughActivity.mainBinding.MaintvPressTo32.getText().toString());
//把界面中的值放进PV类的变量中
DisplayPV displayPV = new DisplayPV(paraIndex, laneChangeDistance,horizontalDistance,verticalDistance,verticalAdjust ,leftCompensation,rightCompensation, pressSet );
myDataHelper.addOrUpdateDisplayDataRough(displayPV); //创建数据库的实例在这里 PV传进去保存到数据库
Toast.makeText(dialog.getContext(), "清除成功", Toast.LENGTH_SHORT).show();
}
});
// 使用按钮 点击事件 //把主界面 调用值显示 改了 并从数据库中读赋值给界面
confirmButton.setOnClickListener(v -> {
/*未选中时设为无*/
int selectedId = radioGroup.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(roughActivity, "未使用预设参数", Toast.LENGTH_SHORT).show();
roughActivity.mainBinding.MaintvParameterCallTo32.setText("无");
return;
}
roughActivity._parameters_Call_Value = result;
roughActivity.mainBinding.MaintvParameterCallTo32.setText(roughActivity._parameters_Call_Value);//把主界面 调用值显示 改了
//读取数据
int paraIndex = Integer.parseInt(roughActivity._parameters_Call_Value);
List<DisplayPV> pvList = roughActivity.myDataHelper.getDisplayDataRough(paraIndex);//从数据库中读,,并对其他控件进行赋值
roughActivity.mainBinding.MaintvLaneChangeDistanceTo32.setText(String.valueOf(pvList.get(0).getLaneChangeDistance()));
roughActivity.mainBinding.MaintvVerticalAdjustTo32.setText(String.valueOf(pvList.get(0).getVerticalAdjust()));
roughActivity.HorizontalDistance=String.valueOf(pvList.get(0).getHorizontalDistance());
roughActivity.VerticalDistance=String.valueOf(pvList.get(0).getVerticalDistance());
roughActivity.mainBinding.tvLCompensationFrom32.setText(String.valueOf(pvList.get(0).getLeftCompensation()));
roughActivity.mainBinding.tvRCopmpensationFrom32.setText(String.valueOf(pvList.get(0).getRightCompensation()));
roughActivity.mainBinding.MaintvPressTo32.setText(String.valueOf(pvList.get(0).getPressSet()));
//读取数据库,并对其他控件进行赋值
Toast.makeText(dialog.getContext(), "调用成功", Toast.LENGTH_SHORT).show();
// dialog.dismiss(); // 关闭弹窗
});
// 退出按钮点击事件
exitButton.setOnClickListener(v -> {
Toast.makeText(dialog.getContext(), "点击了退出", Toast.LENGTH_SHORT).show();
dialog.dismiss(); // 关闭弹窗
});
}
public void RobotErrorListPopUp_Paint(View.OnClickListener context)
{
Dialog dialog = new Dialog(paintActivity);
dialog.setContentView(R.layout.log_item_paint); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
TextView LogText = dialog.findViewById(R.id.popUpErrorLogTextView_Paint);
ScrollBottomScrollView LogScrollView = dialog.findViewById(R.id.popUpErrorLogScrollview_Paint);
List<ErrorModel> list = paintActivity.myDataHelper.GetAllErrorModelsPaint(); //读取错误表
LogText.setMovementMethod(ScrollingMovementMethod.getInstance());
final int[] firstDisplay = {1};
final int[] display = {2};
final int[] displayOver = {0};
int displayNum = 25;
LogScrollView.post(new Runnable() {
@Override
public void run() {
if(firstDisplay[0] == 1){
//滑动顶部
LogScrollView.fullScroll(ScrollView.FOCUS_UP);
firstDisplay[0] = 0;
}
}
});
LogScrollView.onScrollViewScrollToBottom(new ScrollBottomScrollView.OnScrollBottomListener() {
@Override
public void scrollToBottom() {
//请求数据
if (!list.isEmpty()) {
if(list.size()>displayNum * display[0]) {
for(int i = list.size() - displayNum * (display[0]-1); i-- > list.size() - displayNum * display[0];){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
}
display[0] ++;
}
else{
if(displayOver[0]==0){
for(int i = list.size() - displayNum * (display[0]-1); i-- > 0;){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
displayOver[0]=1;
}
}
}
}
}});
if (!list.isEmpty()) {
if(list.size()>displayNum) {
for(int i = list.size(); i-- > list.size() - displayNum;){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
}
}
else{
for(int i = list.size(); i-- > 0;){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
}
}
}
// String list3 = mainActivity.myDataHelper.DeleteAllErrorModels();
dialog.show(); // 显示弹窗
}
public void RobotErrorListPopUp_Rough(View.OnClickListener context)
{
Dialog dialog = new Dialog(roughActivity);
dialog.setContentView(R.layout.log_item_rough); // 设置自定义布局
dialog.setCancelable(true); // 设置点击外部是否关闭弹窗
TextView LogText = dialog.findViewById(R.id.popUpErrorLogTextView_Rough);
ScrollBottomScrollView LogScrollView = dialog.findViewById(R.id.popUpErrorLogScrollview_Rough);
List<ErrorModel> list = roughActivity.myDataHelper.GetAllErrorModelsRough(); //读取错误表
LogText.setMovementMethod(ScrollingMovementMethod.getInstance());
final int[] firstDisplay = {1};
final int[] display = {2};
final int[] displayOver = {0};
int displayNum = 25;
LogScrollView.post(new Runnable() {
@Override
public void run() {
if(firstDisplay[0] == 1){
//滑动顶部
LogScrollView.fullScroll(ScrollView.FOCUS_UP);
firstDisplay[0] = 0;
}
}
});
LogScrollView.onScrollViewScrollToBottom(new ScrollBottomScrollView.OnScrollBottomListener() {
@Override
public void scrollToBottom() {
//请求数据
if (!list.isEmpty()) {
if(list.size()>displayNum * display[0]) {
for(int i = list.size() - displayNum * (display[0]-1); i-- > list.size() - displayNum * display[0];){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
}
display[0] ++;
}
else{
if(displayOver[0]==0){
for(int i = list.size() - displayNum * (display[0]-1); i-- > 0;){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
displayOver[0]=1;
}
}
}
}
}});
if (!list.isEmpty()) {
if(list.size()>displayNum) {
for(int i = list.size(); i-- > list.size() - displayNum;){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
}
}
else{
for(int i = list.size(); i-- > 0;){
ErrorModel item = list.get(i);
String RobotErrorLog = item.getDateTimeBJ() + item.getErrorInfo() +"\n";
LogText.append(RobotErrorLog);
}
}
}
// String list3 = mainActivity.myDataHelper.DeleteAllErrorModels();
dialog.show(); // 显示弹窗
}
} //根类

373
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ReceiivedIVHandler.java

@ -0,0 +1,373 @@
package com.example.paint_rough_inone_appv1_0.services;
import static com.example.paint_rough_inone_appv1_0.services.ErrorDeocdeHelper.ErrorDeocde;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.TextView;
import android.widget.Toast;
import com.example.paint_rough_inone_appv1_0.R;
import com.example.paint_rough_inone_appv1_0.models.BspIV;
import com.example.paint_rough_inone_appv1_0.models.ErrorModel;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.Objects;
public class ReceiivedIVHandler {
static String errorLastPaint = "";
static String errorLastRough = "";
public static int receiveMeasurePaint = 0;
public static int receiveMeasureRough = 0;
private static final int Buttons_Not_Reset = 0;
private static final int Not_Intialized = 1;
private static final int Move_Halt = 2;
private static final int Move_Forward = 3;
private static final int Move_Backward = 4;
private static final int Move_TurnLeft = 5;
private static final int Move_TurnRight = 6;
private static final int Emergency_Stop = 7;
private static final int Upper_Computer_TakenOver = 8;
private static final int Sbus_Not_Online = 9;
private static final int Android_Down = 10;
private static final int Cruise_Ahead = 11;
private static final int Cruise_Back = 12;
public static void midToast(String str, int showTime, com.example.paint_rough_inone_appv1_0.MainActivity MainActivity) {
Toast toast = Toast.makeText(MainActivity, str, showTime);
toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0); //设置显示位置
TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
v.setTextColor(Color.YELLOW); //设置字体颜色
toast.show();
}
public static BspIV.IV_struct_define _toReceiveIV = BspIV.IV_struct_define.newBuilder().build();//上一次有效数据
public static BspIV.IV_struct_define _toReceiveIV_Variable = BspIV.IV_struct_define.newBuilder().build();//最新数据
public static void HandleDataPaint(com.example.paint_rough_inone_appv1_0.PaintActivity PaintActivity, byte[] data) {
try {
receiveMeasurePaint = 0;
byte[] crcbytes = new byte[data.length - 2];
System.arraycopy(data, 0, crcbytes, 0, data.length - 2);
byte[] crc = ModbusCRC.calculateCRC(crcbytes);
// status(bytesToHex(data));
if (data[data.length - 2] == (byte) (crc[1] & 0xff) && data[data.length - 1] == (byte) (crc[0] & 0xff)) {
if ((data[0] == 0x55) && (data[1] == 0x55)) {
byte[] bytes = new byte[data.length - 4];
System.arraycopy(data, 2, bytes, 0, data.length - 4);
try {
_toReceiveIV_Variable = BspIV.IV_struct_define.parseFrom(bytes);//单片机新数据到来
if (_toReceiveIV_Variable != null) {
if (_toReceiveIV_Variable.getIsRestart() == 1)//单片机重启 将收到的时间戳归0
{
_toReceiveIV = _toReceiveIV.toBuilder().setTimeStamp(0).build();
// MainActivity._toSendPV=MainActivity._toSendPV.toBuilder().setIVIsRestartNotified(1).build();
}
//新数据的时间大于上次时间 将新数据赋值给上次数据
if (_toReceiveIV_Variable.getTimeStamp() >= _toReceiveIV.getTimeStamp()) {
_toReceiveIV = _toReceiveIV_Variable;
}
}
if (_toReceiveIV != null) {
PaintActivity.runOnUiThread(() -> {
PaintActivity.mainBinding.tvSpeedFrom32.setText(String.valueOf(_toReceiveIV.getRobotMoveSpeed()));
PaintActivity.mainBinding.tvAngleFrom32.setText(String.valueOf((double) _toReceiveIV.getCurrentAngle() / 100));
PaintActivity.mainBinding.tvCurrentSpeedFrom32.setText(String.valueOf(_toReceiveIV.getCurrentSpeed()));
if (_toReceiveIV.getSBUSState() == 0) {
PaintActivity.mainBinding.tvSignal.setText("断开");
} else if (_toReceiveIV.getSBUSState() == 1) {
PaintActivity.mainBinding.tvSignal.setText("已连接");
}
/******************************硬件错误*****************************/
int errorInt = _toReceiveIV.getSystemError();//硬件错误
String errorString2 = ErrorDeocde(errorInt);
String errorString = " # " + unsignedIntToBinaryWithSeparator(errorInt);
errorString += " " + toHex4Digits(_toReceiveIV.getLeftMotorErr());
errorString += " " + toHex4Digits(_toReceiveIV.getRightMotorErr());
if (errorInt != 0 || _toReceiveIV.getLeftMotorErr() != 0 || _toReceiveIV.getRightMotorErr() != 0) {
if (!Objects.equals(errorLastPaint, errorString)) {
ErrorModel em = new ErrorModel(System.currentTimeMillis(), errorString);
PaintActivity.myDataHelper.AddOrUpdateErrorModelPaint(em);
if (Objects.equals(errorString2, "未复位")) {
PaintActivity.mainBinding.mainViewErrMessageTxViewPaint.setText(String.valueOf(errorString2));
}
else {
PaintActivity.mainBinding.mainViewErrMessageTxViewPaint.setText("有");
PaintActivity.mainBinding.messageRoundedPaint.setBackgroundResource(R.drawable.message_rounded_rectangle_red);
}
errorLastPaint = errorString;
}
}
else {
errorLastPaint = errorString;
PaintActivity.mainBinding.mainViewErrMessageTxViewPaint.setText("无");
PaintActivity.mainBinding.messageRoundedPaint.setBackgroundResource(R.drawable.orange_rounded_rectangle);
}
if (_toReceiveIV.getIsWorking() == 1) {
PaintActivity.mainBinding.rightSend.setEnabled(false);
PaintActivity.mainBinding.rightSend.setAlpha(0.5f);
PaintActivity.mainBinding.setManualModeBtnPaint.setEnabled(false);
PaintActivity.mainBinding.setManualModeBtnPaint.setAlpha(0.5f);
PaintActivity.mainBinding.MaintvLaneChangeDistanceTo32.setEnabled(false);
PaintActivity.mainBinding.MaintvLaneChangeDistanceTo32.setAlpha(0.5f);
PaintActivity.mainBinding.MaintvVerticalAdjustTo32.setEnabled(false);
PaintActivity.mainBinding.MaintvVerticalAdjustTo32.setAlpha(0.5f);
PaintActivity.mainBinding.setcallParametersBtnPaint.setEnabled(false);
PaintActivity.mainBinding.setcallParametersBtnPaint.setAlpha(0.5f);
}
else {
PaintActivity.mainBinding.rightSend.setEnabled(true);
PaintActivity.mainBinding.rightSend.setAlpha(1.0f);
PaintActivity.mainBinding.setManualModeBtnPaint.setEnabled(true);
PaintActivity.mainBinding.setManualModeBtnPaint.setAlpha(1.0f);
PaintActivity.mainBinding.MaintvLaneChangeDistanceTo32.setEnabled(true);
PaintActivity.mainBinding.MaintvLaneChangeDistanceTo32.setAlpha(1.0f);
PaintActivity.mainBinding.MaintvVerticalAdjustTo32.setEnabled(true);
PaintActivity.mainBinding.MaintvVerticalAdjustTo32.setAlpha(1.0f);
PaintActivity.mainBinding.setcallParametersBtnPaint.setEnabled(true);
PaintActivity.mainBinding.setcallParametersBtnPaint.setAlpha(1.0f);
}
});
} else {
}
}
catch (InvalidProtocolBufferException ex) {
}
}
else{
}
}
else {
//status("crc failed");
}
}
catch(Exception e){
}
}
public static void HandleDataRough (com.example.paint_rough_inone_appv1_0.RoughActivity RoughActivity,byte[] data) {
try {
receiveMeasureRough = 0;//接收置0
byte[] crcbytes = new byte[data.length - 2];
System.arraycopy(data, 0, crcbytes, 0, data.length - 2);
byte[] crc = ModbusCRC.calculateCRC(crcbytes);
// status(bytesToHex(data));
if (data[data.length - 2] == (byte) (crc[1] & 0xff) && data[data.length - 1] == (byte) (crc[0] & 0xff)) {
if ((data[0] == 0x55) && (data[1] == 0x55)) {
byte[] bytes = new byte[data.length - 4];
System.arraycopy(data, 2, bytes, 0, data.length - 4);
try {
_toReceiveIV_Variable = BspIV.IV_struct_define.parseFrom(bytes);//单片机新数据到来
if (_toReceiveIV_Variable != null) {
if (_toReceiveIV_Variable.getIsRestart() == 1)//单片机重启 将收到的时间戳归0
{
_toReceiveIV = _toReceiveIV.toBuilder().setTimeStamp(0).build();
}
//新数据的时间大于上次时间 将新数据赋值给上次数据
if (_toReceiveIV_Variable.getTimeStamp() >= _toReceiveIV.getTimeStamp()) {
_toReceiveIV = _toReceiveIV_Variable;
}
}
if (_toReceiveIV != null) {
RoughActivity.runOnUiThread(() -> {
RoughActivity.mainBinding.tvCurrentSpeedFrom32.setText(String.valueOf(_toReceiveIV.getCurrentSpeed()));
RoughActivity.mainBinding.tvSpeedFrom32.setText(String.valueOf(_toReceiveIV.getRobotMoveSpeed()));
RoughActivity.mainBinding.tvLCompensationFrom32.setText(String.valueOf((double) _toReceiveIV.getLeftCompensation() / 100));
RoughActivity.mainBinding.tvRCopmpensationFrom32.setText(String.valueOf((double) _toReceiveIV.getRightCompensation() / 100));
RoughActivity.mainBinding.tvPressFrom32.setText(String.valueOf(_toReceiveIV.getPress()));
RoughActivity.mainBinding.tvAngleFrom32.setText(String.valueOf((double) _toReceiveIV.getCurrentAngle() / 100));
if (_toReceiveIV.getSBUSState() == 0) {
RoughActivity.mainBinding.tvSignal.setText("断开");
} else if (_toReceiveIV.getSBUSState() == 1) {
RoughActivity.mainBinding.tvSignal.setText("已连接");
}
/******************************硬件错误*****************************/
int errorInt = _toReceiveIV.getSystemError();//硬件错误
String errorString2 = ErrorDeocde(errorInt); //未复位 null
String errorString = " # " + unsignedIntToBinaryWithSeparator(errorInt);
errorString += " " + toHex4Digits(_toReceiveIV.getLeftMotorErr());
errorString += " " + toHex4Digits(_toReceiveIV.getRightMotorErr());
if (errorInt != 0 || _toReceiveIV.getLeftMotorErr() != 0 || _toReceiveIV.getRightMotorErr() != 0) {
if (!Objects.equals(errorLastRough, errorString)) { /*错误变了才显示*/
ErrorModel em = new ErrorModel(System.currentTimeMillis(), errorString);
RoughActivity.myDataHelper.AddOrUpdateErrorModelRough(em);
if (Objects.equals(errorString2, "未复位")) {
RoughActivity.mainBinding.mainViewErrMessageTxViewRough.setText(String.valueOf(errorString2));
} else {
RoughActivity.mainBinding.mainViewErrMessageTxViewRough.setText("有");
RoughActivity.mainBinding.errorBackgroundRough.setBackgroundColor(Color.RED);
}
errorLastRough = errorString;//错误码的二进制位
}
} else {
errorLastRough = errorString;//错误码的二进制位
RoughActivity.mainBinding.mainViewErrMessageTxViewRough.setText("无");
RoughActivity.mainBinding.errorBackgroundRough.setBackgroundColor(Color.TRANSPARENT);
}
if (_toReceiveIV.getIsWorking() == 1) {
RoughActivity.mainBinding.rightSend.setEnabled(false);
RoughActivity.mainBinding.rightSend.setAlpha(0.5f);
RoughActivity.mainBinding.setManualModeBtn.setEnabled(false);
RoughActivity.mainBinding.setManualModeBtn.setAlpha(0.5f);
RoughActivity.mainBinding.setAutoModeBtn.setEnabled(false);
RoughActivity.mainBinding.setAutoModeBtn.setAlpha(0.5f);
RoughActivity.mainBinding.MaintvLaneChangeDistanceTo32.setEnabled(false);
RoughActivity.mainBinding.MaintvLaneChangeDistanceTo32.setAlpha(0.5f);
RoughActivity.mainBinding.MaintvVerticalAdjustTo32.setEnabled(false);
RoughActivity.mainBinding.MaintvVerticalAdjustTo32.setAlpha(0.5f);
RoughActivity.mainBinding.MaintvPressTo32.setEnabled(false);
RoughActivity.mainBinding.MaintvPressTo32.setAlpha(0.5f);
RoughActivity.mainBinding.setcallParametersBtn.setEnabled(false);
RoughActivity.mainBinding.setcallParametersBtn.setAlpha(0.5f);
}
else {
RoughActivity.mainBinding.rightSend.setEnabled(true);
RoughActivity.mainBinding.rightSend.setAlpha(1.0f);
RoughActivity.mainBinding.setManualModeBtn.setEnabled(true);
RoughActivity.mainBinding.setManualModeBtn.setAlpha(1.0f);
RoughActivity.mainBinding.setAutoModeBtn.setEnabled(true);
RoughActivity.mainBinding.setAutoModeBtn.setAlpha(1.0f);
RoughActivity.mainBinding.MaintvLaneChangeDistanceTo32.setEnabled(true);
RoughActivity.mainBinding.MaintvLaneChangeDistanceTo32.setAlpha(1.0f);
RoughActivity.mainBinding.MaintvVerticalAdjustTo32.setEnabled(true);
RoughActivity.mainBinding.MaintvVerticalAdjustTo32.setAlpha(1.0f);
RoughActivity.mainBinding.MaintvPressTo32.setEnabled(true);
RoughActivity.mainBinding.MaintvPressTo32.setAlpha(1.0f);
RoughActivity.mainBinding.setcallParametersBtn.setEnabled(true);
RoughActivity.mainBinding.setcallParametersBtn.setAlpha(1.0f);
}
});
} else { //_toReceiveIV == null
}
}
catch (InvalidProtocolBufferException ex) {
}
}
else{ //前两个数据不对
}
}
else { //status("crc failed");
}
}
catch (Exception e) {
}
} //函数头结尾
/*
逐位检查并构建二进制字符串
*/
String unsignedIntToBinary ( int value){
StringBuilder sb = new StringBuilder(32);
for (int i = 7; i >= 0; i--) {
sb.append((value & (1 << i)) == 0 ? '0' : '1');
}
return sb.toString();
}
/*
逐位检查并构建二进制字符串 每4位添加一个分隔符
*/
static String unsignedIntToBinaryWithSeparator ( int value){
StringBuilder sb = new StringBuilder(35);
for (int i = 11; i >= 0; i--) {
sb.append((value & (1 << i)) == 0 ? '0' : '1');
if (i % 4 == 0 && i != 0) {
sb.append(' '); // 每4位添加一个分隔符
}
}
return sb.toString();
}
static String toHex4Digits ( int value){
char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int low16Bits = value & 0xFFFF;
char[] result = new char[4];
result[0] = hexChars[(low16Bits >> 12) & 0xF];
result[1] = hexChars[(low16Bits >> 8) & 0xF];
result[2] = hexChars[(low16Bits >> 4) & 0xF];
result[3] = hexChars[low16Bits & 0xF];
return new String(result);
}
}

63
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/RobotDataHanlder.java

@ -0,0 +1,63 @@
package com.example.paint_rough_inone_appv1_0.services;
import com.example.paint_rough_inone_appv1_0.models.BspIV;
import com.example.paint_rough_inone_appv1_0.models.BspPV;
import com.google.protobuf.InvalidProtocolBufferException;
public class RobotDataHanlder {
public static void test()
{
//byte[] data=hexToByteArray("080110830118313A04B1CBBACF");
byte[] data=hexToByteArray("100A180A28013A32B1CBBACF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
}
public static void DeoodeDataFromRobot(byte[] data)
{
try
{
if(data[0]==0x55&&data[1]==0x55)
{
if (data[2]==0x01)
{
BspIV.IV_struct_define iv = BspIV.IV_struct_define.parseFrom(data);
}else if(data[2]==0x02)
{
BspPV.PV_struct_define pv = BspPV.PV_struct_define.parseFrom(data);
}
}
} catch (InvalidProtocolBufferException e)
{
}
}
public static byte[] hexToByteArray(String inHex){
int hexlen = inHex.length();
byte[] result;
if (hexlen % 2 == 1){
//奇数
hexlen++;
result = new byte[(hexlen/2)];
inHex="0"+inHex;
}else {
//偶数
result = new byte[(hexlen/2)];
}
int j=0;
for (int i = 0; i < hexlen; i+=2){
result[j]=hexToByte(inHex.substring(i,i+2));
j++;
}
return result;
}
public static byte hexToByte(String inHex){
return (byte)Integer.parseInt(inHex,16);
}
}

53
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ToggleRadioButton.java

@ -0,0 +1,53 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewParent;
import android.widget.RadioGroup;
import androidx.appcompat.widget.AppCompatRadioButton;
/**********自己的raidobutton按钮类*************/
public class ToggleRadioButton extends AppCompatRadioButton {
public ToggleRadioButton(Context context) {
super(context);
}
public ToggleRadioButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ToggleRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean performClick() {
// 获取当前选中状态
boolean wasChecked = isChecked();
// 先让父类处理点击事件(这会触发正常的选中逻辑)
boolean result = super.performClick();
// 如果点击前已经是选中状态,说明用户想要取消选中
if (wasChecked) {
setChecked(false);
// 需要手动清除RadioGroup的选择状态
clearSelectionInParent();
}
return result;
}
/**
* 清除父RadioGroup中的选择状态
*/
private void clearSelectionInParent() {
ViewParent parent = getParent();
if (parent instanceof RadioGroup) {
((RadioGroup) parent).clearCheck();
}
}
}

528
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/USBSerialPortHelper.java

@ -0,0 +1,528 @@
package com.example.paint_rough_inone_appv1_0.services;
import static com.example.paint_rough_inone_appv1_0.services.ErrorDeocdeHelper.ErrorDeocde;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import androidx.core.content.ContextCompat;
import com.example.paint_rough_inone_appv1_0.BuildConfig;
import com.example.paint_rough_inone_appv1_0.MainActivity;
import com.example.paint_rough_inone_appv1_0.PaintActivity;
import com.example.paint_rough_inone_appv1_0.RoughActivity;
import com.example.paint_rough_inone_appv1_0.models.BspIV;
import com.example.paint_rough_inone_appv1_0.models.ErrorModel;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.hoho.android.usbserial.util.SerialInputOutputManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
public class USBSerialPortHelper implements SerialInputOutputManager.Listener {
private Activity mActivity;
private PaintActivity activityPaint;
private RoughActivity activityRough;
public USBSerialPortHelper(PaintActivity activityPaint, RoughActivity activityRough, MainActivity mainActivity)
{
if(activityPaint!=null) {
this.mActivity = activityPaint;
this.activityPaint=activityPaint;
}
if(activityRough!=null) {
this.mActivity = activityRough;
this.activityRough=activityRough;
}
if(mainActivity!=null) {
this.mActivity = mainActivity;
}
}
private enum UsbPermission {Unknown, Requested, Granted, Denied}
private final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
// <usb-device vendor-id="4292" product-id="60000" /> <!-- 0xea60: CP2102 and other CP210x single port devices -->
// <usb-device vendor-id="4292" product-id="60016" /> <!-- 0xea70: CP2105 -->
// <usb-device vendor-id="4292" product-id="60017" /> <!-- 0xea71: CP2108 -->
private int deviceId = 60000;
private int deviceId_test = 60000;
private int portNum;
private final int WRITE_WAIT_MILLIS = 500;
private final int READ_WAIT_MILLIS = 100;
private String PortNameContians = "SILICON";/**/
// private static String PortNameContians="FTD";
private int baudRate = 57600;
private boolean withIoManager = true;
private BroadcastReceiver broadcastReceiver;
private Handler mainLooper;
private SerialInputOutputManager usbIoManager;
private UsbSerialPort usbSerialPort;
private UsbPermission usbPermission = UsbPermission.Unknown;
private boolean connected = false;
BspIV.IV_struct_define _toReceiveIV1;
String errorLast = "";
public void intialize() {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (INTENT_ACTION_GRANT_USB.equals(intent.getAction())) {
usbPermission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false) ? UsbPermission.Granted : UsbPermission.Denied;
connect();
}
}
};
mainLooper = new Handler(Looper.getMainLooper());
_receiveBufferlist = new ArrayList<Byte>();
}
/*
* Serial
*/
@Override
public void onNewData(byte[] data) {
// status("new data");
mainLooper.post(() -> {
receive(data);
// receive data
});
}
@Override
public void onRunError(Exception e) {
mainLooper.post(() -> {
// status("connection lost: " + e.getMessage());
disconnect();
});
}
/*
* Serial + UI
*/
public void connect() {
UsbDevice device = null;
UsbManager usbManager = (UsbManager) mActivity.getSystemService(Context.USB_SERVICE);
for (UsbDevice v : usbManager.getDeviceList().values()) {
// status(v.getManufacturerName().toUpperCase());
if (v.getManufacturerName().toUpperCase().contains(PortNameContians)) {
device = v;
break;
}
}
if (device == null) {
// _serialPortSwitch.setChecked(false);
// status("找不到设备");
return;
}
UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);
if (driver == null) {
driver = CustomProber.getCustomProber().probeDevice(device);
}
if (driver == null) {
// _serialPortSwitch.setChecked(false);
// status("无驱动");
return;
}
if (driver.getPorts().size() < portNum) //就是0 cp2102 或者同一个驱动,第一个
{
//status("connection failed: not enough ports at device");
//status("找不到设备");
return;
}
usbSerialPort = driver.getPorts().get(portNum);
UsbDeviceConnection usbConnection = usbManager.openDevice(driver.getDevice());
if (usbConnection == null && usbPermission == UsbPermission.Unknown && !usbManager.hasPermission(driver.getDevice())) {
usbPermission = UsbPermission.Requested;
int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_MUTABLE : 0;
Intent intent = new Intent(INTENT_ACTION_GRANT_USB);
intent.setPackage(mActivity.getPackageName());
PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(mActivity, 0, intent, flags);
usbManager.requestPermission(driver.getDevice(), usbPermissionIntent);
return;
}
if (usbConnection == null) {
if (!usbManager.hasPermission(driver.getDevice())) {
// status("connection failed: permission denied");
} else {
// status("connection failed: open failed");
}
return;
}
try {
usbSerialPort.open(usbConnection);
try {
usbSerialPort.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
// status("connected: ");
} catch (UnsupportedOperationException e) {
//status("unsupport setparameters");
}
if (withIoManager) {
usbIoManager = new SerialInputOutputManager(usbSerialPort, this);
usbIoManager.setReadBufferSize(40960);
usbIoManager.setReadTimeout(READ_WAIT_MILLIS);
usbIoManager.start();
}
//status("connected");
connected = true;
// _serialPortSwitch.setChecked(true);
//switch set true
} catch (Exception e) {
// status("connection failed: " + e.getMessage());
disconnect();
}
}
public void disconnect() {
connected = false;
if (usbIoManager != null) {
usbIoManager.setListener(null);
usbIoManager.stop();
}
usbIoManager = null;
try {
usbSerialPort.close();
} catch (IOException ignored) {
}
usbSerialPort = null;
}
List<Byte> _receiveBufferlist;
private static byte[] listTobyte(List<Byte> list) {
if (list == null || list.size() < 0) return null;
byte[] bytes = new byte[list.size()];
int i = 0;
Iterator<Byte> iterator = list.iterator();
while (iterator.hasNext()) {
bytes[i] = iterator.next();
i++;
}
return bytes;
}
boolean StartCountDown = false;
// byte _receivedData
private void receive(byte[] data) {
// status("read data");
for (int i = 0; i < data.length; i++) {
_receiveBufferlist.add(data[i]);
}
//decodeRceive(data);
if (StartCountDown == false)//从收到第一个数据开始计时
{
StartCountDown = true;
new CountDownTimer(400, 200) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
// status("read finished");
decodeRceive(listTobyte(_receiveBufferlist));
_receiveBufferlist.clear();
StartCountDown = false;
}
}.start();
}
}
/*
逐位检查并构建二进制字符串
*/
String unsignedIntToBinary(int value) {
StringBuilder sb = new StringBuilder(32);
for (int i = 7; i >= 0; i--) {
sb.append((value & (1 << i)) == 0 ? '0' : '1');
}
return sb.toString();
}
/*
逐位检查并构建二进制字符串 每4位添加一个分隔符
*/
String unsignedIntToBinaryWithSeparator(int value) {
StringBuilder sb = new StringBuilder(35);
for (int i = 11; i >= 0; i--) {
sb.append((value & (1 << i)) == 0 ? '0' : '1');
if (i % 4 == 0 && i != 0) {
sb.append(' '); // 每4位添加一个分隔符
}
}
return sb.toString();
}
String toHex4Digits(int value) {
char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int low16Bits = value & 0xFFFF;
char[] result = new char[4];
result[0] = hexChars[(low16Bits >> 12) & 0xF];
result[1] = hexChars[(low16Bits >> 8) & 0xF];
result[2] = hexChars[(low16Bits >> 4) & 0xF];
result[3] = hexChars[low16Bits & 0xF];
return new String(result);
}
private void decodeRceive(byte[] data) {
try {
// String dataReceived = bytesToHex(data);
//status(dataReceived);
// if ((data[0] == 0xFE) && (data[1] == 0xFE))
byte[] crcbytes = new byte[data.length - 2];
System.arraycopy(data, 0, crcbytes, 0, data.length - 2);
byte[] crc=ModbusCRC.calculateCRC(crcbytes);
// status(bytesToHex(data));
// status(String.valueOf(crc[0]+" "+ String.valueOf(crc[1])));
if(data[data.length-2]==(byte)(crc[1]&0xff) && data[data.length-1]==(byte)(crc[0] & 0xff))
{
if ((data[0] == 0x55) && (data[1] == 0x55) )
{
byte[] bytes = new byte[data.length - 4];
System.arraycopy(data, 2, bytes, 0, data.length - 4);
BspIV.IV_struct_define _toReceiveIV=BspIV.IV_struct_define.parseFrom(bytes);
_toReceiveIV1=_toReceiveIV;
if (_toReceiveIV!=null)
{
PaintParaShow();
RoughParaShow();
int errorInt = _toReceiveIV.getSystemError();//硬件错误
activityErrorShow( errorInt, _toReceiveIV.getLeftMotorErr(), _toReceiveIV.getRightMotorErr());
}else
{
// status("null");
}
}else
{
}
}else
{
//status("crc failed");
}
} catch (Exception e) {
}
}
public void activityErrorShow(int errorInt,int leftmotorErr,int rightmotorError)
{
if(activityPaint!=null)
{
String errorString2 = ErrorDeocde(errorInt);
String errorString = " # " + unsignedIntToBinaryWithSeparator(errorInt);
errorString += " " + toHex4Digits(leftmotorErr);
errorString += " " + toHex4Digits(rightmotorError);
if(errorInt !=0 ||leftmotorErr!=0 ||rightmotorError!=0 )
{
if(!Objects.equals(errorLast, errorString)){
ErrorModel em = new ErrorModel(System.currentTimeMillis(), errorString);
activityPaint.myDataHelper.AddOrUpdateErrorModelPaint(em);
if(Objects.equals(errorString2, "未复位"))
{
activityPaint.mainBinding.mainViewErrMessageTxViewPaint.setText(String.valueOf(errorString2));
}
else
{
activityPaint.mainBinding.mainViewErrMessageTxViewPaint.setText("有");
}
errorLast = errorString;
}
}
else
{
activityPaint.mainBinding.mainViewErrMessageTxViewPaint.setText("无");
}
}
if(activityRough!=null)
{
String errorString2 = ErrorDeocde(errorInt);
String errorString = " # " + unsignedIntToBinaryWithSeparator(errorInt);
errorString += " " + toHex4Digits(leftmotorErr);
errorString += " " + toHex4Digits(rightmotorError);
if(errorInt !=0 ||leftmotorErr!=0 ||rightmotorError!=0 )
{
if(!Objects.equals(errorLast, errorString)){
ErrorModel em = new ErrorModel(System.currentTimeMillis(), errorString);
activityPaint.myDataHelper.AddOrUpdateErrorModelPaint(em);
if(Objects.equals(errorString2, "未复位"))
{
activityRough.mainBinding.mainViewErrMessageTxViewRough.setText(String.valueOf(errorString2));
}
else
{
activityRough.mainBinding.mainViewErrMessageTxViewRough.setText("有");
}
errorLast = errorString;
}
}
else
{
activityRough.mainBinding.mainViewErrMessageTxViewRough.setText("无");
}
}
}
public void PaintParaShow()
{
if(activityPaint!=null)
{
activityPaint.mainBinding.tvSpeedFrom32.setText(String.valueOf(_toReceiveIV1.getRobotMoveSpeed()));
activityPaint.mainBinding.tvAngleFrom32.setText(String.valueOf((double)_toReceiveIV1.getCurrentAngle()/100));
if(_toReceiveIV1.getSBUSState()==0)
{
activityPaint.mainBinding.tvSignal.setText("断开");
}
else if(_toReceiveIV1.getSBUSState()==1)
{
activityPaint.mainBinding.tvSignal.setText("已连接");
}
}
}
public void RoughParaShow()
{
if(activityRough!=null)
{
activityRough.mainBinding.tvSpeedFrom32.setText(String.valueOf(_toReceiveIV1.getRobotMoveSpeed()));
activityRough.mainBinding.tvAngleFrom32.setText(String.valueOf((double)_toReceiveIV1.getCurrentAngle()/100));
activityRough.mainBinding.tvLCompensationFrom32.setText( String.valueOf((double)_toReceiveIV1.getLeftCompensation()/10) );
activityRough.mainBinding.tvRCopmpensationFrom32.setText( String.valueOf((double)_toReceiveIV1.getRightCompensation()/10) );
if(_toReceiveIV1.getSBUSState()==0)
{
activityRough.mainBinding.tvSignal.setText("断开");
}
else if(_toReceiveIV1.getSBUSState()==1)
{
activityRough.mainBinding.tvSignal.setText("已连接");
}
}
}
public static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02X ", b & 0xFF));
}
return result.toString();
}
public void onStart() {
ContextCompat.registerReceiver(mActivity, broadcastReceiver, new IntentFilter(INTENT_ACTION_GRANT_USB), ContextCompat.RECEIVER_NOT_EXPORTED);
//status("onStart");
}
public void onStop() {
mActivity.unregisterReceiver(broadcastReceiver);
// status("onStop");
}
public void onResume() {
if (!connected && (usbPermission == UsbPermission.Unknown || usbPermission == UsbPermission.Granted)) {
mainLooper.post(this::connect);
}
}
public void onPause() {
if (connected) {
// status("串口断开");
// _serialPortSwitch.setChecked(false);
disconnect();
}
}
public void SendData(byte[] data) {
if (connected) {
try {
usbSerialPort.write(data, WRITE_WAIT_MILLIS);
} catch (IOException e)
{
// status("Send Failed");
connected = false;
}
}
else {
//status("usb serialport disconnected");
}
}
}

27
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/VideoPlayerHelper.java

@ -0,0 +1,27 @@
package com.example.paint_rough_inone_appv1_0.services;
import cn.nodemedia.NodePlayer;
import cn.nodemedia.NodePlayerView;
public class VideoPlayerHelper {
public static void startVedio(NodePlayerView nodePlayerView, NodePlayer nodePlayer,String address ){
nodePlayerView.setRenderType(NodePlayerView.RenderType.SURFACEVIEW);//设置渲染器类型
nodePlayerView.setUIViewContentMode(NodePlayerView.UIViewContentMode.ScaleToFill);//设置视频画面缩放模式
//nodePlayer=new NodePlayer(this);
nodePlayer.setPlayerView(nodePlayerView);//设置播放视图
//设置RTSP流使用的传输协议,支持的模式有:
nodePlayer.setRtspTransport(NodePlayer.RTSP_TRANSPORT_TCP);//设置传输
nodePlayer.setInputUrl(address);
nodePlayer.setVideoEnable(true);//设置视频启用
nodePlayer.setBufferTime(100);//设置缓冲时间
nodePlayer.setMaxBufferTime(200);//设置最大缓冲时间
nodePlayer.start();
}
}

85
app/src/main/java/com/example/paint_rough_inone_appv1_0/services/ttySerialPortHelper.java

@ -0,0 +1,85 @@
package com.example.paint_rough_inone_appv1_0.services;
import android.util.Log;
import com.example.paint_rough_inone_appv1_0.IVDataReceivedEvent;
import org.greenrobot.eventbus.EventBus;
import android_serialport_api.SerialPortFinder;
import tp.xmaihh.serialport.SerialHelper;
import tp.xmaihh.serialport.bean.ComBean;
public class ttySerialPortHelper {
private static final String TAG = "ttySerialPortHelper";
private static SerialHelper serialHelper;
private static SerialPortFinder serialPortFinder;
final String[] ports = serialPortFinder.getAllDevicesPath();
final String[] botes = new String[]{"0", "50", "75", "110", "134", "150", "200", "300", "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400", "57600", "115200", "230400", "460800", "500000", "576000", "921600", "1000000", "1152000", "1500000", "2000000", "2500000", "3000000", "3500000", "4000000", "CUSTOM"};
final String[] databits = new String[]{"8", "7", "6", "5"};
final String[] paritys = new String[]{"NONE", "ODD", "EVEN", "SPACE", "MARK"};
final String[] stopbits = new String[]{"1", "2"};
final String[] flowcons = new String[]{"NONE", "RTS/CTS", "XON/XOFF"};
public static void Open()
{
try {
serialHelper = new SerialHelper("dev/ttyHS0", 115200)//MK32
// serialHelper = new SerialHelper("/dev/ttyHS3", 115200) //UR7
{
@Override
protected void onDataReceived(ComBean comBean) {
byte[] receivedData=comBean.bRec;
EventBus.getDefault().post(new IVDataReceivedEvent.IVReceived(receivedData));
}
};
serialHelper.open();
}
catch (Exception exception)
{
Log.d(TAG,"Data Received");
}
}
private static int index =0;
public static void SendData(byte[] data) {
serialHelper.send( data); // 发送byte[]
}
//55 66 01 01 00 00 00 42 06 31 80
public static byte[] getAllChData_4Hz=new byte[]{0x55, 0x66,0x01,0x01,0x00,0x00,0x00,0x42,0x02,(byte)(0xB5&0xff),(byte)(0xC0&0xff)};
public static byte[] getAllChData_5Hz=new byte[]{0x55, 0x66,0x01,0x01,0x00,0x00,0x00,0x42,0x03,(byte)(0x94&0xff),(byte)(0xD0&0xff)};
public static byte[] getAllChData_10Hz=new byte[]{0x55, 0x66,0x01,0x01,0x00,0x00,0x00,0x42,0x04,(byte)(0x73&0xff),(byte)(0xA0&0xff)};
public static byte[] getAllChData_20Hz=new byte[]{0x55, 0x66,0x01,0x01,0x00,0x00,0x00,0x42,0x05,(byte)(0x52&0xff),(byte)(0xb0&0xff)};
public static byte[] getAllChData_50Hz=new byte[]{0x55, 0x66,0x01,0x01,0x00,0x00,0x00,0x42,0x06,(byte)(0x31&0xff),(byte)(0x80&0xff)};
public static byte[] stopgetAllChData=new byte[]{0x55, 0x66,0x01,0x01,0x00,0x00,0x00,0x42,0x00,(byte)(0xf7&0xff),(byte)(0xe0&0xff)};
public static void sendTxt(String sTxt)
{
serialHelper.sendTxt( sTxt); // 发送byte[]
}
//serialHelper.send(byte[] bOutArray); // 发送byte[]
//serialHelper.sendHex(String sHex); // 发送Hex
//serialHelper.sendTxt(String sTxt); // 发送ASCII
public static void onDestroy() {
serialHelper.close();
}
}

185
app/src/main/java/com/example/paint_rough_inone_appv1_0/viewmodels/DataExchangeService.java

@ -0,0 +1,185 @@
package com.example.paint_rough_inone_appv1_0.viewmodels;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.example.paint_rough_inone_appv1_0.IVDataReceivedEvent;
import com.example.paint_rough_inone_appv1_0.models.BspPV;
import com.example.paint_rough_inone_appv1_0.services.ModbusCRC;
import com.example.paint_rough_inone_appv1_0.services.USBSerialPortHelper;
import com.example.paint_rough_inone_appv1_0.services.ttySerialPortHelper;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.logging.Handler;
public class DataExchangeService extends Service {
//USB 串口服务
public USBSerialPortHelper serialPortHelper;
private static final String TAG = "UDPMyService";
// 服务中存储的数据
private static BspPV.PV_struct_define _toSendPV;
// 绑定服务通信接口
public class ServiceBinder extends Binder {
DataExchangeService getService() {
return DataExchangeService.this;
}
}
private final IBinder binder = new ServiceBinder();
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "服务被绑定");
return binder;
}
//首次启动时,会执行 onCreate() → onStartCommand();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "服务已启动");
//Intialize("192.168.18.30", 8006, 9006);
Intialize("192.168.144.98", 8006, 9006);
_toSendPV = BspPV.PV_struct_define.newBuilder()
.setWorkMode(0)
.build();
ttySerialPortHelper.Open();//启动串口
// 模拟后台任务
return START_STICKY;
}
//UDP Region
private static Thread receiveThread;
private static Thread sendThread;
private static boolean running = false;
private static boolean send_running = false;
private static DatagramSocket sendSocket;
private static DatagramSocket receiveSocket;
private static Handler handler;// = new Handler(Looper.getMainLooper());
private static String target_ip;
private static int target_port;
private static int listening_port;
public static void Intialize(String targetip, int targetPort, int listentingPort) {
try {
target_ip = targetip;
target_port = targetPort;
listening_port = listentingPort; //本地监听端口
sendSocket = new DatagramSocket(10000);// 创建发送套接字(绑定本地端口 10000)
//sendSocket.setBroadcast(true);
receiveSocket = new DatagramSocket(listening_port);// 创建接收套接字(绑定指定监听端口)
receiveSocket.setBroadcast(true);// 允许接收广播数据
running = true;
receiveThread = new Thread(() -> {
byte[] buffer = new byte[1024];// 数据缓冲区
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);//将数据打包成网络传输的数据包。
while (running) {
try {
receiveSocket.receive(packet);// 阻塞等待接收数据
byte[] receivedArray = new byte[packet.getLength()];// 提取有效数据(剔除缓冲区冗余部分)
System.arraycopy(packet.getData(), 0, receivedArray, 0, receivedArray.length);
// 通过 EventBus 发送事件,通知其他组件(如 Activity)
EventBus.getDefault().post(new IVDataReceivedEvent.IVReceived(receivedArray));
} catch (IOException e) {
if (running) {
}
}
}
});
receiveThread.start();
send_running=true;
sendThread= new Thread(() -> {
while (send_running) {
try {
Thread.sleep(200);
SendPV(_toSendPV);
} catch (Exception e) {
}
}
});
sendThread.start();
} catch (IOException e) {
// tvOutput.setText("Socket error: " + e.getMessage());
}
}
public static void SendRawData(byte[] buffer) {
new Thread(() ->
{
DatagramSocket socket = null;
try {
InetAddress address = InetAddress.getByName(target_ip);
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, target_port);
sendSocket.send(packet);
} catch (Exception e) {
}
}).start();
ttySerialPortHelper.SendData(buffer);
}
private static void SendPV(BspPV.PV_struct_define toSendPV) {
byte[] byteArray = toSendPV.toByteArray();
byte[] sendbyteArray = new byte[byteArray.length + 4];
byte[] sendbyteArray3 = new byte[byteArray.length + 6];
if (byteArray.length != 0) {
System.arraycopy(byteArray, 0, sendbyteArray, 4, byteArray.length);
}
sendbyteArray[0] = (byte) 0x55;
sendbyteArray[1] = (byte) 0x55;
sendbyteArray[2] = (byte) 0x01;
sendbyteArray[3] = (byte) 0x01;
byte[] byteArray2 = ModbusCRC.calculateCRC(sendbyteArray);
System.arraycopy(sendbyteArray, 0, sendbyteArray3, 0, sendbyteArray.length);
System.arraycopy(byteArray2, 0, sendbyteArray3, sendbyteArray3.length - 2, 2);
SendRawData(sendbyteArray3);
}
// 供Activity调用的方法
public BspPV.PV_struct_define getPVData() {
return _toSendPV;
}
public void setPVData(BspPV.PV_struct_define newPV) {
_toSendPV = newPV;
//SendPV(_toSendPV);
// Log.d(TAG, "服务数据已更新: ");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "服务已停止");
running = false;
send_running=false;
//receiveThread.destroy();
if (receiveSocket != null && !receiveSocket.isClosed()) {
receiveSocket.close();
}
if (sendSocket != null && !sendSocket.isClosed()) {
sendSocket.close();
}
}
}

11
app/src/main/java/com/example/paint_rough_inone_appv1_0/viewmodels/MainViewModel.java

@ -0,0 +1,11 @@
package com.example.paint_rough_inone_appv1_0.viewmodels;
import androidx.lifecycle.ViewModel;
public class MainViewModel extends ViewModel {
public MainViewModel() {
}
}

2
app/src/main/java/generate_java.bat

@ -0,0 +1,2 @@
protoc --java_out . *.proto
pause

BIN
app/src/main/java/protoc.exe

Binary file not shown.

25
app/src/main/res/drawable/background.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<!-- <solid android:color="@color/gainsboro" />-->
<solid android:color="#f2f3f4" />
<!-- 设置一个黑色边框 -->
<!-- <stroke-->
<!-- android:width="4px"-->
<!-- android:color="@color/deepskyblue" />-->
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

BIN
app/src/main/res/drawable/bgr.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

25
app/src/main/res/drawable/blue_rounded_rectangle.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<!-- <solid android:color="@color/white" />-->
<solid android:color="#d6eaf8" />
<!-- 设置一个黑色边框 -->
<!-- <stroke-->
<!-- android:width="4px"-->
<!-- android:color="@color/deepskyblue" />-->
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="12dp"
android:bottomRightRadius="12dp"
android:topLeftRadius="12dp"
android:topRightRadius="12dp" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

10
app/src/main/res/drawable/border.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 设置一个黑色边框 -->
<stroke android:width="4px" android:color="#ffffff"/>
<!-- 渐变 -->
<!-- 设置一下边距,让空间大一点 -->
</shape>

8
app/src/main/res/drawable/border_active.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#e6f7ff" />
<stroke
android:width="2dp"
android:color="#1890ff" />
<corners android:radius="8dp" />
</shape>

8
app/src/main/res/drawable/border_inactive.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f5f5f5" />
<stroke
android:width="1dp"
android:color="#d9d9d9" />
<corners android:radius="8dp" />
</shape>

24
app/src/main/res/drawable/borderblue.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置形状的填充颜色 -->
<solid android:color="#d6eaf8" />
<!-- 设置一个黑色边框 -->
<stroke
android:width="4px"
android:color="#d6eaf8" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="20px"
android:bottomRightRadius="20px"
android:topLeftRadius="20px"
android:topRightRadius="20px" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

24
app/src/main/res/drawable/borderbluegreen.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<solid android:color="#d6eaf8" />
<!-- 设置一个黑色边框 -->
<stroke
android:width="2px"
android:color="@color/blue_green" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="10px"
android:bottomRightRadius="10px"
android:topLeftRadius="10px"
android:topRightRadius="10px" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

31
app/src/main/res/drawable/borderlog.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<!-- <solid android:color="##deebf7" />-->
<solid android:color="@color/white" />
<!-- 设置一个黑色边框 -->
<stroke
android:width="4px"
android:color="@color/grey" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<!-- <corners-->
<!-- android:bottomLeftRadius="10px"-->
<!-- android:bottomRightRadius="10px"-->
<!-- android:topLeftRadius="10px"-->
<!-- android:topRightRadius="10px" />-->
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

24
app/src/main/res/drawable/borderorange.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<solid android:color="#f6ddcc" />
<!-- 设置一个黑色边框 -->
<stroke
android:width="2dp"
android:color="#ed7041" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="10px"
android:bottomRightRadius="10px"
android:topLeftRadius="10px"
android:topRightRadius="10px" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

24
app/src/main/res/drawable/borderwhite.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<!-- <solid android:color="#87CEEB" />-->
<!-- 设置一个黑色边框 -->
<stroke
android:width="2px"
android:color="#ffffff" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="10px"
android:bottomRightRadius="10px"
android:topLeftRadius="10px"
android:topRightRadius="10px" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

18
app/src/main/res/drawable/button_active.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<!-- 当视图被按下(用户点击并按住)时应用的样式 -->
<shape>
<solid android:color="@color/red" />
<!-- 填充颜色:深蓝色 -->
<corners android:radius="15dp" />
<!-- 圆角半径:4dp -->
</shape>
</item>
<item>
<shape>
<solid android:color="@color/black" />
<corners android:radius="0dp" />
</shape>
</item>
</selector>

11
app/src/main/res/drawable/button_inactive.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f5f5f5" />
<!-- 浅灰色填充 -->
<stroke
android:width="3dp"
android:color="#FBE5D6" />
<!-- 2dp 宽的红色实线边框 -->
<corners android:radius="10dp" />
</shape>

24
app/src/main/res/drawable/buttonborderwhite.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<solid android:color="#00ffffff" />
<!-- 设置一个黑色边框 -->
<stroke
android:width="16px"
android:color="#ffffff" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="10px"
android:bottomRightRadius="10px"
android:topLeftRadius="10px"
android:topRightRadius="10px" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

6
app/src/main/res/drawable/container_active.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#E8F0FE" />
<stroke android:width="2dp" android:color="#3B88FC" />
<corners android:radius="8dp" />
</shape>

6
app/src/main/res/drawable/container_inactive.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F5F5F5" />
<stroke android:width="1dp" android:color="#CCCCCC" />
<corners android:radius="8dp" />
</shape>

14
app/src/main/res/drawable/dash_line.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
<stroke
android:color="#ffffff"
android:dashWidth="10dp"
/>
<!--width:线条的高度
color:颜色
android:dashGap="8dp"
dashWidth:破折线的宽度
dashGap:破折线间空隙的宽度
如果这里设置了width,xml中android:layout_height的值必须比它大。不设置就默认为0
-->
</shape>

170
app/src/main/res/drawable/ic_launcher_background.xml

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

30
app/src/main/res/drawable/ic_launcher_foreground.xml

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

26
app/src/main/res/drawable/message_rounded_rectangle_red.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<!-- <solid android:color="#F44336" />-->
<solid android:color="#FF0000" />
<!-- 设置一个黑色边框 -->
<!-- <stroke-->
<!-- android:width="4px"-->
<!-- android:color="@color/" />-->
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

9
app/src/main/res/drawable/my_cursor.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!--自定义edittext的光标颜色和粗细-->
<shape xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="ExtraText">
android:shape="rectangle">
<size android:width="3dp" /> <!-- 调整此值控制光标粗细 -->
<solid android:color="@color/black" /> <!-- 光标颜色 -->
</shape>

25
app/src/main/res/drawable/orange_rounded_rectangle.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<!-- <solid android:color="@color/white" />-->
<solid android:color="#FBD6D6" />
<!-- 设置一个黑色边框 -->
<!-- <stroke-->
<!-- android:width="4px"-->
<!-- android:color="@color/deepskyblue" />-->
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="12dp"
android:bottomRightRadius="12dp"
android:topLeftRadius="12dp"
android:topRightRadius="12dp" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

15
app/src/main/res/drawable/radio_button_selected.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<!-- 设置一个黑色边框 -->
<stroke android:width="4px"
android:color="#d6eaf8"/>
<solid android:color="#d6eaf8" />
<corners android:radius="10dp" />
<!-- 渐变 -->
<!-- 设置一下边距,让空间大一点 -->
</shape>

8
app/src/main/res/drawable/radio_button_textcolor.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/grey"
android:state_checked="false" />
<item android:color="@color/blue_green"
android:state_checked="true" />
</selector>

8
app/src/main/res/drawable/radio_button_unselected.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充 -->
<solid android:color="#eaeded" />
<!-- 圆角 -->
<corners android:radius="10dp" />
</shape>

5
app/src/main/res/drawable/radiobutton_background.xml

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/radio_button_selected" />
<item android:state_checked="false" android:drawable="@drawable/radio_button_unselected" />
</selector>

28
app/src/main/res/drawable/rounded_edittext.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置Editext的形状-->
<!-- 设置透明背景色 -->
<!-- <solid android:color="#87CEEB" />-->
<!-- 设置一个自定义颜色边框 -->
<stroke
android:width="1px"
android:color="@color/trasnparent" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="10px"
android:bottomRightRadius="10px"
android:topLeftRadius="10px"
android:topRightRadius="10px" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

BIN
app/src/main/res/drawable/squrelogo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

24
app/src/main/res/drawable/submenu.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置透明背景色 -->
<solid android:color="@color/white" />
<!-- <solid android:color="#d6eaf8" />-->
<!-- 设置一个黑色边框 -->
<stroke
android:width="2px"
android:color="@color/deepskyblue" />
<!-- 设置四个圆角的半径 -->
<corners
android:bottomLeftRadius="2dp"
android:bottomRightRadius="2dp"
android:topLeftRadius="2dp"
android:topRightRadius="2dp" />
<!-- 设置一下边距,让空间大一点 -->
<!-- <padding-->
<!-- android:bottom="5dp"-->
<!-- android:left="5dp"-->
<!-- android:right="5dp"-->
<!-- android:top="5dp" />-->
</shape>

BIN
app/src/main/res/font/font_you_yuan.ttf

Binary file not shown.

78
app/src/main/res/layout/activity_main.xml

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<!--根布局 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/background"
>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_margin="10dp"
android:orientation="horizontal"
>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginTop="50dp"
android:layout_marginLeft="50dp"
android:layout_marginBottom="50dp"
android:background="@drawable/orange_rounded_rectangle"
android:orientation="horizontal">
<Button
android:id="@+id/btn_paint"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/trasnparent"
android:textStyle="bold"
android:gravity="center"
android:textColor="@color/red"
android:textSize="50sp"
android:text="喷漆"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_margin="50dp"
android:background="@drawable/blue_rounded_rectangle"
android:orientation="horizontal">
<Button
android:id="@+id/btn_rough"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/trasnparent"
android:textColor="@color/blue_green"
android:textStyle="bold"
android:textSize="50sp"
android:gravity="center"
android:text="拉毛"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>

549
app/src/main/res/layout/activity_paint.xml

@ -0,0 +1,549 @@
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".PaintActivity">
<!--根布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:orientation="vertical">
<!-- 顶部界面标题-->
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center"
android:text="喷漆界面"
android:textColor="@color/blue_green"
android:textSize="20sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!--左侧显示半框-->
<LinearLayout
android:id="@+id/messageRoundedPaint"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:orientation="vertical"
android:layout_weight="1"
android:background="@drawable/orange_rounded_rectangle"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/信号状态"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_signal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:layout_marginLeft="8dp"
android:text="当前速度"
android:textColor="@color/black"
android:textSize="14dp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_currentSpeedFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="m/min"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:layout_marginLeft="8dp"
android:text="@string/moveSpeed"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_speedFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="m/min"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:fontFamily="@font/font_you_yuan"
android:gravity="left|center"
android:text="@string/realAngle"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvAngleFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="°"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
</LinearLayout>
<!--右侧显示半框-->
<LinearLayout
android:id="@+id/rightSend"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:orientation="vertical"
android:layout_weight="2"
>
<!-- 第一行,1个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="7dp"
android:layout_weight="1">
<!-- 第一行,第1个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="@string/ManualMode"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/manualModeDisplay"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="无"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
<Button
android:id="@+id/setManualModeBtn_Paint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
</LinearLayout>
<!-- 第二行,1个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="7dp"
android:layout_weight="1">
<!-- 第一行,第2个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="换道\n距离"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<EditText
android:id="@+id/Maintv_LaneChangeDistanceTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/rounded_edittext"
android:imeOptions="actionDone"
android:hint="请输入0到250之间的数字"
android:inputType="number"
android:gravity="center"
android:text="1"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="cm"
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
<!-- 第三行,1个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="7dp"
android:layout_weight="1">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="竖直\n微调"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<!-- android:imeOptions="actionDone" 不会切换下一个文本输入 -->
<EditText
android:id="@+id/Maintv_VerticalAdjustTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/rounded_edittext"
android:imeOptions="actionDone"
android:hint="请输入-10到10之间的数字"
android:inputType="numberSigned|numberDecimal"
android:digits="-0123456789."
android:gravity="center"
android:text="1.0"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="°"
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
<!-- 第四行,1个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="7dp"
android:layout_weight="1">
<!-- 第一行,第2个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="参数\n预设"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/Maintv_ParameterCallTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="1"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/blue_green"
android:textSize="20dp" />
</LinearLayout>
<Button
android:id="@+id/setcallParametersBtn_Paint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
</LinearLayout>
<!-- 第五行,1个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:id="@+id/errorBackgroundPaint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="报错\n信息"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/mainViewErrMessageTxView_Paint"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="无"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<Button
android:id="@+id/mainViewErrMessageBtn_Paint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="0dp"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>

773
app/src/main/res/layout/activity_rough.xml

@ -0,0 +1,773 @@
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".RoughActivity">
<!--根布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:orientation="vertical">
<!-- 顶部界面标题-->
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center"
android:text="拉毛界面"
android:textSize="20sp"
android:textColor="@color/blue_green"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<!--左侧显示半框-->
<LinearLayout
android:id="@+id/messageRoundedRough"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:orientation="vertical"
android:layout_weight="1"
android:background="@drawable/orange_rounded_rectangle"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/信号状态"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_signal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:layout_marginLeft="8dp"
android:text="当前速度"
android:textColor="@color/black"
android:textSize="14dp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_currentSpeedFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="m/min"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:layout_marginLeft="8dp"
android:text="@string/moveSpeed"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_speedFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="m/min"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/realAngle"
android:layout_marginLeft="8dp"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tvAngleFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="°"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/realPress"
android:layout_marginLeft="8dp"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tvPressFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="xxx"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/leftCompensation"
android:textColor="@color/black"
android:textSize="15sp"
android:layout_marginLeft="8dp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_LCompensationFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="0.0"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="°"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginBottom="10dp"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/rightCompensation"
android:textColor="@color/black"
android:textSize="15sp"
android:layout_marginLeft="8dp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/tv_RCopmpensationFrom32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="0.0"
android:textColor="@color/navy_blue"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="°"
android:textColor="@color/dark_ink_blue"
android:textSize="10dp" />
</LinearLayout>
</LinearLayout>
<!--右侧显示半框-->
<LinearLayout
android:id="@+id/rightSend"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:orientation="vertical"
android:layout_weight="2"
>
<!-- 第一行,2个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_marginBottom="7dp"
android:layout_height="0dp"
android:layout_weight="1">
<!-- 第一行,第1个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginRight="7dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="@string/ManualMode"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/manualModeDisplay"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="无"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
<Button
android:id="@+id/setManualModeBtn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
<!-- 第一行,第2个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginRight="7dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="自动\n模式"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/autoModeDisplay"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="未启用"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="30dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/blue_green"
android:textSize="20dp" />
</LinearLayout>
<Button
android:id="@+id/setAutoModeBtn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
</LinearLayout>
<!-- 第二行,2个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="7dp"
android:layout_weight="1">
<!-- 第2行,第1个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginRight="7dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="换道\n距离"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<EditText
android:id="@+id/Maintv_LaneChangeDistanceTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/rounded_edittext"
android:imeOptions="actionDone"
android:hint="请输入0到250之间的数字"
android:inputType="number"
android:gravity="center"
android:text="1"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="cm"
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
</FrameLayout>
<!-- 第2行,第2个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginRight="7dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="压力\n设定"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<EditText
android:id="@+id/Maintv_PressTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/rounded_edittext"
android:imeOptions="actionDone"
android:hint="请输入-3000到3000之间的数字"
android:inputType="number"
android:gravity="center"
android:text="100"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="N"
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
<!-- 第五行,2个帧布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="7dp"
android:layout_weight="1">
<!-- 第5行,第1个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginRight="7dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="竖直\n微调"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<!-- android:imeOptions="actionDone" 不会切换下一个文本输入 -->
<EditText
android:id="@+id/Maintv_VerticalAdjustTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/rounded_edittext"
android:imeOptions="actionDone"
android:hint="请输入-10到10之间的数字"
android:inputType="numberSigned|numberDecimal"
android:digits="-0123456789."
android:gravity="center"
android:text="1.0"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="°"
android:textColor="@color/blue_green"
android:textSize="15dp" />
</LinearLayout>
</FrameLayout>
<!-- 第一行,第2个帧布局-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginRight="7dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="参数\n预设"
android:textColor="@color/dark_ink_blue"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/Maintv_ParameterCallTo32"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="1"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textColor="@color/blue_green"
android:textSize="20dp" />
</LinearLayout>
<Button
android:id="@+id/setcallParametersBtn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/blue_rounded_rectangle">
>
<LinearLayout
android:id="@+id/errorBackgroundRough"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:gravity="left|center"
android:text="报错\n信息"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold"
android:fontFamily="@font/font_you_yuan" />
<TextView
android:id="@+id/mainViewErrMessageTxViewRough"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="center"
android:text="无"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="35dp"
android:layout_height="match_parent"
android:gravity="center"
android:text=""
android:textSize="10dp" />
</LinearLayout>
<Button
android:id="@+id/mainViewErrMessageBtn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="0dp"
android:background="@color/trasnparent"
android:textAlignment="center" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>

31
app/src/main/res/layout/log_item_paint.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="450dp"
android:layout_height="350dp"
android:layout_gravity="center"
android:background="@drawable/submenu"
android:orientation="vertical">
<com.example.paint_rough_inone_appv1_0.models.ScrollBottomScrollView
android:id="@+id/popUpErrorLogScrollview_Paint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:background="@drawable/borderlog">
<TextView
android:id="@+id/popUpErrorLogTextView_Paint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:scrollbars="vertical"
android:scrollbarStyle="insideInset"
android:textSize="12sp"
android:textColor="@color/midnightblue" />
</com.example.paint_rough_inone_appv1_0.models.ScrollBottomScrollView>
</LinearLayout>

31
app/src/main/res/layout/log_item_rough.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="450dp"
android:layout_height="350dp"
android:layout_gravity="center"
android:background="@drawable/submenu"
android:orientation="vertical">
<com.example.paint_rough_inone_appv1_0.models.ScrollBottomScrollView
android:id="@+id/popUpErrorLogScrollview_Rough"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:background="@drawable/borderlog">
<TextView
android:id="@+id/popUpErrorLogTextView_Rough"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:scrollbars="vertical"
android:scrollbarStyle="insideInset"
android:textSize="12sp"
android:textColor="@color/midnightblue" />
</com.example.paint_rough_inone_appv1_0.models.ScrollBottomScrollView>
</LinearLayout>

145
app/src/main/res/layout/paint_manualmodepopup.xml

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="500dp"
android:layout_height="360dp"
android:layout_gravity="center"
android:background="@color/white"
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="25dp"
android:letterSpacing="0.5"
android:text="作业模式"
android:textColor="@color/dark_ink_blue"
android:textSize="40sp"
android:textStyle="bold">
</TextView>
<!--第一行 模式选择-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/manualModeSelectorGroup_Paint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/rb_one_paint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:button="@null"
android:layout_marginRight="15dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:textStyle="bold"
android:checked="true"
android:padding="10dp"
android:textSize="40sp"
android:text="无" />
<RadioButton
android:id="@+id/rb_two_paint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:button="@null"
android:layout_marginRight="15dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="40sp"
android:text="竖直\n向左" />
<RadioButton
android:id="@+id/rb_three_paint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:button="@null"
android:layout_marginRight="10dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="40sp"
android:text="竖直\n向右" />
>
</RadioGroup>
</LinearLayout>
<!--第二行 确认取消-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:gravity="center"
android:background="@drawable/borderbluegreen">
<Button
android:id="@+id/manualModeApply_Paint"
android:layout_width="200dp"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/trasnparent"
android:text="确定"
android:textColor="@color/blue_green"
android:textSize="20sp"
android:textStyle="bold">
</Button>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:background="@drawable/borderorange">
<Button
android:id="@+id/manualModeCancel_Paint"
android:layout_width="200dp"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:text="取消"
android:textColor="#ed7041"
android:textSize="20sp"
android:textStyle="bold">
</Button>
</LinearLayout>
</LinearLayout>
</LinearLayout>

207
app/src/main/res/layout/parameters_call_paint.xml

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="500dp"
android:layout_height="360dp"
android:layout_gravity="center"
android:background="@color/white"
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="40dp"
android:letterSpacing="0.5"
android:text="参数预设"
android:textColor="@color/dark_ink_blue"
android:textSize="40sp"
android:textStyle="bold">
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:layout_marginTop="0dp"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/parameters_call_group_paint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraOnePaint"
android:button="@null"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:checked="true"
android:padding="10dp"
android:textSize="30sp"
android:text="1" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraTwoPaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="2" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraThreePaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="3" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraFourPaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="4" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraFivePaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="5" />
</RadioGroup>
</LinearLayout>
<!--四个按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="70dp"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<RadioButton
android:id="@+id/parametersSavebtnPaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@drawable/radiobutton_background"
android:text="保存"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
<RadioButton
android:id="@+id/parametersClearBtnPaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@drawable/radiobutton_background"
android:text="清除"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
<RadioButton
android:id="@+id/parametersApplyPaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@drawable/radiobutton_background"
android:text="使用"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
<RadioButton
android:id="@+id/parametersExitPaint"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/radiobutton_background"
android:text="退出"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
</RadioGroup>
</LinearLayout>
</LinearLayout>

207
app/src/main/res/layout/parameters_call_rough.xml

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="500dp"
android:layout_height="360dp"
android:layout_gravity="center"
android:background="@color/white"
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="40dp"
android:letterSpacing="0.5"
android:text="参数预设"
android:textColor="@color/dark_ink_blue"
android:textSize="40sp"
android:textStyle="bold">
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:layout_marginTop="0dp"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/parameters_call_group_rough"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraOneRough"
android:button="@null"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:checked="true"
android:padding="10dp"
android:textSize="30sp"
android:text="1" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraTwoRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="2" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraThreeRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="3" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraFourRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="4" />
<com.example.paint_rough_inone_appv1_0.services.ToggleRadioButton
android:id="@+id/rb_paraFiveRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="30sp"
android:text="5" />
</RadioGroup>
</LinearLayout>
<!--四个按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="70dp"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>
<RadioButton
android:id="@+id/parametersSavebtnRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@drawable/radiobutton_background"
android:padding="4dp"
android:text="保存"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
<RadioButton
android:id="@+id/parametersClearBtnRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:layout_marginLeft="10dp"
android:padding="4dp"
android:text="清除"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
<RadioButton
android:id="@+id/parametersApplyRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:layout_marginLeft="10dp"
android:padding="4dp"
android:text="使用"
android:gravity="center"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
<RadioButton
android:id="@+id/parametersExitRough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="@drawable/radiobutton_background"
android:text="退出"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:padding="4dp"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="20sp"
android:button="@null"
android:textStyle="bold">
</RadioButton>
</RadioGroup>
</LinearLayout>
</LinearLayout>

210
app/src/main/res/layout/rough_automodepopup.xml

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="500dp"
android:layout_height="360dp"
android:layout_gravity="center"
android:background="@color/white"
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:letterSpacing="0.5"
android:text="自动模式"
android:textColor="@color/dark_ink_blue"
android:textSize="35sp"
android:textStyle="bold">
</TextView>
<!--第一行 水平 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="20dp"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/autoModeSelectorGroup_Rough"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/rb_autoHorizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/radiobutton_background"
android:button="@null"
android:gravity="center"
android:text="水平"
android:checked="true"
android:textColor="@drawable/radio_button_textcolor"
android:textSize="40sp"
android:textStyle="bold" />
</RadioGroup>
</LinearLayout>
<!--第二行 长度宽度-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="20dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/borderblue"
android:layout_marginRight="20dp"
>
<TextView
android:layout_width="80dp"
android:layout_height="match_parent"
android:text="横向\n距离"
android:gravity="left|center"
android:layout_gravity="center"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/black"
/>
<EditText
android:id="@+id/HorizontalDistance_input"
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="@null"
android:gravity="right|center"
android:inputType="numberDecimal"
android:text="50"
android:textColor="@color/blue_green"
android:textSize="40sp"
android:textStyle="bold">
</EditText>
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="m"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/borderblue"
>
<TextView
android:layout_width="80dp"
android:layout_height="match_parent"
android:text="纵向\n距离"
android:gravity="left|center"
android:layout_gravity="center"
android:textSize="20sp"
android:textStyle="bold"
android:clickable="true"
android:textColor="@color/black"
/>
<EditText
android:id="@+id/VerticalDistance_input"
android:inputType="numberDecimal"
android:background="@null"
android:layout_width="100dp"
android:textColor="@color/blue_green"
android:gravity="right|center"
android:layout_height="match_parent"
android:text="50"
android:textStyle="bold"
android:textSize="40sp">
</EditText>
<TextView
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="m"
android:textColor="@color/blue_green"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<!--第三行 确定取消-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:gravity="center"
android:background="@drawable/borderbluegreen">
<Button
android:id="@+id/autoModeApply_Rough"
android:layout_width="200dp"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/trasnparent"
android:text="确定"
android:textColor="@color/blue_green"
android:textSize="20sp"
android:textStyle="bold">
</Button>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:background="@drawable/borderorange">
<Button
android:id="@+id/autoModeCancel_Rough"
android:layout_width="200dp"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:text="取消"
android:textColor="#ed7041"
android:textSize="20sp"
android:textStyle="bold">
</Button>
</LinearLayout>
</LinearLayout>
</LinearLayout>

159
app/src/main/res/layout/rough_manualmodepopup.xml

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="500dp"
android:layout_height="360dp"
android:layout_gravity="center"
android:background="@color/white"
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="25dp"
android:letterSpacing="0.5"
android:text="作业模式"
android:textColor="@color/dark_ink_blue"
android:textSize="40sp"
android:textStyle="bold">
</TextView>
<!--第一行 模式选择-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/manualModeSelectorGroup_Rough"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/rb_one_rough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:button="@null"
android:layout_marginRight="15dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:textStyle="bold"
android:checked="true"
android:padding="10dp"
android:textSize="40sp"
android:text="无" />
<RadioButton
android:id="@+id/rb_two_rough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:button="@null"
android:layout_marginRight="15dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="40sp"
android:text="水平" />
<RadioButton
android:id="@+id/rb_three_rough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:button="@null"
android:layout_marginRight="15dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="40sp"
android:text="竖直\n向左" />
<RadioButton
android:id="@+id/rb_four_rough"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:button="@null"
android:layout_marginRight="10dp"
android:background="@drawable/radiobutton_background"
android:textColor="@drawable/radio_button_textcolor"
android:gravity="center"
android:textStyle="bold"
android:padding="10dp"
android:textSize="40sp"
android:text="竖直\n向右" />
>
</RadioGroup>
</LinearLayout>
<!--第二行 确认取消-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:gravity="center"
android:background="@drawable/borderbluegreen">
<Button
android:id="@+id/manualModeApply_Rough"
android:layout_width="200dp"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/trasnparent"
android:text="确定"
android:textColor="@color/blue_green"
android:textSize="20sp"
android:textStyle="bold">
</Button>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:background="@drawable/borderorange">
<Button
android:id="@+id/manualModeCancel_Rough"
android:layout_width="200dp"
android:layout_height="match_parent"
android:background="@color/trasnparent"
android:text="取消"
android:textColor="#ed7041"
android:textSize="20sp"
android:textStyle="bold">
</Button>
</LinearLayout>
</LinearLayout>
</LinearLayout>

6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save