Browse Source

项目初始化

master
pry 4 months ago
parent
commit
165bbbd106
56 changed files with 2727 additions and 0 deletions
  1. +1
    -0
      app/.gitignore
  2. +125
    -0
      app/build.gradle
  3. +21
    -0
      app/proguard-rules.pro
  4. +26
    -0
      app/src/androidTest/java/com/jdzh/jdzhandroid/ExampleInstrumentedTest.java
  5. +39
    -0
      app/src/main/AndroidManifest.xml
  6. +60
    -0
      app/src/main/java/com/jdzh/jdzhandroid/ActionNotify/NotifyEvent.java
  7. +39
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/ExceptionServer.java
  8. +15
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IExceptionHandling.java
  9. +8
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IModbusMaster.java
  10. +19
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IRead.java
  11. +5
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IReadCallBack.java
  12. +19
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IWrite.java
  13. +7
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IWriteCallBack.java
  14. +43
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/ModbusBasis.java
  15. +626
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/ModbusHelper.java
  16. +81
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/ByteLib.java
  17. +51
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/ByteTransDataFormat.java
  18. +107
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/Convert.java
  19. +263
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/DataConvertLib.java
  20. +14
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/DataType.java
  21. +27
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/FloatLib.java
  22. +47
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/IntLib.java
  23. +34
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/NotifyPropVar.java
  24. +47
    -0
      app/src/main/java/com/jdzh/jdzhandroid/DataUtil/ShortLib.java
  25. +8
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Enum/DataFormat.java
  26. +5
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Interface/IRun.java
  27. +7
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Interface/IRunT.java
  28. +5
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Interface/IRunT2.java
  29. +7
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Log/IMessageLogNotify.java
  30. +58
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Log/MessageLog.java
  31. +25
    -0
      app/src/main/java/com/jdzh/jdzhandroid/MainActivity.java
  32. +39
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Result/IResult.java
  33. +78
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Result/OperateResult.java
  34. +89
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Result/OperateResultT.java
  35. +38
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Result/ResultCode.java
  36. +5
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Task/ITask.java
  37. +7
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Task/ITaskComplete.java
  38. +25
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Task/Task.java
  39. +82
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Task/TaskManager.java
  40. +8
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Task/TaskModel.java
  41. +41
    -0
      app/src/main/java/com/jdzh/jdzhandroid/Trig/RTrig.java
  42. +19
    -0
      app/src/main/res/layout/activity_main.xml
  43. +3
    -0
      app/src/main/res/values-night/themes.xml
  44. +5
    -0
      app/src/main/res/values/colors.xml
  45. +3
    -0
      app/src/main/res/values/strings.xml
  46. +3
    -0
      app/src/main/res/values/themes.xml
  47. +13
    -0
      app/src/main/res/xml/backup_rules.xml
  48. +19
    -0
      app/src/main/res/xml/data_extraction_rules.xml
  49. +61
    -0
      build.gradle
  50. +23
    -0
      gradle.properties
  51. +24
    -0
      gradle/libs.versions.toml
  52. BIN
     
  53. +6
    -0
      gradle/wrapper/gradle-wrapper.properties
  54. +185
    -0
      gradlew
  55. +89
    -0
      gradlew.bat
  56. +23
    -0
      settings.gradle

+ 1
- 0
app/.gitignore View File

@@ -0,0 +1 @@
/build

+ 125
- 0
app/build.gradle View File

@@ -0,0 +1,125 @@
//plugins {
// alias(libs.plugins.androidApplication)
//}

import java.text.DateFormat
import java.text.SimpleDateFormat

apply plugin: 'com.android.application'
def releaseTime() {
DateFormat df = new SimpleDateFormat("yyyyMMddHHmm")
return df.format(Calendar.getInstance(Locale.CHINA).getTime())
}

android {
namespace 'com.jdzh.jdzhandroid'
compileSdk 34
buildToolsVersion "33.0.0"
defaultConfig {
applicationId "com.jdzh.jdzhandroid"//设置applicationId(这里很重要,两个相同applicationId的apk不同同时安装在同一台Android手机中)
minSdk 23
targetSdk 34
versionCode 1
versionName "1.0"
manifestPlaceholders = [UMENG_CHANNEL_VALUE : "default"]
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

debug {
resValue("string", "PORT_NUMBER", "8081")
resValue("bool","superAdminTest","true")
}
}

lintOptions {
abortOnError false
checkReleaseBuilds false
}

compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

sourceSets {
main {
res.srcDirs = [
'src/main/res/layout/dialog',
'src/main/res/layout/datatab',
'src/main/res/layout/item',
'src/main/res/layout/new',
'src/main/res/layout',
'src/main/res'
]
assets {
srcDirs 'src\\main\\assets'
}

}
}
buildFeatures {
viewBinding = true
}
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "jdzh-master-v${defaultConfig.versionCode}-${releaseTime()}"+"-unsigned-${variant.name}.apk"
}
}

}

dependencies {

implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
implementation libs.play.services.vision.common
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core

//http服务器组件
implementation 'org.nanohttpd:nanohttpd:2.3.1'

//Modbus
implementation 'com.github.licheedev:Modbus4Android:2.0.2'

//Modbus server
implementation 'com.github.hwx95:ModbusTCP:v1.1'

//s7通讯库
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6'
implementation 'com.github.xingshuangs:iot-communication:1.5.0'

//日志工具 可定位代码行数
// api 'com.apkfuns.logutils:library:1.7.5'
implementation 'com.apkfuns.logutils:library:1.7.5'

//事件总线库
api 'org.greenrobot:eventbus:3.1.1'

//图片加载库
api 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'

//json操作库
implementation 'com.google.code.gson:gson:2.8.0'

// RecyclerAdapter框架
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.46'

// SmartShow Toast框架,解决不同机型弹出方式缺陷问题
implementation 'com.github.the-pig-of-jungle.smart-show:toast:2.6.7'

// litePal 数据库操作框架
implementation 'org.litepal.android:java:3.0.0'
}

+ 21
- 0
app/proguard-rules.pro View File

@@ -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

+ 26
- 0
app/src/androidTest/java/com/jdzh/jdzhandroid/ExampleInstrumentedTest.java View File

@@ -0,0 +1,26 @@
package com.jdzh.jdzhandroid;

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.jdzh.jdzhandroid", appContext.getPackageName());
}
}

+ 39
- 0
app/src/main/AndroidManifest.xml View File

@@ -0,0 +1,39 @@
<?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-permission android:name="android.permission.INTERNET" /> <!-- 网络连接 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 获取网络连接状态 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 写存储的权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 读存储的权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <!-- 0未知来源的应用权限,更新App -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" /> <!-- DownloadManager -->
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 录音权限 -->
<uses-permission android:name="android.permission.RECORD_VIDEO" /> <!-- 录像权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

+ 60
- 0
app/src/main/java/com/jdzh/jdzhandroid/ActionNotify/NotifyEvent.java View File

@@ -0,0 +1,60 @@
package com.jdzh.jdzhandroid.ActionNotify;

import com.jdzh.jdzhandroid.Interface.IRun;
import com.jdzh.jdzhandroid.Interface.IRunT;
import com.jdzh.jdzhandroid.Result.OperateResult;

import java.util.concurrent.ConcurrentHashMap;

public class NotifyEvent {
private static volatile NotifyEvent _instance;
public synchronized static NotifyEvent get(){
if(_instance == null)_instance = new NotifyEvent();
return _instance;
}
private NotifyEvent(){}
private ConcurrentHashMap<String, Object> _runMap = new ConcurrentHashMap<String, Object>();

public void Register(String name, IRun run){
_runMap.put(name,run);
}

public <T> void Register(String name, IRunT<T> run){
_runMap.put(name,run);
}

public OperateResult Send(String name){
try{
if(_runMap.containsKey(name)&&_runMap.get(name)!=null){
if(_runMap.get(name) instanceof IRun){
((IRun)_runMap.get(name)).Run();
return OperateResult.CreateSuccess();
}else{
return OperateResult.CreateFailed("注册类型和发送消息类型不匹配");
}
}else{
return OperateResult.CreateFailed(name+"消息未注册");
}
}catch(Exception e){
return OperateResult.CreateFailed(e);
}
}

public <T> OperateResult Send(String name, T value){
try{
if(_runMap.containsKey(name)&&_runMap.get(name)!=null){
if(_runMap.get(name) instanceof IRunT){
((IRunT)_runMap.get(name)).Run(value);
return OperateResult.CreateSuccess();
}else{
return OperateResult.CreateFailed("注册类型和发送消息类型不匹配");
}
}else{
return OperateResult.CreateFailed(name+"消息未注册");
}
}catch(Exception e){
return OperateResult.CreateFailed(e);
}
}

}

+ 39
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/ExceptionServer.java View File

@@ -0,0 +1,39 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

import com.jdzh.jdzhandroid.DataUtil.DataConvertLib;
import com.jdzh.jdzhandroid.Log.MessageLog;
import com.licheedev.modbus4android.ModbusRespException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;

import java.util.concurrent.ExecutionException;

public class ExceptionServer {
public ExceptionServer(String Address, int length,IExceptionHandling excpet)
{
try {
int add = DataConvertLib.GetAddress(Address);
if (add < 0) {
MessageLog.ShowError("地址解析失败=" + Address);
return;
}
if (excpet!=null) excpet.onSuccess(add);
} catch (InterruptedException e) {
MessageLog.ShowError("InterruptedException,Address=" + Address + ",length=" + length + ",msg:" + e.getMessage());
if (excpet!=null) excpet.onFailure(e.getMessage());
} catch (ExecutionException e) {
MessageLog.ShowError("ExecutionException,Address=" + Address + ",length=" + length + ",msg:" + e.getMessage());
if (excpet!=null) excpet.onFailure(e.getMessage());
} catch (ModbusTransportException e) {
MessageLog.ShowError("ModbusTransportException,Address=" + Address + ",length=" + length + ",msg:" + e.getMessage());
if (excpet!=null) excpet.onFailure(e.getMessage());
} catch (ModbusInitException e) {
MessageLog.ShowError("ModbusInitException,Address=" + Address + ",length=" + length + ",msg:" + e.getMessage());
if (excpet!=null) excpet.onFailure(e.getMessage());
} catch (ModbusRespException e) {
MessageLog.ShowError("ModbusRespException,Address=" + Address + ",length=" + length + ",msg:" + e.getMessage());
if (excpet!=null) excpet.onFailure(e.getMessage());
}

}
}

+ 15
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IExceptionHandling.java View File

@@ -0,0 +1,15 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

import com.licheedev.modbus4android.ModbusRespException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;

import java.util.concurrent.ExecutionException;

public interface IExceptionHandling {
void onSuccess(int add)throws InterruptedException, ExecutionException, ModbusTransportException,
ModbusInitException, ModbusRespException;


void onFailure(String error);
}

+ 8
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IModbusMaster.java View File

@@ -0,0 +1,8 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

import com.jdzh.jdzhandroid.Result.OperateResult;

public interface IModbusMaster {
OperateResult TcpConnect(String ip, int port)throws InterruptedException;
OperateResult RtuConnect(String com, int baudRate)throws InterruptedException;
}

+ 19
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IRead.java View File

@@ -0,0 +1,19 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

import com.jdzh.jdzhandroid.Enum.DataFormat;

public interface IRead {
void ReadBool(String address, int length, int slaveId, IReadCallBack<boolean[]> callback);

void ReadShort(String address, int length,int slaveId, IReadCallBack<short[]> callback);

void ReadInt(String address, int length, int slaveId, DataFormat df, IReadCallBack<int[]> callback);
void ReadInt(String address, int length, int slaveId, IReadCallBack<int[]> callback);

void ReadByte(String address, int length, int slaveId, IReadCallBack<byte[]> callback);

void ReadString(String address, int length, int slaveId, IReadCallBack<String> callback);

void ReadFloat(String address, int length, int slaveId,DataFormat df, IReadCallBack<float[]> callback);
void ReadFloat(String address, int length, int slaveId, IReadCallBack<float[]> callback);
}

+ 5
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IReadCallBack.java View File

@@ -0,0 +1,5 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

public interface IReadCallBack<T> {
void onSuccess(T t);
}

+ 19
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IWrite.java View File

@@ -0,0 +1,19 @@
package com.jdzh.jdzhandroid.Communication.Modbus;


public interface IWrite {
void WriteBool(String address, boolean value, int slaveId, IWriteCallBack callback);
void WriteBool(String address, boolean[] value, int slaveId, IWriteCallBack callback);

void WriteShort(String address, short value, int slaveId, IWriteCallBack callback);
void WriteShort(String address, short[] value, int slaveId, IWriteCallBack callback);

void WriteInt(String address, int value, int slaveId, IWriteCallBack callback);
void WriteInt(String address, int[] value, int slaveId, IWriteCallBack callback);

void WriteString(String address, String value, int slaveId, IWriteCallBack callback);

void WriteFloat(String address, float value, int slaveId, IWriteCallBack callback);
void WriteFloat(String address, float[] value, int slaveId, IWriteCallBack callback);

}

+ 7
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/IWriteCallBack.java View File

@@ -0,0 +1,7 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

public interface IWriteCallBack {
void onSuccess();

void onFailure(String ErrorMsg);
}

+ 43
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/ModbusBasis.java View File

@@ -0,0 +1,43 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

import com.licheedev.modbus4android.ModbusWorker;
import com.serotonin.modbus4j.ModbusMaster;

public class ModbusBasis extends ModbusWorker {
private static volatile ModbusBasis instance = null;

public static ModbusBasis get() {
ModbusBasis manager = instance;
if (manager == null) {
synchronized (ModbusBasis.class) {
manager = instance;
if (manager == null) {
manager = new ModbusBasis();
instance = manager;
}
}
}
return manager;
}

private ModbusBasis() {
}

/**
* 释放整个ModbusManager,单例会被置null
*/
public synchronized void release() {
super.release();
instance = null;
}

/**
* 获取
* @return
*/
public synchronized ModbusMaster getModbusMaster()
{
return super.getModbusMaster();
}

}

+ 626
- 0
app/src/main/java/com/jdzh/jdzhandroid/Communication/Modbus/ModbusHelper.java View File

@@ -0,0 +1,626 @@
package com.jdzh.jdzhandroid.Communication.Modbus;

import com.jdzh.jdzhandroid.DataUtil.DataConvertLib;
import com.jdzh.jdzhandroid.DataUtil.NotifyPropVar;
import com.jdzh.jdzhandroid.Enum.DataFormat;
import com.jdzh.jdzhandroid.Log.MessageLog;
import com.jdzh.jdzhandroid.Result.OperateResult;
import com.licheedev.modbus4android.ModbusCallback;
import com.licheedev.modbus4android.ModbusParam;
import com.licheedev.modbus4android.ModbusRespException;
import com.licheedev.modbus4android.ModbusWorker;
import com.licheedev.modbus4android.param.SerialParam;
import com.licheedev.modbus4android.param.TcpParam;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.ReadCoilsResponse;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;

public class ModbusHelper implements IRead,IWrite,IModbusMaster {
//https://blog.csdn.net/zgkxzx/article/details/71630301
// ModbusFactory factory = new ModbusFactory();//使用该方法可以创建不同类型的modbus通讯

private ModbusWorker mw = new ModbusWorker();

public void release(){
try{
mw.release();
}catch (Exception e){}
}

/**
* Ping PLC地址是否通畅
* @param address
* @param pingTimes ping的次数
* @param timeOut 超时时间 10
* @return
*/
private boolean ping2(String address, int pingTimes, int timeOut) {
Process process = null;
try {
process = Runtime.getRuntime().exec( "ping " + "-c " + pingTimes + " -w " + timeOut+ " "+address);
InputStreamReader r = new InputStreamReader(process.getInputStream());
LineNumberReader returnData = new LineNumberReader(r);
String returnMsg="";
String line = "";
while ((line = returnData.readLine()) != null) {
System.out.println(line);
returnMsg += line;
}

if(returnMsg.indexOf("100% packet loss")!=-1){
System.out.println("与 " +address +" 连接不畅通.");
return false;
} else{
System.out.println("与 " +address +" 连接畅通.");
return true;
}
} catch (IOException e) {
}
return false;

}
public boolean IsConnected=false;
public String TempIp;
private int TempPort;
private String TempCom;
private int TempBaudRate;

/**
* 连接类型,1=TCP,2=RUT
*/
private int ConnectionType;

private void ReConnect(String error){
if(ConnectionType==1){
if(error.contains("Connection refused")||error.contains("SocketException")||error.contains("SocketTimeoutException")){
IsConnected=false;
ConnectStatus.setValue(false);
TcpConnect(TempIp,TempPort);
}else{
MessageLog.ShowError("Tcp 重连失败:"+error);
}
}
else if (ConnectionType==2){
if(error.contains("Connection refused")){
IsConnected=false;
ConnectStatus.setValue(false);
RtuConnect(TempCom,TempBaudRate);
}else{
MessageLog.ShowError("Rtu 重连失败:"+error);
}
}

}

boolean IsOutErrorLog=false;

/**
* 连接状态通知
*/
public NotifyPropVar<Boolean> ConnectStatus=new NotifyPropVar<>(false);

/**
* TCP 连接,连接时请用多线程的方式,否者有可能无法连接
* @param ip
* @param port
* @throws InterruptedException
*/
@Override
public OperateResult TcpConnect(String ip, int port){
OperateResult result=new OperateResult();
TempIp=ip;
TempPort=port;
ConnectionType=1;
MessageLog.ShowInfo("开始验证网络:"+ip );
boolean status = false;
while (!status) {
try {
//status为0则代表通,为1则代表不通。
status =ping2(ip,1,1);
Thread.sleep(1000);
} catch (InterruptedException e) {
MessageLog.ShowInfo("设备 " + ip + " 网络验证失败");
} catch (Exception e) {
MessageLog.ShowInfo("设备 " + ip + " 网络验证失败");
}
}
MessageLog.ShowInfo("设备 " + ip + " 网络验证成功");
ModbusParam param= TcpParam.create(ip, port)
.setTimeout(1000)
.setRetries(0)
.setEncapsulated(false)
.setKeepAlive(true);
IsOutErrorLog=false;
while (IsConnected==false)
{
mw.init(param, new ModbusCallback<com.serotonin.modbus4j.ModbusMaster>() {
@Override
public void onSuccess(com.serotonin.modbus4j.ModbusMaster modbusMaster) {
IsConnected=true;
result.isSuccess=true;
ConnectStatus.setValue(true);
MessageLog.ShowInfo("Modbus TCP 连接成功" );
}
@Override
public void onFailure(Throwable tr) {
IsConnected = false;
ConnectStatus.setValue(false);
result.isSuccess=false;
result.message=tr.getMessage();
if(!IsOutErrorLog) {
MessageLog.ShowInfo("Modbus TCP 连接失败" );
IsOutErrorLog=true;
}
}
@Override
public void onFinally() {

}
});
try
{
if(IsConnected==false) Thread.sleep(5000);
}catch(InterruptedException ex){

}
}
return result.isSuccess?OperateResult.CreateSuccess():OperateResult.CreateFailed(result.message);
}

/**
* RTU 串口连接,建议连接时用多线程的方式,否者有可能无法连接
* @param com
* @param baudRate
* @throws InterruptedException
*/
@Override
public OperateResult RtuConnect(String com, int baudRate){
OperateResult result=new OperateResult();
MessageLog.ShowInfo("开始连接Modbus RTU" );
TempCom=com;
TempBaudRate=baudRate;
ConnectionType=2;
ModbusParam param= SerialParam.create(com, baudRate) // 串口地址和波特率
.setDataBits(8) // 数据位
.setParity(0) // 校验位
.setStopBits(1) // 停止位
.setTimeout(500).setRetries(0); // 不重试
while (IsConnected==false)
{
mw.init(param, new ModbusCallback<com.serotonin.modbus4j.ModbusMaster>() {
@Override
public void onSuccess(com.serotonin.modbus4j.ModbusMaster modbusMaster) {
IsConnected=true;
ConnectStatus.setValue(true);
result.isSuccess=true;
MessageLog.ShowInfo("Modbus RTU 连接成功" );
}
@Override
public void onFailure(Throwable tr) {
IsConnected = false;
ConnectStatus.setValue(false);
result.isSuccess=false;
result.message=tr.getMessage();
MessageLog.ShowInfo("Modbus RTU 连接失败" );
}
@Override
public void onFinally() {
}
});
try{
if(IsConnected==false) Thread.sleep(5000);
}catch (InterruptedException ex){

}
}
return result.isSuccess?OperateResult.CreateSuccess():OperateResult.CreateFailed(result.message);
}

@Override
public void ReadBool(String address, int length, int slaveId, IReadCallBack<boolean[]> callback) {
if (!IsConnected) {
return;
}
new ExceptionServer(address, length, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
ReadCoilsResponse res = mw.syncReadCoil(slaveId, add, length);
boolean[] data = res.getBooleanData();
boolean[] result = Arrays.copyOfRange(data, 0, length);
if (callback != null) callback.onSuccess(result);
}

@Override
public void onFailure(String error) {
ReConnect(error);
}
});
}

@Override
public void ReadShort(String address, int length,int slaveId, IReadCallBack<short[]> callback) {
if (!IsConnected) {
return;
}
new ExceptionServer(address, length, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
ReadHoldingRegistersResponse res = mw.syncReadHoldingRegisters(slaveId, add, length);
short[] data = res.getShortData();
if (data.length == length) {
if (callback != null) callback.onSuccess(data);
}
}

@Override
public void onFailure(String error) {
ReConnect(error);
}
});
}

@Override
public void ReadInt(String address, int length, int slaveId, DataFormat df, IReadCallBack<int[]> callback) {
if (!IsConnected) {
return;
}
new ExceptionServer(address, length, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
ReadHoldingRegistersResponse res = mw.syncReadHoldingRegisters(slaveId, add, length * 2);
byte[] data = res.getData();
int[] tempValues = new int[length];
if(data.length==4*length)
{
for (int i = 0; i < length; i++) {
byte[] tempData = new byte[4];
for (int m = 0; m < 4; m++) {
tempData[m] = data[i * 4 + m];
}
tempValues[i] = DataConvertLib.BytesToInt(tempData, df);
}
if (callback != null) callback.onSuccess(tempValues);
}else{
MessageLog.ShowError("ReadInt onFailure,数据长度不匹配,读取长度:"+length+"返回长度:"+data.length );
}
}

@Override
public void onFailure(String error) {
ReConnect(error);
}
});
}

@Override
public void ReadInt(String address, int length, int slaveId, IReadCallBack<int[]> callback) {
if (!IsConnected) {
return;
}
ReadInt(address, length, slaveId,DataFormat.BADC, callback);
}

@Override
public void ReadByte(String address, int length, int slaveId, IReadCallBack<byte[]> callback) {
if (!IsConnected) {
return;
}
new ExceptionServer(address, length, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
int tempLength=length;
if (length%2!=0){
tempLength++;
}
ReadHoldingRegistersResponse res = mw.syncReadHoldingRegisters(slaveId, add, tempLength );
byte[] data = res.getData();
if(data.length==tempLength)
{
byte[] result = Arrays.copyOfRange(data, 0, length);
if (callback != null) callback.onSuccess(result);
}else
{
MessageLog.ShowError("ReadInt onFailure,数据长度不匹配,读取长度:"+length+"返回长度:"+data.length );
}
}

@Override
public void onFailure(String error) {
ReConnect(error);
}
});
}

@Override
public void ReadString(String address, int length, int slaveId, IReadCallBack<String> callback) {
if (!IsConnected) {
return;
}
new ExceptionServer(address, length, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
ReadHoldingRegistersResponse res = mw.syncReadHoldingRegisters(slaveId, add, length);
byte[] data = res.getData();
try {
if (data.length ==length*2) {
if (callback != null) callback.onSuccess(new String(data, "UTF-8").trim());
}
} catch (UnsupportedEncodingException ex) {
}
}

@Override
public void onFailure(String error) {
ReConnect(error);
}
});
}

@Override
public void ReadFloat(String address, int length, int slaveId, DataFormat df, IReadCallBack<float[]> callback) {
if (!IsConnected) {
return;
}
new ExceptionServer(address, length, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
ReadHoldingRegistersResponse res = mw.syncReadHoldingRegisters(slaveId, add, length*2);
byte[] data = res.getData();
float[] tempValues = new float[length];
for (int i = 0; i < length; i++) {
byte[] tempData = new byte[4];
for (int m = 0; m < 4; m++) {
tempData[m] = data[i * 4 + m];
}
tempValues[i] = DataConvertLib.BytesToFloat(tempData, df);
}
if (tempValues.length == length) {
if (callback != null) callback.onSuccess(tempValues);
}
}

@Override
public void onFailure(String error) {
ReConnect(error);
}
});
}

@Override
public void ReadFloat(String address, int length, int slaveId, IReadCallBack<float[]> callback) {
if (!IsConnected) {
return;
}
ReadFloat(address,length,slaveId,DataFormat.BADC,callback);
}




@Override
public void WriteBool(String address, boolean value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
mw.syncWriteCoil(slaveId, add, value);
if (callback != null)callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteBool(String address, boolean[] value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
mw.syncWriteCoils(slaveId, add, value);
if (callback != null)callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteShort(String address, short value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
short[] send = new short[1];
send[0] = value;
mw.syncWriteRegisters(slaveId, add, send);
if (callback != null)callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteShort(String address, short[] value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
mw.syncWriteRegisters(slaveId, add, value);
if (callback != null)callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteInt(String address, int value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
short[] send = DataConvertLib.IntToShorts(value);
mw.syncWriteRegisters(slaveId, add, send);
if (callback != null) callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteInt(String address, int[] value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
short[] send=new short[value.length*2];
for(int i=0;i<value.length;i=i+2)
{
short[] temp = DataConvertLib.IntToShorts(value[i]);
if (temp.length==2)
{
send[i]=temp[0];
send[i+1]=temp[1];
}
}
mw.syncWriteRegisters(slaveId, add,send);
if (callback != null) callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteString(String address, String value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
byte[] bytes= value.getBytes();
short[] send =DataConvertLib.ByteToShort(bytes);
mw.syncWriteRegisters(slaveId, add, send);
if (callback != null) callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteFloat(String address, float value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
int intBits = Float.floatToRawIntBits(value);
short[] send = DataConvertLib.IntToShorts(intBits);
mw.syncWriteRegisters(slaveId, add, send);
if (callback != null) callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}

@Override
public void WriteFloat(String address, float[] value, int slaveId, IWriteCallBack callback) {
if (!IsConnected) {
if (callback != null) callback.onFailure("设备未连接");
return;
}
new ExceptionServer(address, 1, new IExceptionHandling() {
@Override
public void onSuccess(int add) throws InterruptedException, ExecutionException, ModbusTransportException, ModbusInitException, ModbusRespException {
short[] send=new short[value.length*2];
for(int i=0;i<value.length;i=i+2)
{
int intBits = Float.floatToRawIntBits(value[i]);
short[] temp = DataConvertLib.IntToShorts(intBits);
if (temp.length==2)
{
send[i]=temp[0];
send[i+1]=temp[1];
}
}
mw.syncWriteRegisters(slaveId, add, send);
if (callback != null) callback.onSuccess();
}

@Override
public void onFailure(String error) {
if (callback != null)callback.onFailure(error);
ReConnect(error);
}
});
}


}

+ 81
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/ByteLib.java View File

@@ -0,0 +1,81 @@
package com.jdzh.jdzhandroid.DataUtil;


import com.jdzh.jdzhandroid.Enum.DataFormat;

public class ByteLib {

public static byte[] ToBytes(short value, DataFormat df) {
byte[] b = new byte[2];
b[0]=(byte)((value>>8)&0xff);
b[1]=(byte)((value>>0)&0xff);
return new ByteTransDataFormat().ByteTransDataFormat2(b,df,0);
}

public static byte[] ToBytes(short[] value,DataFormat df) {
byte[] b = new byte[value.length*2];
for (int i = 0; i < value.length; i++)
{
b[i*2]=(byte)((value[i]>>8)&0xff);
b[i*2+1]=(byte)((value[i]>>0)&0xff);
}
return new ByteTransDataFormat().ByteTransDataFormat2(b,df,0);
}

public static byte[] ToBytes(float value,DataFormat df) {
int tempValue = Float.floatToRawIntBits(value);
byte[] b = new byte[4];
b[0]=(byte)((tempValue>>24)&0xff);
b[1]=(byte)((tempValue>>16)&0xff);
b[2]=(byte)((tempValue>>8)&0xff);
b[3]=(byte)((tempValue>>0)&0xff);
return new ByteTransDataFormat().ByteTransDataFormat4(b,df,0);
}

public static byte[] ToBytes(float[] value,DataFormat df) {
byte[] b = new byte[value.length*4];
for (int i=0;i<value.length;i++)
{
int tempValue = Float.floatToRawIntBits(value[i]);
b[i*4]=(byte)((tempValue>>24)&0xff);
b[i*4+1]=(byte)((tempValue>>16)&0xff);
b[i*4+2]=(byte)((tempValue>>8)&0xff);
b[i*4+3]=(byte)((tempValue>>0)&0xff);
}
return new ByteTransDataFormat().ByteTransDataFormat4(b,df,0);
}

public static byte[] ToBytes(int value,DataFormat df) {
byte[] b = new byte[4];
b[0]=(byte)((value>>24)&0xff);
b[1]=(byte)((value>>16)&0xff);
b[2]=(byte)((value>>8)&0xff);
b[3]=(byte)((value>>0)&0xff);
return new ByteTransDataFormat().ByteTransDataFormat4(b,df,0);
}

public static byte[] ToBytes(int[] value,DataFormat df) {
byte[] b = new byte[value.length*4];
for (int i=0;i<value.length;i++)
{
b[i*4]=(byte)((value[i]>>24)&0xff);
b[i*4+1]=(byte)((value[i]>>16)&0xff);
b[i*4+2]=(byte)((value[i]>>8)&0xff);
b[i*4+3]=(byte)((value[i]>>0)&0xff);
}
return new ByteTransDataFormat().ByteTransDataFormat4(b,df,0);
}

public static boolean GetBit(byte value,int offset)
{
if (offset > 8 || offset < 1) return false;
return (value & 1 << offset - 1) == 0 ? false : true;
}

public static byte SetBit(byte value,int offset, boolean val)
{
if (offset > 8 || offset < 1) return value;
int ConvertValue = 1 << offset - 1;
return (byte)(val ? value | ConvertValue : value & ~ConvertValue);
}
}

+ 51
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/ByteTransDataFormat.java View File

@@ -0,0 +1,51 @@
package com.jdzh.jdzhandroid.DataUtil;


import com.jdzh.jdzhandroid.Enum.DataFormat;

public class ByteTransDataFormat {
public byte[] ByteTransDataFormat2(byte[] data, DataFormat df, int offset ){
if (offset+2<2) return new byte[2];
byte[] numArray = new byte[2];
if (df==DataFormat.ABCD||df==DataFormat.BADC){
numArray[0] = data[offset+1];
numArray[1] = data[offset];
}
else {
numArray[0] = data[offset];
numArray[1] = data[offset+1];
}
return numArray;
}

public byte[] ByteTransDataFormat4(byte[] data, DataFormat df,int offset ){
if (offset+4<4) return new byte[4];
byte[] numArray = new byte[4];
if (df==DataFormat.ABCD){
numArray[0] = data[offset+3];
numArray[1] = data[offset+2];
numArray[2] = data[offset+1];
numArray[3] = data[offset];
}
else if (df==DataFormat.BADC){
numArray[0] = data[offset+2];
numArray[1] = data[offset+3];
numArray[2] = data[offset];
numArray[3] = data[offset+1];
}
else if(df==DataFormat.CDAB){
numArray[0] = data[offset+1];
numArray[1] = data[offset];
numArray[2] = data[offset+3];
numArray[3] = data[offset+2];
}
else if(df==DataFormat.DCBA){
numArray[0] = data[offset];
numArray[1] = data[offset+1];
numArray[2] = data[offset+2];
numArray[3] = data[offset+3];
}
return numArray;
}
}


+ 107
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/Convert.java View File

@@ -0,0 +1,107 @@
package com.jdzh.jdzhandroid.DataUtil;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jdzh.jdzhandroid.Result.OperateResultT;

public class Convert {
public static OperateResultT<Boolean> TryToBoolean(Object value){
if(value==null) return OperateResultT.CreateFailedT("TryToBoolean:转换对象为空");
try{
return OperateResultT.CreateSuccess(Boolean.parseBoolean(value.toString()));
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}

public static OperateResultT<Integer> TryToInt(Object value){
if(value==null) return OperateResultT.CreateFailedT("TryToInt:转换对象为空");
try{
return OperateResultT.CreateSuccess(Integer.parseInt(value.toString()));
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}

public static OperateResultT<Short> TryToShort(Object value){
if(value==null) return OperateResultT.CreateFailedT("TryToShort:转换对象为空");
try{
return OperateResultT.CreateSuccess(Short.parseShort(value.toString()));
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}

public static OperateResultT<Float> TryToFloat(Object value){
if(value==null) return OperateResultT.CreateFailedT("TryToFloat:转换对象为空");
try{
return OperateResultT.CreateSuccess(Float.parseFloat(value.toString()));
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}

public static <T> OperateResultT<T> TryToGenericity( Object value){
if(value==null) return OperateResultT.CreateFailedT("TryToGenericity:转换对象为空");
try{
return OperateResultT.CreateSuccess((T)value);
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}

// public static <T extends Number> OperateResultT<T> TryToNumber(Object value,Class<T> type){
// if(value==null) return OperateResultT.CreateFailedT("TryToGenericity:转换对象为空");
// try{
// String temp = value.toString();
// if(type==Integer.TYPE){
// return OperateResultT.CreateSuccess((T)Integer.valueOf(temp));
// }else if (type==Short.TYPE){
// return OperateResultT.CreateSuccess((T)Short.valueOf(temp));
// }else if (type==Byte.TYPE){
// return OperateResultT.CreateSuccess((T)Byte.valueOf(temp));
// }else if (type==Float.TYPE){
// return OperateResultT.CreateSuccess((T)Float.valueOf(temp));
// }else if (type==Long.TYPE){
// return OperateResultT.CreateSuccess((T)Long.valueOf(temp));
// }else if (type==Double.TYPE){
// return OperateResultT.CreateSuccess((T)Double.valueOf(temp));
// }else if (type.getName().contains(Boolean.TYPE.getName())){
// return OperateResultT.CreateSuccess((T)Boolean.valueOf(temp));
// }else if (type.getName().contains(String.class.getName())){
// return OperateResultT.CreateSuccess((T)temp);
// }
// return OperateResultT.CreateSuccess((T)value);
// }catch (Exception e) {
// return OperateResultT.CreateFailedT(e);
// }
// }

public static <T> OperateResultT<T> fromJson(Object value, Class<T> clazz) {
if(value==null) return OperateResultT.CreateFailedT("TryToBoolean:转换对象为空");
try{
Gson gson = new GsonBuilder().create();
String temp = gson.toJson(value);
T arr = gson.fromJson(temp, clazz);
if(arr!=null)return OperateResultT.CreateSuccess( arr );
else return OperateResultT.CreateFailedT("返回对象为空");
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}

public static <T> OperateResultT<T> fromJson(String value, Class<T> clazz) {
if(value==null||value.isEmpty()) return OperateResultT.CreateFailedT("TryToBoolean:转换对象为空");
try{
Gson gson = new GsonBuilder().create();
T arr = gson.fromJson(value, clazz);
if(arr!=null)return OperateResultT.CreateSuccess( arr);
else return OperateResultT.CreateFailedT("返回对象为空");
}catch (Exception e) {
return OperateResultT.CreateFailedT(e);
}
}


}

+ 263
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/DataConvertLib.java View File

@@ -0,0 +1,263 @@
package com.jdzh.jdzhandroid.DataUtil;

import com.jdzh.jdzhandroid.Enum.DataFormat;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

public class DataConvertLib {

/***
* 字节数组转换成浮点数
* @param ,需要转换的字节
* @param ,转换的数据格式
* @return
*/
public static Float BytesToFloat(byte[] buffers, DataFormat df) {
if (buffers.length == 4) {
byte[] bytes = new byte[4];
if (df == DataFormat.ABCD) {
bytes[0] = buffers[3];
bytes[1] = buffers[2];
bytes[2] = buffers[1];
bytes[3] = buffers[0];
} else if (df == DataFormat.CDAB) {
bytes[0] = buffers[1];
bytes[1] = buffers[0];
bytes[2] = buffers[3];
bytes[3] = buffers[2];
} else if (df == DataFormat.BADC) {
bytes[0] = buffers[2];
bytes[1] = buffers[3];
bytes[2] = buffers[0];
bytes[3] = buffers[1];
} else if (df == DataFormat.DCBA) {
bytes[0] = buffers[0];
bytes[1] = buffers[1];
bytes[2] = buffers[2];
bytes[3] = buffers[3];
}
return ByteBuffer.wrap(bytes).getFloat();
}
return 0.0f;
}

/**
* 字节数组转换成整形
* @param ,需要转换的字节数组
* @param ,转换的数据格式
* @return
*/
public static Integer BytesToInt(byte[] buffers, DataFormat df) {
if (buffers.length == 4) {
byte[] bytes = new byte[4];
if (df == DataFormat.ABCD) {
bytes[0] = buffers[3];
bytes[1] = buffers[2];
bytes[2] = buffers[1];
bytes[3] = buffers[0];
} else if (df == DataFormat.CDAB) {
bytes[0] = buffers[1];
bytes[1] = buffers[0];
bytes[2] = buffers[3];
bytes[3] = buffers[2];
} else if (df == DataFormat.BADC) {
bytes[0] = buffers[2];
bytes[1] = buffers[3];
bytes[2] = buffers[0];
bytes[3] = buffers[1];
} else if (df == DataFormat.DCBA) {
bytes[0] = buffers[0];
bytes[1] = buffers[1];
bytes[2] = buffers[2];
bytes[3] = buffers[3];
}
return ByteBuffer.wrap(bytes).getInt();
}
return 0;
}

/**
* 32位整数转换成字节
* @param ,number
* @return
*/
public static byte[] IntToByte(int number) {
int temp = number;
byte[] b = new byte[4];
for (int i = 0; i < b.length; i++) {
b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位
temp = temp >> 8; // 向右移8位
}
return b;
}

/**
* 32位整形转换成16位整数数组
* @param ,value
* @return
*/
public static short[] IntToShorts(int value) {
short[] res = new short[2];
int temp = value;
byte[] b = new byte[4];
for (int i = 0; i < b.length; i++) {
b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位
temp = temp >> 8; // 向右移8位
}
for (int i = 0; i < res.length; i++) {
short s0 = (short) (b[i * 2] & 0xff);// 最低位
short s1 = (short) (b[i * 2 + 1] & 0xff);
s1 <<= 8;
res[i] = (short) (s0 | s1);
}
return res;
}

public static String GetString(short[] src, int start, int len) throws UnsupportedEncodingException {
short[] temp = new short[len];
for (int i = 0; i < len; i++) {
temp[i] = src[i + start];
}
byte[] bytesTemp = shorts2Bytes(temp);
for (int i = 0; i < bytesTemp.length; i++) {
byte b = bytesTemp[i];
}
String str = new String(bytesTemp, "UTF-8");
return str;
}

public static short[] ByteToShort(byte[] bytes) {

int len=bytes.length;
if (bytes.length%2!=0) len++;
byte[] tempBytes=new byte[len];
short[] result = new short[len/2];
for (int i=0;i<len;i++){
if (i<bytes.length)tempBytes[i]=bytes[i];
}
for(int m=0;m<result.length;m++) {
result[m] = (short) ((tempBytes[m * 2] & 0xff) | ((tempBytes[m * 2 + 1] & 0xff) << 8));
}
return result;
}


public static byte[] shorts2Bytes(short[] data) {
byte[] byteValue = new byte[data.length * 2];
for (int i = 0; i < data.length; i++) {
byteValue[i * 2] = (byte) (data[i] & 0xff);
byteValue[i * 2 + 1] = (byte) ((data[i] & 0xff00) >> 8);
}
return byteValue;
}

public static int GetAddress(String address) {
if (address == null) return -1;
if (address.length() > 0) {
address = address.trim();
if (address.toUpperCase().contains("M") && address.length() >= 4) {
String[] res = address.substring(1).split("[.]");
if (res != null && res.length == 2) {
try {
int firstAdd = Integer.parseInt(res[0]);
int endAdd = Integer.parseInt(res[1]);
if (endAdd >= 0 && endAdd <= 7) {
return (firstAdd * 8) + 320 + endAdd;
}
} catch (NumberFormatException e) {
return -1;
}
}
} else if (address.toUpperCase().contains("I") && address.length() >= 4) {
String[] res = address.substring(1).split("[.]");
if (res != null && res.length == 2) {
try {
int firstAdd = Integer.parseInt(res[0]);
int endAdd = Integer.parseInt(res[1]);
if (endAdd >= 0 && endAdd <= 7) {
return (firstAdd * 8) + endAdd;
}
} catch (NumberFormatException e) {
return -1;
}
}
} else if ((address.toUpperCase().contains("VW") || address.toUpperCase().contains("VD")) && address.length() >= 3) {
String res = address.substring(2);
if (res != null) {
try {
int tempAdd = Integer.parseInt(res);
return (tempAdd / 2) + 100;
} catch (NumberFormatException e) {
return -1;
}
}
}else if (address.toUpperCase().contains("GI") &&address.length() >=3){
String res = address.substring(2);
if (res != null) {
try {
return Integer.parseInt(res);
} catch (NumberFormatException e) {
return -1;
}
}
}
else {
try {
return Integer.parseInt(address);
} catch (NumberFormatException e) {
return -1;
}
}
}
return -1;
}


/**
* 获取布尔位地址信息
* 列:M2.5 = getBitSingleAdd("M",2,5);
*
* @param Prefix 地址标头
* @param startAdd 起始地址编号
* @param num 要获取的第几位数量
* @return
*/
public static String getBitSingleAdd(String Prefix, int startAdd, int num) {
if (num > 0) {
int FirstAdd = num / 8;
int EndAdd = num % 8;
if (EndAdd == 0) {
FirstAdd--;
EndAdd = 7;
} else {
EndAdd--;
}
return Prefix + FirstAdd + startAdd + "." + EndAdd;
}
return "";
}

public static String bytesToString(byte[] bytes){
if (bytes == null) {
return null;
}
StringBuilder builder = new StringBuilder();
char[] hexArray = "0123456789ABCDEF".toCharArray();
for (byte aByte : bytes) {
int v = aByte & 0xFF;
builder.append(hexArray[v >>> 4]).append(hexArray[v & 0x0F]).append(" ");
}
return builder.toString();
}
public static int bytes2Int(byte[] bytes) {
int value = 0;
// 由高位到低位
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (bytes[i] & 0x000000FF) << shift;// 往高位游
}
return value;
}

}

+ 14
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/DataType.java View File

@@ -0,0 +1,14 @@
package com.jdzh.jdzhandroid.DataUtil;

public class DataType {
public static final String STRING="";
public static final byte BYTE=0;
public static final short SHORT=0;

public static final short[] SHORTS = new short[0];
public static final int INT=0;
public static final long LONG=0;
public static final float FLOAT=0f;
public static final double DOUBLE=0d;
public static final boolean BOOLEAN=false;
}

+ 27
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/FloatLib.java View File

@@ -0,0 +1,27 @@
package com.jdzh.jdzhandroid.DataUtil;
import com.jdzh.jdzhandroid.Enum.DataFormat;

import java.nio.ByteBuffer;

public class FloatLib {
public static float ToFloat(byte[] bytes, DataFormat df) {
byte[] res= new ByteTransDataFormat().ByteTransDataFormat4(bytes,df,0);
return ByteBuffer.wrap(res).getFloat();
}

public static float[] ToFloats(byte[] bytes, DataFormat df) {
byte[] tempBytes=new byte[bytes.length];
if (bytes.length%4!=0)
{
int offset=4-bytes.length%4;
tempBytes=new byte[bytes.length+offset];
}
for (int i=0;i<bytes.length;i++){tempBytes[i]=bytes[i];}
float[] result = new float[tempBytes.length/4];
for (int i=0; i<result.length; i++){
byte[] res= new ByteTransDataFormat().ByteTransDataFormat4(tempBytes,df,i*4);
result[i]=ByteBuffer.wrap(res).getFloat();
}
return result;
}
}

+ 47
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/IntLib.java View File

@@ -0,0 +1,47 @@
package com.jdzh.jdzhandroid.DataUtil;
import com.jdzh.jdzhandroid.Enum.DataFormat;

import java.nio.ByteBuffer;

public class IntLib {
public static int ToInt(byte[] bytes, DataFormat df) {
byte[] res= new ByteTransDataFormat().ByteTransDataFormat4(bytes,df,0);
return ByteBuffer.wrap(res).getInt();
}

public static int ToInt(short[] shorts, DataFormat df) {
if (shorts.length<2) return 0;
byte[] bytes= ByteLib.ToBytes(shorts,df);
if (bytes.length!=4) return 0;
return ByteBuffer.wrap(bytes).getInt();
}

public static int[] ToInts(byte[] bytes, DataFormat df) {
byte[] tempBytes=new byte[bytes.length];
if (bytes.length%4!=0)
{
int offset=4-bytes.length%4;
tempBytes=new byte[bytes.length+offset];
}
for (int i=0;i<bytes.length;i++){tempBytes[i]=bytes[i];}
int[] result = new int[tempBytes.length/4];
for (int i=0; i<result.length; i++){
byte[] res= new ByteTransDataFormat().ByteTransDataFormat4(tempBytes,df,i*4);
result[i]=ByteBuffer.wrap(res).getInt();
}
return result;
}

public static boolean GetBit(int value,int offset)
{
if (offset > 32 || offset < 1) return false;
return (value & 1 << offset - 1) == 0 ? false : true;
}

public static int SetBit(int value,int offset, boolean val)
{
if (offset > 32 || offset < 1) return value;
int ConvertValue =1 << offset - 1;
return val ? value | ConvertValue : value & ~ConvertValue;
}
}

+ 34
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/NotifyPropVar.java View File

@@ -0,0 +1,34 @@
package com.jdzh.jdzhandroid.DataUtil;
import com.jdzh.jdzhandroid.Interface.IRunT;

import java.io.Serializable;
import java.util.LinkedHashMap;

public class NotifyPropVar<T extends Serializable> {

public NotifyPropVar(T defaultValue){
_value=defaultValue;
}
public IRunT<T> ChangeNotify;

private boolean IsFirst=false;
private LinkedHashMap<String,IRunT<T>> changedNotifys=new LinkedHashMap<>();

public void Register(String key,IRunT<T> notify){
// if(changedNotifys.containsKey(key))changedNotifys.remove(key);
changedNotifys.put(key,notify);
}

private T _value;
// public T getValue(){ return _value; }
public <T> T getValue(){ return (T) _value; }
public void setValue(T value){
if (value != null && !value.equals(_value) || !IsFirst) {
_value=value;
if(ChangeNotify!=null) ChangeNotify.Run(value);
changedNotifys.values().forEach(item->{if(item!=null) item.Run(value);});
IsFirst = true;
}
}
}


+ 47
- 0
app/src/main/java/com/jdzh/jdzhandroid/DataUtil/ShortLib.java View File

@@ -0,0 +1,47 @@
package com.jdzh.jdzhandroid.DataUtil;
import com.jdzh.jdzhandroid.Enum.DataFormat;

import java.nio.ByteBuffer;

public class ShortLib {
public static short ToShort(byte[] bytes, DataFormat df) {
byte[] res= new ByteTransDataFormat().ByteTransDataFormat2(bytes,df,0);
short result= ByteBuffer.wrap(res).getShort();
return result;
}

public static short[] ToShorts(byte[] bytes, DataFormat df) {
byte[] tempBytes=new byte[bytes.length];
if (bytes.length%2!=0){ tempBytes=new byte[bytes.length+1]; }
for (int i=0; i<bytes.length; i++){tempBytes[i]=bytes[i];}
short[] result = new short[tempBytes.length/2];
for (int i=0; i<result.length; i++){
byte[] res= new ByteTransDataFormat().ByteTransDataFormat2(tempBytes,df,i*2);
result[i]=ByteBuffer.wrap(res).getShort();
}
return result;
}

public static short[] ToShorts(float[] floats, DataFormat df) {
byte[] bytes = ByteLib.ToBytes(floats,df);
return ShortLib.ToShorts(bytes,df);
}

public static short[] ToShorts(int[] floats, DataFormat df) {
byte[] bytes = ByteLib.ToBytes(floats,df);
return ShortLib.ToShorts(bytes,df);
}

public static boolean GetBit(short value,int offset)
{
if (offset > 16 || offset < 1) return false;
return (value & 1 << offset - 1) == 0 ? false : true;
}

public static short SetBit(short value,int offset, boolean val)
{
if (offset > 16 || offset < 1) return value;
short ConvertValue = (short)(1 << offset - 1);
return (short)(val ? value | ConvertValue : value & ~ConvertValue);
}
}

+ 8
- 0
app/src/main/java/com/jdzh/jdzhandroid/Enum/DataFormat.java View File

@@ -0,0 +1,8 @@
package com.jdzh.jdzhandroid.Enum;

public enum DataFormat {
ABCD,
CDAB,
BADC,
DCBA
}

+ 5
- 0
app/src/main/java/com/jdzh/jdzhandroid/Interface/IRun.java View File

@@ -0,0 +1,5 @@
package com.jdzh.jdzhandroid.Interface;

public interface IRun {
void Run();
}

+ 7
- 0
app/src/main/java/com/jdzh/jdzhandroid/Interface/IRunT.java View File

@@ -0,0 +1,7 @@
package com.jdzh.jdzhandroid.Interface;

public interface IRunT<T> {
void Run(T t);
}



+ 5
- 0
app/src/main/java/com/jdzh/jdzhandroid/Interface/IRunT2.java View File

@@ -0,0 +1,5 @@
package com.jdzh.jdzhandroid.Interface;

public interface IRunT2<T1,T2> {
void Run(T1 t1, T2 t2);;
}

+ 7
- 0
app/src/main/java/com/jdzh/jdzhandroid/Log/IMessageLogNotify.java View File

@@ -0,0 +1,7 @@
package com.jdzh.jdzhandroid.Log;

public interface IMessageLogNotify {
void ErrorMsg(String msg);
void InfoMsg(String msg);
void WarnMsg(String msg);
}

+ 58
- 0
app/src/main/java/com/jdzh/jdzhandroid/Log/MessageLog.java View File

@@ -0,0 +1,58 @@
package com.jdzh.jdzhandroid.Log;

import com.apkfuns.logutils.LogUtils;

import java.util.concurrent.ConcurrentLinkedQueue;

public class MessageLog {
private static IMessageLogNotify MsgNotify;
private static ConcurrentLinkedQueue<String> msgQueue=new ConcurrentLinkedQueue<String>();
private static void Init(){
MsgNotify = new IMessageLogNotify() {
@Override
public void ErrorMsg(String msg) {
LogUtils.e("错误日志 "+msg);
}

@Override
public void InfoMsg(String msg) {
LogUtils.d("信息日志 "+msg);
}

@Override
public void WarnMsg(String msg) {
LogUtils.d("警告日志 "+msg);
}
};
// ThreadManager.get().StartLong("日志信息保存",true, () -> {
// while(msgQueue.size()>0){
// String msg= msgQueue.poll();
// BPA_ALERTLOG log= new BPA_ALERTLOG();
// log.text=msg;
// QueryDB.AddAlertlog(log);
// }
// Thread.sleep(2000);
// });
}

public static void ShowInfo(String msg) {
if (MsgNotify == null)Init();
MsgNotify.InfoMsg(msg);
}

public static void ShowWarning(String msg) {
if (MsgNotify == null)Init();
MsgNotify.WarnMsg(msg);
}

public static void ShowError(String msg) {
if (MsgNotify == null)Init();
MsgNotify.ErrorMsg(msg);
}

public static void ShowError(Exception e) {
if (MsgNotify == null)Init();
MsgNotify.ErrorMsg(e.toString());
}

}

+ 25
- 0
app/src/main/java/com/jdzh/jdzhandroid/MainActivity.java View File

@@ -0,0 +1,25 @@
package com.jdzh.jdzhandroid;

import android.os.Bundle;


import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
}

+ 39
- 0
app/src/main/java/com/jdzh/jdzhandroid/Result/IResult.java View File

@@ -0,0 +1,39 @@
package com.jdzh.jdzhandroid.Result;


public abstract class IResult {
/**
* 是否成功
*/
public boolean isSuccess ;

/**
* 返回消息
*/
public String message;

/**
* 操作代码
*/
public ResultCode resultCode = ResultCode.Default ;

abstract void setErrorMsg(String msg);

public boolean getIsSuccess(){
return resultCode==ResultCode.Success;
}

public void setIsSuccess(boolean tempSuccess){
isSuccess= tempSuccess;
resultCode = tempSuccess ? ResultCode.Success : ResultCode.Fail;
}

@Override
public String toString() {
return "IResult{" +
"isSuccess=" + isSuccess +
", message='" + message + '\'' +
", resultCode=" + resultCode +
'}';
}
}

+ 78
- 0
app/src/main/java/com/jdzh/jdzhandroid/Result/OperateResult.java View File

@@ -0,0 +1,78 @@
package com.jdzh.jdzhandroid.Result;

import com.jdzh.jdzhandroid.Interface.IRun;
import com.jdzh.jdzhandroid.Log.MessageLog;

public class OperateResult extends IResult {

public OperateResult(){

}

public OperateResult(Exception ex){
message = ex.getMessage()+"\rException:"+ex.toString();
resultCode = ResultCode.Exception;
isSuccess=false;
}

public OperateResult(String msg, ResultCode rc)
{
message = msg;
resultCode = rc;
isSuccess=false;
}

public OperateResult(ResultCode rc)
{
resultCode = rc;
isSuccess=true;
}


@Override
public void setErrorMsg(String msg) {
message =message+ msg;
isSuccess=false;
resultCode = ResultCode.Fail;
}

public OperateResult OnSource(IRun action){
if(action!=null&&getIsSuccess())action.Run();
return this;
}

public OperateResult OnFailed(IRun action){
try{
if(action!=null&&!getIsSuccess())action.Run();
}catch(Exception e){
MessageLog.ShowError(e);
}
return this;
}

public OperateResult OnFinally(IRun action){
try{
if(action!=null)action.Run();
}catch(Exception e){
MessageLog.ShowError(e);
}
return this;
}

public static OperateResult CreateSuccess()
{
return new OperateResult(ResultCode.Success);
}

public static OperateResult CreateFailed(String msg)
{
MessageLog.ShowError(msg);
return new OperateResult(msg, ResultCode.Fail);
}

public static OperateResult CreateFailed(Exception ex)
{
MessageLog.ShowError(ex.toString());
return new OperateResult(ex);
}
}

+ 89
- 0
app/src/main/java/com/jdzh/jdzhandroid/Result/OperateResultT.java View File

@@ -0,0 +1,89 @@
package com.jdzh.jdzhandroid.Result;


import com.apkfuns.logutils.LogUtils;
import com.jdzh.jdzhandroid.Interface.IRunT;
import com.jdzh.jdzhandroid.Log.MessageLog;

public class OperateResultT<T> extends IResult
{
public OperateResultT(){}
public OperateResultT(Exception ex) {
message = ex.getMessage()+"\rException:"+ex.toString();
resultCode = ResultCode.Exception;
isSuccess=false;
}

public OperateResultT(String msg, ResultCode rc ){
message = msg;
resultCode = rc;
isSuccess=false;
}

public OperateResultT(ResultCode rc){
resultCode = rc;
isSuccess=true;
}

@Override
public void setErrorMsg(String msg) {
message =message+ msg;
isSuccess=false;
resultCode = ResultCode.Fail;
}

public OperateResultT(T content, String msg, ResultCode rc){
Content = content;
message = msg;
resultCode = rc;
isSuccess=getIsSuccess();
}

public T Content ;

public void setContent(T value){
Content = value;
resultCode = ResultCode.Success;
isSuccess=true;
}

public OperateResultT<T> OnSource(IRunT<OperateResultT<T>> action){
try{
if(action!=null&&getIsSuccess())action.Run(this);
}catch(Exception e){
MessageLog.ShowError(e);
}
return this;
}

public OperateResultT<T> OnFailed(IRunT<OperateResultT<T>> action){
try{
if(action!=null&&!getIsSuccess())action.Run(this);
}catch(Exception e){
MessageLog.ShowError(e);
}
return this;
}

public OperateResultT<T> OnFinally(IRunT<OperateResultT<T>> action){
if(action!=null)action.Run(this);
return this;
}

public static <T> OperateResultT<T> CreateSuccess(T value)
{
return new OperateResultT<T>(value,"", ResultCode.Success);
}

public static <T> OperateResultT<T> CreateFailedT(String msg)
{
MessageLog.ShowError(msg);
return new OperateResultT<T>( msg, ResultCode.Fail);
}

public static <T> OperateResultT<T> CreateFailedT(Exception ex)
{
MessageLog.ShowError(ex.toString());
return new OperateResultT<T>(ex);
}
}

+ 38
- 0
app/src/main/java/com/jdzh/jdzhandroid/Result/ResultCode.java View File

@@ -0,0 +1,38 @@
package com.jdzh.jdzhandroid.Result;

public enum ResultCode {
/**
* 默认
*/
Default,

/**
* 错误
*/
Error,

/**
* 异常
*/
Exception,

/**
* 成功
*/
Success,

/**
* 失败
*/
Fail,

/**
* 操作超时
*/
Overtime,

/**
* 操作取消
*/
Canceled
}

+ 5
- 0
app/src/main/java/com/jdzh/jdzhandroid/Task/ITask.java View File

@@ -0,0 +1,5 @@
package com.jdzh.jdzhandroid.Task;

public interface ITask {
void Run() throws InterruptedException;
}

+ 7
- 0
app/src/main/java/com/jdzh/jdzhandroid/Task/ITaskComplete.java View File

@@ -0,0 +1,7 @@
package com.jdzh.jdzhandroid.Task;

public interface ITaskComplete {
void Run() throws Exception;

void RunComplete() throws Exception;
}

+ 25
- 0
app/src/main/java/com/jdzh/jdzhandroid/Task/Task.java View File

@@ -0,0 +1,25 @@
package com.jdzh.jdzhandroid.Task;


import com.jdzh.jdzhandroid.Interface.IRun;
import com.jdzh.jdzhandroid.Log.MessageLog;

public class Task {
public static void Run(IRun action){
if(action!=null){
new Thread(()->{
try{
action.Run();
}catch(Exception e){
MessageLog.ShowError(e.getMessage());
}
}).start();
}
}

public static void Delay(long millis){
try{
Thread.sleep(millis);
}catch (Exception e){}
}
}

+ 82
- 0
app/src/main/java/com/jdzh/jdzhandroid/Task/TaskManager.java View File

@@ -0,0 +1,82 @@
package com.jdzh.jdzhandroid.Task;

import com.jdzh.jdzhandroid.Log.MessageLog;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TaskManager {
private static volatile TaskManager _Instance;
public static TaskManager get() {
if (_Instance == null){
synchronized (TaskManager.class){
if (_Instance == null){
_Instance = new TaskManager();
}
}
}
return _Instance;
}

private TaskManager() {

}


public long RestartInterval = 1000;
ConcurrentHashMap<String, TaskModel> tm = new ConcurrentHashMap<>();

private void Sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

public void StartLong(String Key, boolean IsRestart, ITask _thread) {
if (!tm.containsKey(Key)) {
tm.put(Key, new TaskModel());
tm.get(Key).Task = _thread;
tm.get(Key).ThreadObj = new Thread(() -> {
MessageLog.ShowInfo("启动线程:" + Key);
while (!tm.get(Key).IsCancel) {
if (IsRestart) {
try {
tm.get(Key).Task.Run();
} catch (Exception ex) {
MessageLog.ShowError("多线程:[" + Key + "] 运行发生异常,已重启,错误信息:" + ex.toString());
Sleep(RestartInterval);
}
} else {
try {
tm.get(Key).Task.Run();
} catch (Exception e) {
MessageLog.ShowError("多线程:[" + Key + "] 运行发生异常,已重启,错误信息:" + e.toString());
}
}
}
tm.remove(Key);
});
tm.get(Key).ThreadObj.setName(Key);
tm.get(Key).ThreadObj.start();
} else {
MessageLog.ShowWarning("任务-[" + Key + "]-已存在");
}
}

public void Stop(String Key) {
if (tm.containsKey(Key)) {
tm.get(Key).IsCancel = true;
}
}

public void release(){
for (HashMap.Entry<String, TaskModel> entry : tm.entrySet()) {
entry.getValue().IsCancel = true;
}
}

}

+ 8
- 0
app/src/main/java/com/jdzh/jdzhandroid/Task/TaskModel.java View File

@@ -0,0 +1,8 @@
package com.jdzh.jdzhandroid.Task;

public class TaskModel {
public ITaskComplete RunThread;
public ITask Task;
public boolean IsCancel;
public Thread ThreadObj;
}

+ 41
- 0
app/src/main/java/com/jdzh/jdzhandroid/Trig/RTrig.java View File

@@ -0,0 +1,41 @@
package com.jdzh.jdzhandroid.Trig;
import com.jdzh.jdzhandroid.Interface.IRun;

import java.util.concurrent.ConcurrentHashMap;

/**
* 上升沿操作
*/
public class RTrig {
private static volatile ConcurrentHashMap<String, RTrig> _Instance;

public static RTrig get(String name) {
if (_Instance == null)
_Instance = new ConcurrentHashMap<String, RTrig>();
if (!_Instance.containsKey(name))
_Instance.put(name, new RTrig());
return _Instance.get(name);
}

private RTrig() {
}

private boolean flag=false;
private boolean Q=false;

public boolean getQ() {
return Q;
}

private void setIN(boolean falag) {
Q = falag && !flag;
flag = falag;
}

public void Start(boolean IN, IRun callback) {
setIN(IN);
if (Q)
callback.Run();
}

}

+ 19
- 0
app/src/main/res/layout/activity_main.xml View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

+ 3
- 0
app/src/main/res/values-night/themes.xml View File

@@ -0,0 +1,3 @@
<resources >

</resources>

+ 5
- 0
app/src/main/res/values/colors.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

+ 3
- 0
app/src/main/res/values/strings.xml View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">JDZHAndroid</string>
</resources>

+ 3
- 0
app/src/main/res/values/themes.xml View File

@@ -0,0 +1,3 @@
<resources xmlns:tools="http://schemas.android.com/tools">

</resources>

+ 13
- 0
app/src/main/res/xml/backup_rules.xml View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

+ 19
- 0
app/src/main/res/xml/data_extraction_rules.xml View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

+ 61
- 0
build.gradle View File

@@ -0,0 +1,61 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
//plugins {
// alias(libs.plugins.androidApplication) apply false
//}

//最新版的Android studio已经将配置转移到settings.gradle文件中了,要正常编译的话需要将多余的项注释掉

buildscript {
repositories {
google()
jcenter()
maven {
url "https://maven.aliyun.com/nexus/content/repositories/releases/"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
//classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}

}



allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
maven {
url "https://maven.aliyun.com/nexus/content/repositories/releases/"
}
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

ext { // 统一版本入口
//App版本号
versionCode = 101
versionName = "1.0.1"

// 支持Android版本
buildToolsVersion = "33.0.0"
minSdkVersion = 23
targetSdkVersion = 33
compileSdkVersion = 33

// 支持包
supportVersion = "28.0.0"
//butterknife = "8.8.1"
butterknife = "10.0.0"

//设置applicationId(这里很重要,两个相同applicationId的apk不同同时安装在同一台Android手机中)
applicationId= "com.bonait.yteccj"

}

+ 23
- 0
gradle.properties View File

@@ -0,0 +1,23 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

android.enableJetifier=true

+ 24
- 0
gradle/libs.versions.toml View File

@@ -0,0 +1,24 @@
[versions]
agp = "8.3.2"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
appcompat = "1.6.1"
material = "1.10.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
playServicesVisionCommon = "19.1.3"

[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
play-services-vision-common = { group = "com.google.android.gms", name = "play-services-vision-common", version.ref = "playServicesVisionCommon" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }


BIN
View File


+ 6
- 0
gradle/wrapper/gradle-wrapper.properties View File

@@ -0,0 +1,6 @@
#Thu Aug 22 15:36:42 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

+ 185
- 0
gradlew View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn () {
echo "$*"
}

die () {
echo
echo "$*"
echo
exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar


# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

JAVACMD=`cygpath --unix "$JAVACMD"`

# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option

if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi

# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

exec "$JAVACMD" "$@"

+ 89
- 0
gradlew.bat View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

+ 23
- 0
settings.gradle View File

@@ -0,0 +1,23 @@
//pluginManagement {
// repositories {
// google {
// content {
// includeGroupByRegex("com\\.android.*")
// includeGroupByRegex("com\\.google.*")
// includeGroupByRegex("androidx.*")
// }
// }
// mavenCentral()
// gradlePluginPortal()
// }
//}
//dependencyResolutionManagement {
// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
// repositories {
// google()
// mavenCentral()
// }
//}
//
rootProject.name = "JDZHAndroid"
include ':app'

Loading…
Cancel
Save