From c584c193d5dd4290bcbeddd434e1d642db59eb13 Mon Sep 17 00:00:00 2001 From: JLChen <551775569@qq.com> Date: 星期二, 09 十一月 2021 17:25:59 +0800 Subject: [PATCH] 2021-11-09 1.更新 --- HDLSDK/app/src/main/AndroidManifest.xml | 33 HDLSDK/hdl-connect/.gitignore | 1 HDLSDK/config.gradle | 7 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java | 327 +++ HDLSDK/app/src/main/res/layout/activity_main.xml | 79 HDLSDK/app/src/main/res/layout/demo_item.xml | 28 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/ClientPool.java | 57 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/HDLSdk.java | 30 HDLSDK/.idea/jarRepositories.xml | 55 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IpUtils.java | 72 HDLSDK/hdl-connect/src/androidTest/java/com/hdl/sdk/connect/ExampleInstrumentedTest.java | 26 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/ConnectStatusListener.java | 27 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/SendListener.java | 11 HDLSDK/hdl-common/src/main/AndroidManifest.xml | 5 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessageToByteEncoder.java | 24 HDLSDK/app/src/main/res/values/colors.xml | 10 HDLSDK/app/src/main/java/com/hdl/hdlsdk/App.java | 24 HDLSDK/hdl-common/consumer-rules.pro | 0 HDLSDK/hdl-socket/proguard-rules.pro | 21 HDLSDK/app/src/main/res/drawable-v24/ic_launcher_foreground.xml | 30 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleMessage.java | 10 HDLSDK/app/.gitignore | 1 HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp | 0 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IMessagePipeLine.java | 11 HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml | 5 HDLSDK/.gitignore | 15 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IdUtils.java | 12 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleFlow.java | 12 HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp | 0 HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoBean.java | 28 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketRequest.java | 34 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ProtocolParse.java | 74 HDLSDK/gradle.properties | 19 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLSocket.java | 650 +++++++ HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher.webp | 0 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ThreadToolUtils.java | 72 HDLSDK/hdl-connect/src/test/java/com/hdl/sdk/connect/ExampleUnitTest.java | 17 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyUpRequest.java | 50 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/annotation/ConnectStatus.java | 31 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java | 52 HDLSDK/app/src/main/res/values-night/themes.xml | 16 HDLSDK/hdl-connect/consumer-rules.pro | 0 HDLSDK/hdl-common/src/test/java/com/hdl/sdk/common/ExampleUnitTest.java | 17 HDLSDK/hdl-socket/consumer-rules.pro | 0 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/DeviceControlRequest.java | 51 HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoAdapter.java | 26 HDLSDK/app/src/main/res/values/themes.xml | 16 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalResponse.java | 38 HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp | 0 HDLSDK/hdl-socket/src/main/AndroidManifest.xml | 5 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/ParameterizedTypeImpl.java | 46 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/LogUtils.java | 51 HDLSDK/hdl-socket/README.md | 8 HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java | 144 + HDLSDK/hdl-common/build.gradle | 34 HDLSDK/hdl-socket/build.gradle | 33 HDLSDK/gradle/wrapper/gradle-wrapper.jar | 0 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventDispatcher.java | 132 + HDLSDK/.idea/misc.xml | 17 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java | 206 ++ HDLSDK/hdl-connect/src/main/AndroidManifest.xml | 5 HDLSDK/app/src/androidTest/java/com/hdl/hdlsdk/ExampleInstrumentedTest.java | 26 HDLSDK/hdl-socket/src/test/java/com/hdl/sdk/socket/ExampleUnitTest.java | 17 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ByteUtils.java | 134 + HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/FunctionAttributeRequest.java | 24 HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp | 0 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkResponse.java | 55 HDLSDK/.idea/gradle.xml | 24 HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp | 0 HDLSDK/build.gradle | 30 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalRequest.java | 47 HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml | 5 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java | 64 HDLSDK/hdl-socket/.gitignore | 1 HDLSDK/gradle/wrapper/gradle-wrapper.properties | 6 HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher.webp | 0 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java | 37 HDLSDK/app/src/main/res/drawable/ic_launcher_background.xml | 170 ++ .gitignore | 81 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/IHDLClient.java | 52 HDLSDK/gradlew.bat | 89 + HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java | 81 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/GsonConvert.java | 55 HDLSDK/settings.gradle | 6 HDLSDK/.idea/.gitignore | 3 HDLSDK/hdl-connect/proguard-rules.pro | 21 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java | 176 ++ HDLSDK/app/src/test/java/com/hdl/hdlsdk/ExampleUnitTest.java | 17 HDLSDK/app/src/main/res/values/strings.xml | 3 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventListener.java | 10 HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/SPUtils.java | 151 + HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/ByteToMessageDecoder.java | 20 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyReadRequest.java | 17 HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher.webp | 0 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageEncoder.java | 16 HDLSDK/.idea/compiler.xml | 6 HDLSDK/hdl-common/proguard-rules.pro | 21 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java | 130 + HDLSDK/app/build.gradle | 43 HDLSDK/gradlew | 185 ++ HDLSDK/app/proguard-rules.pro | 21 HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessagePipeLine.java | 51 HDLSDK/hdl-connect/build.gradle | 34 HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp | 0 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/GatewaySearchBean.java | 102 + HDLSDK/hdl-socket/src/androidTest/java/com/hdl/sdk/socket/ExampleInstrumentedTest.java | 26 HDLSDK/hdl-common/.gitignore | 1 HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp | 0 HDLSDK/hdl-common/src/androidTest/java/com/hdl/sdk/common/ExampleInstrumentedTest.java | 26 109 files changed, 4,887 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3a36c6e..110ac68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,15 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/android +# Edit at https://www.toptal.com/developers/gitignore?templates=android + +### Android ### # Built application files *.apk +*.aar *.ap_ +*.aab -# Files for the Dalvik VM +# Files for the ART/Dalvik VM *.dex # Java class files @@ -11,6 +18,9 @@ # Generated files bin/ gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ # Gradle files .gradle/ @@ -22,5 +32,72 @@ # Proguard folder generated by Eclipse proguard/ -#Log Files +# Log Files *.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +.idea/jarRepositories.xml +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +# Android Profiling +*.hprof + +### Android Patch ### +gen-external-apklibs +output.json + +# Replacement of .externalNativeBuild directories introduced +# with Android Studio 3.5. + +# End of https://www.toptal.com/developers/gitignore/api/android \ No newline at end of file diff --git a/HDLSDK/.gitignore b/HDLSDK/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/HDLSDK/.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 diff --git a/HDLSDK/.idea/.gitignore b/HDLSDK/.idea/.gitignore new file mode 100644 index 0000000..eaf91e2 --- /dev/null +++ b/HDLSDK/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/HDLSDK/.idea/compiler.xml b/HDLSDK/.idea/compiler.xml new file mode 100644 index 0000000..7d7ec2e --- /dev/null +++ b/HDLSDK/.idea/compiler.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CompilerConfiguration"> + <bytecodeTargetLevel target="11" /> + </component> +</project> \ No newline at end of file diff --git a/HDLSDK/.idea/gradle.xml b/HDLSDK/.idea/gradle.xml new file mode 100644 index 0000000..7e69409 --- /dev/null +++ b/HDLSDK/.idea/gradle.xml @@ -0,0 +1,24 @@ +<?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="PLATFORM" /> + <option name="distributionType" value="DEFAULT_WRAPPED" /> + <option name="externalProjectPath" value="$PROJECT_DIR$" /> + <option name="modules"> + <set> + <option value="$PROJECT_DIR$" /> + <option value="$PROJECT_DIR$/app" /> + <option value="$PROJECT_DIR$/hdl-common" /> + <option value="$PROJECT_DIR$/hdl-connect" /> + <option value="$PROJECT_DIR$/hdl-socket" /> + </set> + </option> + <option name="resolveModulePerSourceSet" value="false" /> + <option name="useQualifiedModuleNames" value="true" /> + </GradleProjectSettings> + </option> + </component> +</project> \ No newline at end of file diff --git a/HDLSDK/.idea/jarRepositories.xml b/HDLSDK/.idea/jarRepositories.xml new file mode 100644 index 0000000..fbe72e2 --- /dev/null +++ b/HDLSDK/.idea/jarRepositories.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="RemoteRepositoriesConfiguration"> + <remote-repository> + <option name="id" value="central" /> + <option name="name" value="Maven Central repository" /> + <option name="url" value="https://repo1.maven.org/maven2" /> + </remote-repository> + <remote-repository> + <option name="id" value="jboss.community" /> + <option name="name" value="JBoss Community repository" /> + <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven" /> + <option name="name" value="maven" /> + <option name="url" value="https://maven.aliyun.com/repository/central" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven2" /> + <option name="name" value="maven2" /> + <option name="url" value="https://maven.aliyun.com/repository/google" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven5" /> + <option name="name" value="maven5" /> + <option name="url" value="https://maven.aliyun.com/repository/public/" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven4" /> + <option name="name" value="maven4" /> + <option name="url" value="https://maven.aliyun.com/repository/gradle-plugin" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven3" /> + <option name="name" value="maven3" /> + <option name="url" value="https://maven.aliyun.com/repository/jcenter" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven9" /> + <option name="name" value="maven9" /> + <option name="url" value="https://jitpack.io" /> + </remote-repository> + <remote-repository> + <option name="id" value="maven8" /> + <option name="name" value="maven8" /> + <option name="url" value="https://maven.aliyun.com/repository/public" /> + </remote-repository> + <remote-repository> + <option name="id" value="Google" /> + <option name="name" value="Google" /> + <option name="url" value="https://dl.google.com/dl/android/maven2/" /> + </remote-repository> + </component> +</project> \ No newline at end of file diff --git a/HDLSDK/.idea/misc.xml b/HDLSDK/.idea/misc.xml new file mode 100644 index 0000000..2f09a86 --- /dev/null +++ b/HDLSDK/.idea/misc.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="DesignSurface"> + <option name="filePathToZoomLevelMap"> + <map> + <entry key="..\:/job/me/Android/HDLSDK/app/src/main/res/layout/activity_main.xml" value="0.1" /> + <entry key="..\:/job/me/Android/HDLSDK/app/src/main/res/layout/demo_item.xml" value="0.28958333333333336" /> + </map> + </option> + </component> + <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/build/classes" /> + </component> + <component name="ProjectType"> + <option name="id" value="Android" /> + </component> +</project> \ No newline at end of file diff --git a/HDLSDK/app/.gitignore b/HDLSDK/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/HDLSDK/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/HDLSDK/app/build.gradle b/HDLSDK/app/build.gradle new file mode 100644 index 0000000..22b041f --- /dev/null +++ b/HDLSDK/app/build.gradle @@ -0,0 +1,43 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdk 31 + + defaultConfig { + applicationId "com.hdl.hdlsdk" + minSdk 21 + targetSdk 31 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.1' + + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + + implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6' + + implementation project(path: ':hdl-connect') +} \ No newline at end of file diff --git a/HDLSDK/app/proguard-rules.pro b/HDLSDK/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/HDLSDK/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 \ No newline at end of file diff --git a/HDLSDK/app/src/androidTest/java/com/hdl/hdlsdk/ExampleInstrumentedTest.java b/HDLSDK/app/src/androidTest/java/com/hdl/hdlsdk/ExampleInstrumentedTest.java new file mode 100644 index 0000000..4f7fa58 --- /dev/null +++ b/HDLSDK/app/src/androidTest/java/com/hdl/hdlsdk/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.hdl.hdlsdk; + +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.hdl.hdlsdk", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/HDLSDK/app/src/main/AndroidManifest.xml b/HDLSDK/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c9d8256 --- /dev/null +++ b/HDLSDK/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.hdl.hdlsdk"> + + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> + <uses-permission + android:name="android.permission.WRITE_EXTERNAL_STORAGE" + tools:ignore="ScopedStorage" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + + <application + android:allowBackup="true" + android:name=".App" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/Theme.HDLSDK"> + <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> \ No newline at end of file diff --git a/HDLSDK/app/src/main/java/com/hdl/hdlsdk/App.java b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/App.java new file mode 100644 index 0000000..86fe706 --- /dev/null +++ b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/App.java @@ -0,0 +1,24 @@ +package com.hdl.hdlsdk; + +import android.app.Application; + +import com.hdl.sdk.common.HDLSdk; +import com.hdl.sdk.connect.HDLSocket; + +/** + * Created by Tong on 2021/10/8. + */ +public class App extends Application { + + @Override + public void onCreate() { + super.onCreate(); + HDLSdk.getInstance().init(this); + } + + @Override + public void onTerminate() { + super.onTerminate(); + + } +} diff --git a/HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoAdapter.java b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoAdapter.java new file mode 100644 index 0000000..18f6d76 --- /dev/null +++ b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoAdapter.java @@ -0,0 +1,26 @@ +package com.hdl.hdlsdk; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; + +import java.util.List; + +/** + * Created by Tong on 2021/10/8. + */ +public class DemoAdapter extends BaseMultiItemQuickAdapter<DemoBean, BaseViewHolder> { + + public DemoAdapter(@Nullable List<DemoBean> data) { + super(data); + addItemType(0,R.layout.demo_item); + } + + @Override + protected void convert(@NonNull BaseViewHolder baseViewHolder, DemoBean demoBean) { + baseViewHolder.setText(R.id.tv_title,demoBean.getName()); + } +} diff --git a/HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoBean.java b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoBean.java new file mode 100644 index 0000000..ad185fa --- /dev/null +++ b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/DemoBean.java @@ -0,0 +1,28 @@ +package com.hdl.hdlsdk; + +import com.chad.library.adapter.base.entity.MultiItemEntity; + +/** + * Created by Tong on 2021/10/8. + */ +public class DemoBean implements MultiItemEntity { + + private String name; + + public DemoBean(String name) { + this.name = name; + } + + @Override + public int getItemType() { + return 0; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java new file mode 100644 index 0000000..31d24e3 --- /dev/null +++ b/HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java @@ -0,0 +1,144 @@ +package com.hdl.hdlsdk; + +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.Manifest; +import android.app.Instrumentation; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.google.gson.JsonObject; +import com.hdl.sdk.common.config.TopicConstant; +import com.hdl.sdk.common.utils.IdUtils; +import com.hdl.sdk.common.utils.IpUtils; +import com.hdl.sdk.connect.HDLSocket; +import com.hdl.sdk.connect.bean.LinkRequest; +import com.hdl.sdk.connect.protocol.LinkMessageDecoder; +import com.hdl.sdk.connect.protocol.LinkMessageEncoder; +import com.hdl.sdk.socket.SocketBoot; +import com.hdl.sdk.socket.SocketOptions; +import com.hdl.sdk.socket.client.UdpClient; +import com.hdl.sdk.socket.codec.MessagePipeLine; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class MainActivity extends AppCompatActivity { + + private DemoAdapter demoAdapter; + private RecyclerView rv; + private TextView tv; + private TextView responseTv; + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + responseTv = findViewById(R.id.response_tv); + tv = findViewById(R.id.state_tv); + rv = findViewById(R.id.rv); + rv.setLayoutManager(new LinearLayoutManager(this)); + + ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() { + @Override + public void onActivityResult(Map<String, Boolean> result) { + + } + }); + + launcher.launch(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}); + + final List<DemoBean> beans = new ArrayList<>(); + beans.add(new DemoBean("鎼滅储缃戝叧")); + beans.add(new DemoBean("鑾峰彇鍔熻兘鍒楄〃")); + beans.add(new DemoBean("鍔熻兘灞炴�ц鍙�")); + beans.add(new DemoBean("璁惧鎺у埗")); + beans.add(new DemoBean("鐘舵�佷笂鎶�")); + beans.add(new DemoBean("璇诲彇鐘舵��")); + demoAdapter = new DemoAdapter(beans); + rv.setAdapter(demoAdapter); + + + final SocketOptions options = new SocketOptions(); + + MessagePipeLine pipeLine = new MessagePipeLine(); + pipeLine.add(new LinkMessageDecoder()); + pipeLine.add(new LinkMessageEncoder()); + options.setHandleMessage(pipeLine); + options.setEnabledHeartbeat(false); + + demoAdapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) { + switch (position) { + case 0: + tv.setText("鎼滅储缃戝叧涓�"); + responseTv.setText(""); + + HDLSocket.getInstance().searchGateway(new HDLSocket.CallBack() { + @Override + public void onError(String error) { + tv.setText("缃戝叧鑾峰彇澶辫触"); + } + + @Override + public void onResponse(String data) { + tv.setText("鑾峰彇缃戝叧鎴愬姛"); + responseTv.setText(data); + } + }); + + break; + case 1: + + tv.setText("鑾峰彇鍔熻兘鍒楄〃涓�"); + responseTv.setText(""); + HDLSocket.getInstance().getFunctionList(new HDLSocket.CallBack() { + @Override + public void onError(String error) { + tv.setText(error); + } + + @Override + public void onResponse(String data) { + tv.setText("鑾峰彇鍔熻兘鍒楄〃鎴愬姛"); + responseTv.setText(data); + } + }); + break; + case 2: + //鍔熻兘灞炴�ц鍙� + // HDLSocket.getInstance().getFunctionAttribute(); + + break; + case 3: + //璁惧鎺у埗 + // HDLSocket.getInstance().propertyDown(); + break; + case 4: + //鐘舵�佷笂鎶� + //HDLSocket.getInstance().propertyUp(); + break; + case 5: + //璇诲彇鐘舵�� + // HDLSocket.getInstance().propertyRead(); + break; + } + } + }); + } + +} \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/HDLSDK/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/HDLSDK/app/src/main/res/drawable-v24/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> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/drawable/ic_launcher_background.xml b/HDLSDK/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/HDLSDK/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> diff --git a/HDLSDK/app/src/main/res/layout/activity_main.xml b/HDLSDK/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..6fa6c2b --- /dev/null +++ b/HDLSDK/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,79 @@ +<?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:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".MainActivity"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/rv" + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/scrollView" + app:layout_constraintHorizontal_weight="1" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <View + android:layout_width="1dp" + android:layout_height="0dp" + android:background="#f4f4f4" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/scrollView" + app:layout_constraintStart_toEndOf="@id/rv" + app:layout_constraintTop_toTopOf="parent" /> + + <androidx.core.widget.NestedScrollView + android:id="@+id/scrollView" + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_weight="2" + app:layout_constraintStart_toEndOf="@id/rv" + app:layout_constraintTop_toTopOf="parent"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingStart="10dp" + android:text="褰撳墠鐘舵�侊細" /> + + <TextView + android:id="@+id/state_tv" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:text="鏈搷浣�" /> + + <View + android:layout_width="match_parent" + android:layout_height="2dp" + android:background="#f5f5f5" /> + + <TextView + android:paddingStart="10dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:text="鍝嶅簲锛�" /> + + <TextView + android:id="@+id/response_tv" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" /> + + + </LinearLayout> + </androidx.core.widget.NestedScrollView> + + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/layout/demo_item.xml b/HDLSDK/app/src/main/res/layout/demo_item.xml new file mode 100644 index 0000000..84a9aed --- /dev/null +++ b/HDLSDK/app/src/main/res/layout/demo_item.xml @@ -0,0 +1,28 @@ +<?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" + android:layout_width="match_parent" + android:layout_height="40dp"> + + <TextView + android:id="@+id/tv_title" + android:layout_width="0dp" + android:layout_height="0dp" + android:gravity="center" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <View + android:layout_width="0dp" + android:layout_height="1dp" + android:layout_marginStart="10dp" + android:layout_marginEnd="10dp" + android:background="#f5f5f5" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ +<?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" /> +</adaptive-icon> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ +<?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" /> +</adaptive-icon> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 --- /dev/null +++ b/HDLSDK/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp Binary files differ diff --git a/HDLSDK/app/src/main/res/values-night/themes.xml b/HDLSDK/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..ab52aa6 --- /dev/null +++ b/HDLSDK/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ +<resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Base application theme. --> + <style name="Theme.HDLSDK" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> + <!-- Primary brand color. --> + <item name="colorPrimary">@color/purple_200</item> + <item name="colorPrimaryVariant">@color/purple_700</item> + <item name="colorOnPrimary">@color/black</item> + <!-- Secondary brand color. --> + <item name="colorSecondary">@color/teal_200</item> + <item name="colorSecondaryVariant">@color/teal_200</item> + <item name="colorOnSecondary">@color/black</item> + <!-- Status bar color. --> + <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> + <!-- Customize your theme here. --> + </style> +</resources> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/values/colors.xml b/HDLSDK/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/HDLSDK/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="purple_200">#FFBB86FC</color> + <color name="purple_500">#FF6200EE</color> + <color name="purple_700">#FF3700B3</color> + <color name="teal_200">#FF03DAC5</color> + <color name="teal_700">#FF018786</color> + <color name="black">#FF000000</color> + <color name="white">#FFFFFFFF</color> +</resources> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/values/strings.xml b/HDLSDK/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..192b55f --- /dev/null +++ b/HDLSDK/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="app_name">HDLSDK</string> +</resources> \ No newline at end of file diff --git a/HDLSDK/app/src/main/res/values/themes.xml b/HDLSDK/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..dcf7fa1 --- /dev/null +++ b/HDLSDK/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ +<resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Base application theme. --> + <style name="Theme.HDLSDK" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> + <!-- Primary brand color. --> + <item name="colorPrimary">@color/purple_500</item> + <item name="colorPrimaryVariant">@color/purple_700</item> + <item name="colorOnPrimary">@color/white</item> + <!-- Secondary brand color. --> + <item name="colorSecondary">@color/teal_200</item> + <item name="colorSecondaryVariant">@color/teal_700</item> + <item name="colorOnSecondary">@color/black</item> + <!-- Status bar color. --> + <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> + <!-- Customize your theme here. --> + </style> +</resources> \ No newline at end of file diff --git a/HDLSDK/app/src/test/java/com/hdl/hdlsdk/ExampleUnitTest.java b/HDLSDK/app/src/test/java/com/hdl/hdlsdk/ExampleUnitTest.java new file mode 100644 index 0000000..eceb1d2 --- /dev/null +++ b/HDLSDK/app/src/test/java/com/hdl/hdlsdk/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.hdl.hdlsdk; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/HDLSDK/build.gradle b/HDLSDK/build.gradle new file mode 100644 index 0000000..1755efa --- /dev/null +++ b/HDLSDK/build.gradle @@ -0,0 +1,30 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply from: "config.gradle" +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath "com.android.tools.build:gradle:4.2.2" + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + + +allprojects { + repositories { + maven { url 'https://maven.aliyun.com/repository/google' } + maven { url 'https://maven.aliyun.com/repository/jcenter' } + maven { url 'https://maven.aliyun.com/repository/public' } + google() + maven { url "https://jitpack.io" } + } +} + + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/HDLSDK/config.gradle b/HDLSDK/config.gradle new file mode 100644 index 0000000..582d32b --- /dev/null +++ b/HDLSDK/config.gradle @@ -0,0 +1,7 @@ +ext { + minSdkVersion = 16 + targetSdkVersion = 31 + compileSdkVersion = 31 + versionName = "1.0.0" + +} \ No newline at end of file diff --git a/HDLSDK/gradle.properties b/HDLSDK/gradle.properties new file mode 100644 index 0000000..52f5917 --- /dev/null +++ b/HDLSDK/gradle.properties @@ -0,0 +1,19 @@ +# 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. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec: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 +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true \ No newline at end of file diff --git a/HDLSDK/gradle/wrapper/gradle-wrapper.jar b/HDLSDK/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c --- /dev/null +++ b/HDLSDK/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/HDLSDK/gradle/wrapper/gradle-wrapper.properties b/HDLSDK/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e85e154 --- /dev/null +++ b/HDLSDK/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Sep 15 00:34:41 CST 2021 +distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/HDLSDK/gradlew b/HDLSDK/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/HDLSDK/gradlew @@ -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" "$@" diff --git a/HDLSDK/gradlew.bat b/HDLSDK/gradlew.bat new file mode 100644 index 0000000..ac1b06f --- /dev/null +++ b/HDLSDK/gradlew.bat @@ -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 diff --git a/HDLSDK/hdl-common/.gitignore b/HDLSDK/hdl-common/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/HDLSDK/hdl-common/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/HDLSDK/hdl-common/build.gradle b/HDLSDK/hdl-common/build.gradle new file mode 100644 index 0000000..673c577 --- /dev/null +++ b/HDLSDK/hdl-common/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion rootProject.compileSdkVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + api 'com.google.code.gson:gson:2.8.8' + api 'androidx.annotation:annotation:1.2.0' + api 'androidx.collection:collection:1.1.0' +} \ No newline at end of file diff --git a/HDLSDK/hdl-common/consumer-rules.pro b/HDLSDK/hdl-common/consumer-rules.pro new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/HDLSDK/hdl-common/consumer-rules.pro diff --git a/HDLSDK/hdl-common/proguard-rules.pro b/HDLSDK/hdl-common/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/HDLSDK/hdl-common/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 \ No newline at end of file diff --git a/HDLSDK/hdl-common/src/androidTest/java/com/hdl/sdk/common/ExampleInstrumentedTest.java b/HDLSDK/hdl-common/src/androidTest/java/com/hdl/sdk/common/ExampleInstrumentedTest.java new file mode 100644 index 0000000..46d814a --- /dev/null +++ b/HDLSDK/hdl-common/src/androidTest/java/com/hdl/sdk/common/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.hdl.sdk.common; + +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.hdl.sdk.common.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/HDLSDK/hdl-common/src/main/AndroidManifest.xml b/HDLSDK/hdl-common/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ea4c4f9 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.hdl.sdk.common"> + +</manifest> \ No newline at end of file diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/HDLSdk.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/HDLSdk.java new file mode 100644 index 0000000..120fc9d --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/HDLSdk.java @@ -0,0 +1,30 @@ +package com.hdl.sdk.common; + +import android.content.Context; + +/** + * Created by Tong on 2021/9/28. + */ +public class HDLSdk { + + private Context context; + + private HDLSdk() { + } + + private static class SingletonInstance { + private static final HDLSdk INSTANCE = new HDLSdk(); + } + + public static HDLSdk getInstance() { + return SingletonInstance.INSTANCE; + } + + public void init(Context context) { + this.context = context.getApplicationContext(); + } + + public Context getContext() { + return context; + } +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/IHDLClient.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/IHDLClient.java new file mode 100644 index 0000000..5c6007f --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/IHDLClient.java @@ -0,0 +1,52 @@ +package com.hdl.sdk.common; + +/** + * Created by Tong on 2021/9/28. + * 鍖呭惈鎵�鏈夋搷浣� + */ +public interface IHDLClient { + + + /** + * 鎼滅储缃戝叧 + */ + void searchGateway(); + + + /** + * 鑾峰彇缃戝叧璇︾粏淇℃伅 + */ + void getGatewayInfo(); + + /** + * 鑾峰彇璁惧鍒楄〃 + */ + void getDeviceList(); + + /** + * 鑾峰彇鍔熻兘鍒楄〃 + */ + void getFunctionList(); + + /** + * 鑾峰彇鍔熻兘灞炴�� + */ + void getFunctionAttribute(); + + /** + * 璁惧鎺у埗 + */ + void deviceControl(); + + /** + * 鑾峰彇璁惧鐘舵�� + */ + void getDeviceStatus(); + + /** + * 鏀瑰彉璁惧鐘舵�� + */ + void changeDeviceStatus(); + + +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java new file mode 100644 index 0000000..ace530f --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java @@ -0,0 +1,52 @@ +package com.hdl.sdk.common.config; + +/** + * Created by Tong on 2021/9/22. + */ +public class TopicConstant { + + //鎼滅储缃戝叧 + public static final String GATEWAY_SEARCH = "/user/all/custom/gateway/search"; + + //鎼滅储缃戝叧鍝嶅簲 + public static final String GATEWAY_SEARCH_REPLY = "/user/all/custom/gateway/search_reply"; + + //缃戝叧璇︾粏淇℃伅鑾峰彇s=gw_id + public static final String GATEWAY_INFO = "/user/%s/custom/gateway/get"; + + //鑾峰彇鐗╃悊璁惧鍒楄〃 + public static final String GET_DEVICE_LIST = " /user/%s/custom/device/list/get"; + + //鑾峰彇鐗╃悊璁惧鍒楄〃鍝嶅簲 + public static final String GET_DEVICE_LIST_REPLY = " /user/%s/custom/device/list/get_reply"; + + //鑾峰彇鍔熻兘鍒楄〃 + public static final String GET_FUNCTION_LIST = "/user/%s/custom/function/list/get"; + + //鑾峰彇鍔熻兘鍝嶅簲 + public static final String GET_FUNCTION_LIST_REPLY = "/user/%s/custom/function/list/get_reply"; + + //鍔熻兘灞炴�ц鍙� + public static final String GET_FUNCTION_ATTRIBUTE = "/user/%s/custom/function/attribute/get"; + + //鍔熻兘灞炴�у搷搴� + public static final String GET_FUNCTION_ATTRIBUTE_REPLY = "/user/%s/custom/function/attribute/get_reply"; + + //鎺у埗 + public static final String PROPERTY_DOWN = "/base/%s/thing/property/down"; + + //鎺у埗鍝嶅簲 + public static final String PROPERTY_DOWN_REPLY = "/base/%s/thing/property/down_reply"; + + //鐘舵�佷笂鎶� + public static final String PROPERTY_UP = "/base/%s/thing/property/up"; + + //鐘舵�佷笂鎶ュ搷搴� + public static final String PROPERTY_UP_REPLY = "/base/%s/thing/property/up_reply"; + + //璇诲彇鐘舵�� + public static final String PROPERTY_READ = "/base/%s/thing/property/read"; + + //璇诲彇鐘舵�佸搷搴� + public static final String PROPERTY_READ_REPLY = "/base/%s/thing/property/read_reply"; +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventDispatcher.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventDispatcher.java new file mode 100644 index 0000000..b17b3a8 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventDispatcher.java @@ -0,0 +1,132 @@ +package com.hdl.sdk.common.event; + +import androidx.annotation.NonNull; +import androidx.collection.ArrayMap; + + +import com.hdl.sdk.common.utils.ThreadToolUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ExecutorService; + + +/** + * Created by Tong on 2021/9/22. + * 浜嬩欢鍒嗗彂 + */ +public class EventDispatcher { + + private static final ArrayMap<Object, List<EventListener>> EVENT = new ArrayMap<>(); + + private static final ArrayMap<EventListener, Integer> TYPE = new ArrayMap<>(); + + private static final int MAIN_TYPE = 0; + private static final int IO_TYPE = 1; + + private static final ExecutorService ioThread = ThreadToolUtils.getInstance().newFixedThreadPool(2); + + private EventDispatcher() { + } + + private static class SingletonInstance { + private static final EventDispatcher INSTANCE = new EventDispatcher(); + } + + public static EventDispatcher getInstance() { + return SingletonInstance.INSTANCE; + } + + public synchronized void register(Object tag, EventListener listener) { + if (!EVENT.containsKey(tag)) { + EVENT.put(tag, new ArrayList<>()); + } + List<EventListener> events = EVENT.get(tag); + if (events != null && !events.contains(listener)) { + events.add(listener); + } + TYPE.put(listener, MAIN_TYPE); + } + + public synchronized void registerIo(Object tag, EventListener listener) { + if (!EVENT.containsKey(tag)) { + EVENT.put(tag, new ArrayList<>()); + } + List<EventListener> events = EVENT.get(tag); + if (events != null && !events.contains(listener)) { + events.add(listener); + } + TYPE.put(listener, IO_TYPE); + } + + public synchronized void remove(Object tag) { + ioThread.execute(new Runnable() { + @Override + public void run() { + try { + if (EVENT.containsKey(tag)) { + List<EventListener> list = EVENT.get(tag); + for (EventListener eventListener : list) { + TYPE.remove(eventListener); + } + EVENT.remove(tag); + } + } catch (Exception ignored) { + + } + + } + }); + } + + public synchronized void remove(Object tag, EventListener listener) { + ioThread.execute(new Runnable() { + @Override + public void run() { + try { + if (EVENT.containsKey(tag)) { + List<EventListener> ev = EVENT.get(tag); + if (ev != null && !ev.isEmpty()) { + TYPE.remove(listener); + ev.remove(listener); + } + } + } catch (Exception ignored) { + + } + + } + }); + } + + public synchronized void post(Object tag, @NonNull Object o) { + if (EVENT.containsKey(tag)) { + List<EventListener> list = EVENT.get(tag); + if (list != null && !list.isEmpty()) { + for (EventListener listener : list) { + ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { + @Override + public void run() { + if (listener != null) { + listener.onMessage(o); + } + } + }); + } + } + } + } + + public synchronized void clear() { + EVENT.clear(); + TYPE.clear(); + } + + public synchronized void release() { + clear(); + ioThread.shutdownNow(); + } + + +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventListener.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventListener.java new file mode 100644 index 0000000..eb82740 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/event/EventListener.java @@ -0,0 +1,10 @@ +package com.hdl.sdk.common.event; + +/** + * Created by Tong on 2021/9/22. + */ +public interface EventListener { + + void onMessage(Object msg); + +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ByteUtils.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ByteUtils.java new file mode 100644 index 0000000..ff641db --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ByteUtils.java @@ -0,0 +1,134 @@ +package com.hdl.sdk.common.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by Tong on 2021/9/23. + */ +public class ByteUtils { + + public static byte[] toByteArray(List<Byte> list) { + Byte[] temps = list.toArray(new Byte[0]); + byte[] result = new byte[temps.length]; + for (int i = 0; i < result.length; i++) { + result[i] = temps[i]; + } + return result; + + } + + public static List<Byte> toByteList(byte[] bytes) { + final List<Byte> list = new ArrayList<>(); + for (byte aByte : bytes) { + list.add(aByte); + } + return list; + + } + + public static byte[] getRangeBytes(List<Byte> list, int start, int end) { + Byte[] temps = Arrays.copyOfRange(list.toArray(new Byte[0]), start, end); + byte[] result = new byte[temps.length]; + for (int i = 0; i < temps.length; i++) { + result[i] = temps[i]; + } + return result; + + } + + /** + * 鎷兼帴byte + */ + public static byte[] concatBytes(byte[] bt1, byte[] bt2) { + if (bt1 == null) { + return bt2; + } + if (bt2 == null) { + return bt1; + } + byte[] bt3 = new byte[bt1.length + bt2.length]; + System.arraycopy(bt1, 0, bt3, 0, bt1.length); + System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length); + return bt3; + } + + + public boolean endWith(Byte[] src, byte[] target) { + if (src.length < target.length) { + return false; + } + for (int i = 0; i < target.length; i++) { + if (target[target.length - i - 1] != src[src.length - i - 1]) { + return false; + } + } + return true; + } + + + public static int byteIndexOf(byte[] searched, byte[] find, int start) { + boolean matched; + int end = find.length - 1; + int skip = 0; + for (int index = start; index <= searched.length - find.length; ++index) { + matched = true; + if (find[0] != searched[index] || find[end] != searched[index + end]) continue; + else skip++; + if (end > 10) + if (find[skip] != searched[index + skip] || find[end - skip] != searched[index + end - skip]) + continue; + else skip++; + for (int subIndex = skip; subIndex < find.length - skip; ++subIndex) { + if (find[subIndex] != searched[index + subIndex]) { + matched = false; + break; + } + } + if (matched) { + return index; + } + } + return -1; + + } + + public static int getByteIndexOf(byte[] sources, byte[] src) { + return getByteIndexOf(sources, src, 0, sources.length); + } + + //鍒ゆ柇涓�涓猙yte鏁板�煎湪鍙﹀涓�涓猙yte鏁扮粍涓搴旂殑娓告爣鍊� + public static int getByteIndexOf(byte[] sources, byte[] src, int startIndex) { + return getByteIndexOf(sources, src, startIndex, sources.length); + } + + + //鍒ゆ柇涓�涓猙yte鏁板�煎湪鍙﹀涓�涓猙yte鏁扮粍涓搴旂殑娓告爣鍊硷紝鎸囧畾寮�濮嬬殑娓告爣鍜岀粨鏉熺殑娓告爣浣嶇疆 + public static int getByteIndexOf(byte[] sources, byte[] src, int startIndex, int endIndex) { + + if (sources == null || src == null || sources.length == 0 || src.length == 0) { + return -1; + } + + if (endIndex > sources.length) { + endIndex = sources.length; + } + + int i, j; + for (i = startIndex; i < endIndex; i++) { + if (sources[i] == src[0] && i + src.length < endIndex) { + for (j = 1; j < src.length; j++) { + if (sources[i + j] != src[j]) { + break; + } + } + + if (j == src.length) { + return i; + } + } + } + return -1; + } +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IdUtils.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IdUtils.java new file mode 100644 index 0000000..97181a7 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IdUtils.java @@ -0,0 +1,12 @@ +package com.hdl.sdk.common.utils; + +import java.util.UUID; + +/** + * Created by Tong on 2021/10/8. + */ +public class IdUtils { + public static String getUUId() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IpUtils.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IpUtils.java new file mode 100644 index 0000000..f35cfb9 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/IpUtils.java @@ -0,0 +1,72 @@ +package com.hdl.sdk.common.utils; + +import android.content.Context; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; + +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + +/** + * Created by Tong on 2021/9/27. + */ +public class IpUtils { + + /** + * @return 骞挎挱鍦板潃 + */ + public static String getBroadcastAddress() { + try { + for (Enumeration<NetworkInterface> niEnum = NetworkInterface.getNetworkInterfaces(); + niEnum.hasMoreElements(); ) { + NetworkInterface ni = niEnum.nextElement(); + if (!ni.isLoopback()) { + for (InterfaceAddress interfaceAddress : ni.getInterfaceAddresses()) { + if (interfaceAddress.getBroadcast() != null) { + return interfaceAddress.getBroadcast().toString().substring(1); + } + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + return "255.255.255.255"; + } + + public static String getIP(Context application) { + WifiManager wifiManager = (WifiManager) application.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + if (!wifiManager.isWifiEnabled()) { + try { + for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { + NetworkInterface intf = en.nextElement(); + for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress()) { + return inetAddress.getHostAddress(); + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + } else { + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + int ipAddress = wifiInfo.getIpAddress(); + return intToIp(ipAddress); + } + return null; + } + + + private static String intToIp(int i) { + + return (i & 0xFF) + "." + + ((i >> 8) & 0xFF) + "." + + ((i >> 16) & 0xFF) + "." + + (i >> 24 & 0xFF); + } +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/LogUtils.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/LogUtils.java new file mode 100644 index 0000000..22ab283 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/LogUtils.java @@ -0,0 +1,51 @@ +package com.hdl.sdk.common.utils; + +/** + * Created by Tong on 2021/9/23. + */ +public class LogUtils { + + private static final String TAG = "HDLSocket"; + + private boolean isEnabled = true; + + + private LogUtils() { + } + + private static class SingletonInstance { + private static final LogUtils INSTANCE = new LogUtils(); + } + + public static LogUtils getInstance() { + return SingletonInstance.INSTANCE; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean enabled) { + isEnabled = enabled; + } + + public static void d(String tag, String msg) { + + } + + public static void e(String tag, String msg) { + + } + + public static void w(String tag, String msg) { + + } + + public static void v(String tag, String msg) { + + } + + public static void i(String tag, String msg) { + + } +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/SPUtils.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/SPUtils.java new file mode 100644 index 0000000..bbdd808 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/SPUtils.java @@ -0,0 +1,151 @@ +package com.hdl.sdk.common.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; + +import com.hdl.sdk.common.HDLSdk; + + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * Created by Tong on 2021/9/28. + */ +public class SPUtils { + private static final String APP_PREFERENCES_KEY = "profile"; + private static final SharedPreferences PREFERENCES = + HDLSdk.getInstance().getContext().getApplicationContext().getSharedPreferences(APP_PREFERENCES_KEY, Context.MODE_PRIVATE); + + private static SharedPreferences getAppPreference() { + return PREFERENCES; + } + + + //======閫氱敤瀛樺偍======== + public static void put(@NonNull final String key, final String value) { + getAppPreference().edit().putString(key, value).apply(); + } + + + public static String getString(@NonNull final String key) { + return getString(key, ""); + } + + + public static String getString(@NonNull final String key, final String defaultValue) { + return getAppPreference().getString(key, defaultValue); + } + + + public static void put(@NonNull final String key, final int value) { + put(key, value, false); + } + + + public static void put(@NonNull final String key, final int value, final boolean isCommit) { + getAppPreference().edit().putInt(key, value).apply(); + } + + + public static int getInt(@NonNull final String key) { + return getInt(key, -1); + } + + + public static int getInt(@NonNull final String key, final int defaultValue) { + return getAppPreference().getInt(key, defaultValue); + } + + + public static void put(@NonNull final String key, final long value) { + getAppPreference().edit().putLong(key, value).apply(); + } + + + public static long getLong(@NonNull final String key) { + return getLong(key, -1L); + } + + + public static long getLong(@NonNull final String key, final long defaultValue) { + return getAppPreference().getLong(key, defaultValue); + } + + + public static void put(@NonNull final String key, final float value) { + getAppPreference().edit().putFloat(key, value).apply(); + } + + + public static float getFloat(@NonNull final String key) { + return getFloat(key, -1f); + } + + + public static float getFloat(@NonNull final String key, final float defaultValue) { + return getAppPreference().getFloat(key, defaultValue); + } + + + public static void put(@NonNull final String key, final boolean value) { + getAppPreference().edit().putBoolean(key, value).apply(); + } + + + public static boolean getBoolean(@NonNull final String key) { + return getBoolean(key, false); + } + + + public static boolean getBoolean(@NonNull final String key, final boolean defaultValue) { + return getAppPreference().getBoolean(key, defaultValue); + } + + + public static void put(@NonNull final String key, + final Set<String> value + ) { + + getAppPreference().edit().putStringSet(key, value).apply(); + + } + + + public static Set<String> getStringSet(@NonNull final String key) { + return getStringSet(key, Collections.<String>emptySet()); + } + + + public static Set<String> getStringSet(@NonNull final String key, + final Set<String> defaultValue) { + return getAppPreference().getStringSet(key, defaultValue); + } + + + public static Map<String, ?> getAll() { + return getAppPreference().getAll(); + } + + + public static boolean contains(@NonNull final String key) { + return getAppPreference().contains(key); + } + + + public static void remove(@NonNull final String key) { + getAppPreference().edit().remove(key).apply(); + } + + public static void clear() { + getAppPreference() + .edit() + .clear() + .apply(); + } + + +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ThreadToolUtils.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ThreadToolUtils.java new file mode 100644 index 0000000..d42da84 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/ThreadToolUtils.java @@ -0,0 +1,72 @@ +package com.hdl.sdk.common.utils; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +/** + * Created by Tong on 2021/9/15. + */ +public class ThreadToolUtils { + + private final Handler uiHandler = new Handler(Looper.getMainLooper()); + + //cpu 鏈�澶х嚎绋嬪绾抽噺 + private final int coreSize = Runtime.getRuntime().availableProcessors() + 1; + + private ThreadToolUtils() { + } + + private static class SingletonInstance { + private static final ThreadToolUtils INSTANCE = new ThreadToolUtils(); + } + + public static ThreadToolUtils getInstance() { + return SingletonInstance.INSTANCE; + } + + + /** + * 绾跨▼鏁伴噺鍥哄畾鐨勭嚎绋嬫睜 + */ + public ExecutorService newFixedThreadPool(int size) { + if (size == 0 || coreSize < size) { + return Executors.newFixedThreadPool(coreSize); + } + return Executors.newFixedThreadPool(size); + } + + /** + * 瀹氭椂浠诲姟绾跨▼姹� + */ + public ScheduledExecutorService newScheduledThreadPool(int size) { + if (size == 0 || coreSize < size) { + return Executors.newScheduledThreadPool(coreSize); + } + return Executors.newScheduledThreadPool(size); + } + + /** + * 鍗曚竴绾跨▼ + */ + public ExecutorService newSingleThreadPool() { + return Executors.newSingleThreadExecutor(); + } + + + public ExecutorService newCachedThreadPool() { + return Executors.newCachedThreadPool(); + } + + /** + * 鍒囨崲鍥炰富绾跨▼ + */ + public void runOnUiThread(Runnable run) { + uiHandler.post(run); + } + + +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/GsonConvert.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/GsonConvert.java new file mode 100644 index 0000000..f38cfa9 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/GsonConvert.java @@ -0,0 +1,55 @@ +package com.hdl.sdk.common.utils.gson; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +/** + * Created by Tong on 2021/9/8. + */ +public class GsonConvert { + + private static Gson gson = null; + + public static Gson getGson() { + if (gson == null) { + synchronized (GsonConvert.class) { + if (gson == null) { + gson = new GsonBuilder() + .setPrettyPrinting() + .disableHtmlEscaping() + .registerTypeAdapter(String.class, new StringTypeAdapter()) + .create(); + } + } + } + return gson; + } + + private static class StringTypeAdapter implements JsonSerializer<String>, JsonDeserializer<String> { + @Override + public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + if (json instanceof JsonPrimitive) { + return json.getAsString(); + } else { + return json.toString(); + } + } + + @Override + public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src); + } + } + + +} diff --git a/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/ParameterizedTypeImpl.java b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/ParameterizedTypeImpl.java new file mode 100644 index 0000000..fd122d8 --- /dev/null +++ b/HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/utils/gson/ParameterizedTypeImpl.java @@ -0,0 +1,46 @@ +package com.hdl.sdk.common.utils.gson; + + +import androidx.annotation.NonNull; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * Created by Tong on 2021/9/17. + */ +public class ParameterizedTypeImpl implements ParameterizedType { + + private final Type[] actualTypeArguments; + private final Type rawType; + private final Type ownerType; + + public ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type ownerType) { + this.ownerType = ownerType; + this.rawType = rawType; + this.actualTypeArguments = actualTypeArguments; + } + + public static Type getType(Type rawType, Type[] actualTypeArguments) { + return new ParameterizedTypeImpl(rawType, actualTypeArguments, null); + } + + @NonNull + @Override + public Type[] getActualTypeArguments() { + return actualTypeArguments; + } + + + @NonNull + @Override + public Type getRawType() { + return rawType; + } + + + @Override + public Type getOwnerType() { + return ownerType; + } +} diff --git a/HDLSDK/hdl-common/src/test/java/com/hdl/sdk/common/ExampleUnitTest.java b/HDLSDK/hdl-common/src/test/java/com/hdl/sdk/common/ExampleUnitTest.java new file mode 100644 index 0000000..6e8323f --- /dev/null +++ b/HDLSDK/hdl-common/src/test/java/com/hdl/sdk/common/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.hdl.sdk.common; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/HDLSDK/hdl-connect/.gitignore b/HDLSDK/hdl-connect/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/HDLSDK/hdl-connect/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/HDLSDK/hdl-connect/build.gradle b/HDLSDK/hdl-connect/build.gradle new file mode 100644 index 0000000..74a62e0 --- /dev/null +++ b/HDLSDK/hdl-connect/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion rootProject.compileSdkVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + api project(path: ':hdl-socket') + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' +} \ No newline at end of file diff --git a/HDLSDK/hdl-connect/consumer-rules.pro b/HDLSDK/hdl-connect/consumer-rules.pro new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/HDLSDK/hdl-connect/consumer-rules.pro diff --git a/HDLSDK/hdl-connect/proguard-rules.pro b/HDLSDK/hdl-connect/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/HDLSDK/hdl-connect/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 \ No newline at end of file diff --git a/HDLSDK/hdl-connect/src/androidTest/java/com/hdl/sdk/connect/ExampleInstrumentedTest.java b/HDLSDK/hdl-connect/src/androidTest/java/com/hdl/sdk/connect/ExampleInstrumentedTest.java new file mode 100644 index 0000000..32322d2 --- /dev/null +++ b/HDLSDK/hdl-connect/src/androidTest/java/com/hdl/sdk/connect/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.hdl.sdk.connect; + +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.hdl.sdk.connect.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/HDLSDK/hdl-connect/src/main/AndroidManifest.xml b/HDLSDK/hdl-connect/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c3b028e --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.hdl.sdk.connect"> + +</manifest> \ No newline at end of file diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLSocket.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLSocket.java new file mode 100644 index 0000000..00cb3a2 --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLSocket.java @@ -0,0 +1,650 @@ +package com.hdl.sdk.connect; + +import android.text.TextUtils; +import android.util.ArrayMap; +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.hdl.sdk.common.config.TopicConstant; +import com.hdl.sdk.common.event.EventDispatcher; +import com.hdl.sdk.common.event.EventListener; +import com.hdl.sdk.common.utils.IdUtils; +import com.hdl.sdk.common.utils.IpUtils; +import com.hdl.sdk.common.utils.SPUtils; +import com.hdl.sdk.common.utils.ThreadToolUtils; +import com.hdl.sdk.common.utils.gson.GsonConvert; +import com.hdl.sdk.connect.bean.BaseLocalRequest; +import com.hdl.sdk.connect.bean.BaseLocalResponse; +import com.hdl.sdk.connect.bean.DeviceControlRequest; +import com.hdl.sdk.connect.bean.FunctionAttributeRequest; +import com.hdl.sdk.connect.bean.GatewaySearchBean; +import com.hdl.sdk.connect.bean.LinkRequest; +import com.hdl.sdk.connect.bean.LinkResponse; +import com.hdl.sdk.connect.bean.PropertyReadRequest; +import com.hdl.sdk.connect.bean.PropertyUpRequest; +import com.hdl.sdk.connect.protocol.LinkMessageDecoder; +import com.hdl.sdk.connect.protocol.LinkMessageEncoder; +import com.hdl.sdk.socket.SocketBoot; +import com.hdl.sdk.socket.SocketOptions; +import com.hdl.sdk.socket.client.TcpClient; +import com.hdl.sdk.socket.client.UdpClient; +import com.hdl.sdk.socket.codec.MessagePipeLine; +import com.hdl.sdk.socket.listener.ConnectStatusListener; +import com.hdl.sdk.socket.listener.SendListener; + +import java.io.UnsupportedEncodingException; +import java.lang.reflect.ParameterizedType; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Tong on 2021/9/26. + * 1銆侀�氳繃Udp 缁勬挱鎴栬�呭箍鎾悳绱㈢綉鍏� + * 2銆侀�氳繃Udp 鑾峰彇Tcp ip 绔彛缁熶竴8586 + */ +public class HDLSocket { + + private static final String GATEWAY_KEY = "gateway_key"; + private static final String TCP_IP_KEY = "tcp_ip_key"; + private String gatewayId; + + public interface CallBack { + + void onError(String error); + + void onResponse(String data); + + } + + /** + * udp榛樿缁勬挱ip + */ + private static final String UDP_GROUP_IP = "239.0.168.188"; + + /** + * udp榛樿绔彛 + */ + private static final int UDP_PORT = 8585; + + /** + * tcp榛樿绔彛 + */ + private static final int TCP_PORT = 8586; + + private String tcpIp; + private int tcpPort; + + private int udpPort; + private String udpIp; + + private static SocketBoot updBoot; + private SocketBoot tcpBoot; + + private ConnectStatusListener statusListener; + + private EventListener searchEvent; + private CallBack searchCallBack; + private ScheduledExecutorService searchGatewayThread; + private final AtomicInteger searchCount = new AtomicInteger(0); + + private HDLSocket() { + statusListener = new ConnectStatusListener() { + @Override + public void onConnecting() { + + } + + @Override + public void onConnected() { + + } + + @Override + public void onConnectFailed() { + + } + }; + searchEvent = new EventListener() { + @Override + public void onMessage(Object msg) { + try { + if (msg instanceof LinkResponse) { + LinkResponse linkResponse = (LinkResponse) msg; + String data = linkResponse.getData(); + if (!TextUtils.isEmpty(data)) { + final BaseLocalResponse<GatewaySearchBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() { + }.getType()); + GatewaySearchBean searchBean = response.getObjects(); + if (searchBean != null) { + gatewayId = searchBean.getGatewayId(); + if (!TextUtils.isEmpty(gatewayId)) { + SPUtils.put(GATEWAY_KEY, gatewayId); + } + tcpIp = searchBean.getIp_address(); + if (!TextUtils.isEmpty(tcpIp)) { + SPUtils.put(TCP_IP_KEY, tcpIp); + } + } + + if (searchCallBack != null) { + searchCallBack.onResponse(linkResponse.toString()); + } + } + + } + } catch (Exception e) { + if (searchCallBack != null) { + searchCallBack.onError("瑙f瀽澶辫触"); + } + } + + + } + }; + } + + private static class SingletonInstance { + private static final HDLSocket INSTANCE = new HDLSocket(); + } + + public static HDLSocket getInstance() { + return SingletonInstance.INSTANCE; + } + + + private SocketOptions getUdpOptions() { + final SocketOptions options = new SocketOptions(); + final MessagePipeLine pipeLine = new MessagePipeLine(); + pipeLine.add(new LinkMessageDecoder()); + pipeLine.add(new LinkMessageEncoder()); + options.setHandleMessage(pipeLine); + options.setEnabledHeartbeat(false); + return options; + } + + private SocketOptions getTcpOptions() { + final SocketOptions options = new SocketOptions(); + final MessagePipeLine pipeLine = new MessagePipeLine(); + pipeLine.add(new LinkMessageDecoder()); + pipeLine.add(new LinkMessageEncoder()); + options.setHandleMessage(pipeLine); + options.setEnabledHeartbeat(false); + return options; + } + + private int getUdpPort() { + return UDP_PORT; + } + + public int getTcpPort() { + return TCP_PORT; + } + + public String getTcpIp() { + if (!TextUtils.isEmpty(tcpIp)) { + return tcpIp; + } + return SPUtils.getString(TCP_IP_KEY, ""); + } + + public String getGatewayId() { + if (!TextUtils.isEmpty(gatewayId)) { + return gatewayId; + } + return SPUtils.getString(GATEWAY_KEY, ""); + } + + + private String getUdpIp() { + if (TextUtils.isEmpty(udpIp)) { + udpIp = UDP_GROUP_IP; + } + return udpIp; + } + + public void searchGateway() { + searchGateway(null); + } + + /** + * 缁勬挱鎼滅储 + */ + public void searchGateway(CallBack callBack) { + this.searchCallBack = callBack; + + if (searchGatewayThread != null) { + searchGatewayThread.shutdownNow(); + } + + + new Thread(new Runnable() { + @Override + public void run() { + while (TextUtils.isEmpty(gatewayId)) { + //鎼滅储缃戝叧 + searchGateway(IdUtils.getUUId(), searchEvent); + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } + + + /** + * 閫氳繃缁勬挱鎼滅储缃戝叧 + */ + public void searchGateway(String msgId, EventListener eventListener) { + searchGateway(getUdpIp(), getUdpPort(), msgId, eventListener); + } + + /** + * 閫氳繃骞挎挱鎼滅储缃戝叧 + */ + public void searchGatewayByBroadcast(String msgId, EventListener eventListener) { + searchGateway(IpUtils.getBroadcastAddress(), getUdpPort(), msgId, eventListener); + } + + /** + * 榛樿鏄粍鎾悳绱㈢綉鍏� + */ + public void searchGateway(String ip, int port, String msgId, EventListener eventListener) { + + if (updBoot == null) { + updBoot = UdpClient.init(ip, port, getUdpOptions()); + updBoot.connect(); + } + + + String time = String.valueOf(System.currentTimeMillis()); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("id", msgId); + jsonObject.addProperty("time_stamp", time); + + EventDispatcher.getInstance().registerIo(TopicConstant.GATEWAY_SEARCH_REPLY, eventListener); + LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH, + jsonObject.toString()); + + try { + updBoot.sendMsg(message.toString().getBytes("utf-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + } + + + /** + * 鑾峰彇璁惧鍒楄〃 + */ + public void getDeviceList(CallBack callBack) { + if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) { + String time = String.valueOf(System.currentTimeMillis()); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("id", IdUtils.getUUId()); + jsonObject.addProperty("time_stamp", time); + + String topic = String.format(TopicConstant.GET_DEVICE_LIST, getGatewayId()); + + LinkRequest message = new LinkRequest(topic, + jsonObject.toString()); + + String replyTopic = String.format(TopicConstant.GET_DEVICE_LIST_REPLY, getGatewayId()); + try { + sendMsg(message.toString().getBytes("utf-8"), replyTopic, callBack, new SendListener() { + @Override + public void onSucceed() { + + } + + @Override + public void onError() { + if (callBack != null) { + callBack.onError("鑾峰彇璁惧鍒楄〃澶辫触"); + } + } + }); + } catch (UnsupportedEncodingException e) { + if (callBack != null) { + callBack.onError("鑾峰彇璁惧鍒楄〃澶辫触"); + } + } + } else { + if (callBack != null) { + callBack.onError("ip鍦板潃涓㈠け"); + } + } + } + + + /** + * 鑾峰彇鍔熻兘鍒楄〃 + */ + public void getFunctionList(CallBack callBack) { + if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) { + String time = String.valueOf(System.currentTimeMillis()); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("id", IdUtils.getUUId()); + jsonObject.addProperty("time_stamp", time); + + String topic = String.format(TopicConstant.GET_FUNCTION_LIST, getGatewayId()); + + LinkRequest message = new LinkRequest(topic, + jsonObject.toString()); + + String replyTopic = String.format(TopicConstant.GET_FUNCTION_LIST_REPLY, getGatewayId()); + try { + sendMsg(message.toString().getBytes("utf-8"), replyTopic, callBack, new SendListener() { + @Override + public void onSucceed() { + + } + + @Override + public void onError() { + if (callBack != null) { + callBack.onError("鑾峰彇鍔熻兘鍒楄〃澶辫触"); + } + } + }); + } catch (UnsupportedEncodingException e) { + if (callBack != null) { + callBack.onError("鑾峰彇鍔熻兘鍒楄〃澶辫触"); + } + } + } else { + if (callBack != null) { + callBack.onError("ip鍦板潃涓㈠け"); + } + } + } + + + /** + * 鑾峰彇鍔熻兘灞炴�� + * + * @param callBack + * @param sid + */ + public void getFunctionAttribute(CallBack callBack, String... sid) { + if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) { + String time = String.valueOf(System.currentTimeMillis()); + + final BaseLocalResponse<List<FunctionAttributeRequest>> data = new BaseLocalResponse<>(); + data.setId(IdUtils.getUUId()); + data.setTime_stamp(time); + List<FunctionAttributeRequest> list = new ArrayList<>(); + for (String s : sid) { + list.add(new FunctionAttributeRequest(s)); + } + data.setObjects(list); + + String topic = String.format(TopicConstant.GET_FUNCTION_ATTRIBUTE, getGatewayId()); + LinkRequest message = new LinkRequest(topic, + GsonConvert.getGson().toJson(data)); + + String replyTopic = String.format(TopicConstant.GET_FUNCTION_ATTRIBUTE_REPLY, getGatewayId()); + try { + sendMsg(message.toString().getBytes("utf-8"), replyTopic, callBack, new SendListener() { + @Override + public void onSucceed() { + + } + + @Override + public void onError() { + if (callBack != null) { + callBack.onError("鑾峰彇鍔熻兘灞炴�уけ璐�"); + } + } + }); + } catch (UnsupportedEncodingException e) { + if (callBack != null) { + callBack.onError("鑾峰彇鍔熻兘灞炴�уけ璐�"); + } + } + } else { + if (callBack != null) { + callBack.onError("ip鍦板潃涓㈠け"); + } + } + } + + /** + * 璁惧鎺у埗 + */ + public void propertyDown(List<DeviceControlRequest> request, CallBack callBack) { + + if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) { + String time = String.valueOf(System.currentTimeMillis()); + + final BaseLocalResponse<List<DeviceControlRequest>> data = new BaseLocalResponse<>(); + data.setId(IdUtils.getUUId()); + data.setTime_stamp(time); + data.setObjects(request); + + + String topic = String.format(TopicConstant.PROPERTY_DOWN, getGatewayId()); + LinkRequest message = new LinkRequest(topic, + GsonConvert.getGson().toJson(request)); + + String replyTopic = String.format(TopicConstant.PROPERTY_DOWN_REPLY, getGatewayId()); + try { + sendMsg(message.toString().getBytes("utf-8"), replyTopic, callBack, new SendListener() { + @Override + public void onSucceed() { + + } + + @Override + public void onError() { + if (callBack != null) { + callBack.onError("鎺у埗鎸囦护鍙戦�佸け璐�"); + } + } + }); + } catch (UnsupportedEncodingException e) { + if (callBack != null) { + callBack.onError("鎺у埗鎸囦护鍙戦�佸け璐�"); + } + } + } else { + if (callBack != null) { + callBack.onError("鎺у埗鎸囦护鍙戦�佸け璐�"); + } + } + + } + + /** + * 鐘舵�佷笂鎶� + */ + public void propertyUp(List<PropertyUpRequest> request, CallBack callBack) { + if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) { + String time = String.valueOf(System.currentTimeMillis()); + + final BaseLocalResponse<List<PropertyUpRequest>> data = new BaseLocalResponse<>(); + data.setId(IdUtils.getUUId()); + data.setTime_stamp(time); + data.setObjects(request); + + + String topic = String.format(TopicConstant.PROPERTY_UP, getGatewayId()); + LinkRequest message = new LinkRequest(topic, + GsonConvert.getGson().toJson(request)); + + String replyTopic = String.format(TopicConstant.PROPERTY_UP_REPLY, getGatewayId()); + try { + sendMsg(message.toString().getBytes("utf-8"), replyTopic, callBack, new SendListener() { + @Override + public void onSucceed() { + + } + + @Override + public void onError() { + if (callBack != null) { + callBack.onError("鎸囦护鍙戦�佸け璐�"); + } + } + }); + } catch (UnsupportedEncodingException e) { + if (callBack != null) { + callBack.onError("鎸囦护鍙戦�佸け璐�"); + } + } + } else { + if (callBack != null) { + callBack.onError("鎸囦护鍙戦�佸け璐�"); + } + } + } + + /** + * 璇诲彇鐘舵�� + */ + public void propertyRead(List<PropertyReadRequest> request, CallBack callBack) { + if (!TextUtils.isEmpty(getGatewayId()) && !TextUtils.isEmpty(getTcpIp())) { + String time = String.valueOf(System.currentTimeMillis()); + + final BaseLocalResponse<List<PropertyReadRequest>> data = new BaseLocalResponse<>(); + data.setId(IdUtils.getUUId()); + data.setTime_stamp(time); + data.setObjects(request); + + + String topic = String.format(TopicConstant.PROPERTY_READ, getGatewayId()); + LinkRequest message = new LinkRequest(topic, + GsonConvert.getGson().toJson(request)); + + String replyTopic = String.format(TopicConstant.PROPERTY_READ_REPLY, getGatewayId()); + try { + sendMsg(message.toString().getBytes("utf-8"), replyTopic, callBack, new SendListener() { + @Override + public void onSucceed() { + + } + + @Override + public void onError() { + if (callBack != null) { + callBack.onError("鎸囦护鍙戦�佸け璐�"); + } + } + }); + } catch (UnsupportedEncodingException e) { + if (callBack != null) { + callBack.onError("鎸囦护鍙戦�佸け璐�"); + } + } + } else { + if (callBack != null) { + callBack.onError("鎸囦护鍙戦�佸け璐�"); + } + } + } + + public SocketBoot getTcp() throws RuntimeException { + if (TextUtils.isEmpty(getTcpIp())) { + throw new RuntimeException("璇锋悳绱㈢綉鍏�"); + } + if (tcpBoot == null) { + tcpBoot = TcpClient.init(getTcpIp(), getTcpPort(), getTcpOptions()); + } + return tcpBoot; + } + + /** + * 娓呯┖缂撳瓨 + */ + public void clearCache() { + SPUtils.remove(TCP_IP_KEY); + SPUtils.remove(GATEWAY_KEY); + } + + + /** + * 鍙戦�佹寚浠� + * 1绉掓病鍝嶅簲灏辫浠栭噸鏂板彂閫�,閲嶈瘯3娆� + */ + public void sendMsg(byte[] data, String eventTag, CallBack callBack, SendListener sendListener) { + + try { + final AtomicInteger sendCount = new AtomicInteger(0); + + final ScheduledExecutorService threadPool = ThreadToolUtils.getInstance().newScheduledThreadPool(1); + final EventListener eventListener = new EventListener() { + @Override + public void onMessage(Object msg) { + if (msg instanceof LinkResponse) { + + if (callBack != null) { + callBack.onResponse(msg.toString()); + } + threadPool.shutdownNow(); + } + } + }; + + threadPool.scheduleWithFixedDelay(new Runnable() { + @Override + public void run() { + if (sendCount.get() < 3) { + sendCount.set(sendCount.get() + 1); + getTcp().sendMsg(data); + } else { + threadPool.shutdownNow(); + EventDispatcher.getInstance().remove(eventTag, eventListener); + ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { + @Override + public void run() { + if (callBack != null) { + callBack.onError("鍙戦�佸け璐�"); + } + } + }); + } + } + }, 1000, 500, TimeUnit.MILLISECONDS); + EventDispatcher.getInstance().register(eventTag, eventListener); + getTcp().sendMsg(data, new SendListener() { + @Override + public void onSucceed() { + if (sendListener != null) { + sendListener.onSucceed(); + } + } + + @Override + public void onError() { + if (sendListener != null) { + sendListener.onError(); + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { + @Override + public void run() { + if (callBack != null) { + callBack.onError("鍙戦�佸け璐�"); + } + } + }); + } + + } + +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalRequest.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalRequest.java new file mode 100644 index 0000000..d2ae00f --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalRequest.java @@ -0,0 +1,47 @@ +package com.hdl.sdk.connect.bean; + +import java.io.Serializable; + +/** + * Created by Tong on 2021/9/29. + */ +public class BaseLocalRequest<T> implements Serializable { + + + private String id; + private String code; + private String time_stamp; + private T objects; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getTime_stamp() { + return time_stamp; + } + + public void setTime_stamp(String time_stamp) { + this.time_stamp = time_stamp; + } + + public T getObjects() { + return objects; + } + + public void setObjects(T objects) { + this.objects = objects; + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalResponse.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalResponse.java new file mode 100644 index 0000000..0a664a2 --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/BaseLocalResponse.java @@ -0,0 +1,38 @@ +package com.hdl.sdk.connect.bean; + +import java.io.Serializable; + +/** + * Created by Tong on 2021/9/29. + */ +public class BaseLocalResponse<T> implements Serializable { + + + private String id; + private String time_stamp; + private T objects; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTime_stamp() { + return time_stamp; + } + + public void setTime_stamp(String time_stamp) { + this.time_stamp = time_stamp; + } + + public T getObjects() { + return objects; + } + + public void setObjects(T objects) { + this.objects = objects; + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/DeviceControlRequest.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/DeviceControlRequest.java new file mode 100644 index 0000000..275b7fc --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/DeviceControlRequest.java @@ -0,0 +1,51 @@ +package com.hdl.sdk.connect.bean; + +import java.io.Serializable; +import java.util.List; + +/** + * Created by Tong on 2021/10/8. + */ +public class DeviceControlRequest implements Serializable { + + private String sid; + private List<StatusBean> status; + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + + public List<StatusBean> getStatus() { + return status; + } + + public void setStatus(List<StatusBean> status) { + this.status = status; + } + + public static class StatusBean implements Serializable { + private String key; + private String value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/FunctionAttributeRequest.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/FunctionAttributeRequest.java new file mode 100644 index 0000000..03ad699 --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/FunctionAttributeRequest.java @@ -0,0 +1,24 @@ +package com.hdl.sdk.connect.bean; + +import java.io.Serializable; + +/** + * Created by Tong on 2021/10/8. + */ +public class FunctionAttributeRequest implements Serializable { + + private String sid; + + public FunctionAttributeRequest(String sid) { + this.sid = sid; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/GatewaySearchBean.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/GatewaySearchBean.java new file mode 100644 index 0000000..f3585fc --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/GatewaySearchBean.java @@ -0,0 +1,102 @@ +package com.hdl.sdk.connect.bean; + +import java.io.Serializable; + +/** + * Created by Tong on 2021/9/29. + * 缃戝叧鎼滅储 + */ +public class GatewaySearchBean implements Serializable { + + + private String device_model; + private String device_name; + private String device_mac; + private String gatewayId; + private String gatewayType; + private String gateway_type; + private String oid; + private String ip_address; + private String access_mode; + private String master; + + public String getDevice_model() { + return device_model; + } + + public void setDevice_model(String device_model) { + this.device_model = device_model; + } + + public String getDevice_name() { + return device_name; + } + + public void setDevice_name(String device_name) { + this.device_name = device_name; + } + + public String getDevice_mac() { + return device_mac; + } + + public void setDevice_mac(String device_mac) { + this.device_mac = device_mac; + } + + public String getGatewayId() { + return gatewayId; + } + + public void setGatewayId(String gatewayId) { + this.gatewayId = gatewayId; + } + + public String getGatewayType() { + return gatewayType; + } + + public void setGatewayType(String gatewayType) { + this.gatewayType = gatewayType; + } + + public String getGateway_type() { + return gateway_type; + } + + public void setGateway_type(String gateway_type) { + this.gateway_type = gateway_type; + } + + public String getOid() { + return oid; + } + + public void setOid(String oid) { + this.oid = oid; + } + + public String getIp_address() { + return ip_address; + } + + public void setIp_address(String ip_address) { + this.ip_address = ip_address; + } + + public String getAccess_mode() { + return access_mode; + } + + public void setAccess_mode(String access_mode) { + this.access_mode = access_mode; + } + + public String getMaster() { + return master; + } + + public void setMaster(String master) { + this.master = master; + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java new file mode 100644 index 0000000..3634ce4 --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkRequest.java @@ -0,0 +1,64 @@ +package com.hdl.sdk.connect.bean; + +import android.text.TextUtils; + +import androidx.annotation.NonNull; + +/** + * Created by Tong on 2021/9/29. + */ +public class LinkRequest { + private String topic; + private String data; + private int length; + + public LinkRequest() { + } + + public LinkRequest(String topic, String data) { + this.topic = topic; + setData(data); + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + if (!TextUtils.isEmpty(data)) { + setLength(data.length()); + } else { + setLength(0); + } + + } + + public int getLength() { + return length; + } + + private void setLength(int length) { + this.length = length; + } + + @NonNull + @Override + public String toString() { + return "Topic:" + + getTopic() + + "\r\n" + + "Length:" + + getLength() + + "\r\n\r\n" + + getData(); + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkResponse.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkResponse.java new file mode 100644 index 0000000..b35dcfc --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/LinkResponse.java @@ -0,0 +1,55 @@ +package com.hdl.sdk.connect.bean; + +import android.text.TextUtils; + +import androidx.annotation.NonNull; + +import com.hdl.sdk.common.utils.gson.GsonConvert; + +import java.io.Serializable; + +/** + * Created by Tong on 2021/9/27. + */ +public class LinkResponse implements Serializable { + + private String topic; + private String data; + private int length; + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + if (!TextUtils.isEmpty(data)) { + setLength(data.length()); + } else { + setLength(0); + } + + } + + public int getLength() { + return length; + } + + private void setLength(int length) { + this.length = length; + } + + @NonNull + @Override + public String toString() { + return GsonConvert.getGson().toJson(this); + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyReadRequest.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyReadRequest.java new file mode 100644 index 0000000..43ddfdb --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyReadRequest.java @@ -0,0 +1,17 @@ +package com.hdl.sdk.connect.bean; + +/** + * Created by Tong on 2021/10/8. + */ +public class PropertyReadRequest { + + private String sid; + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyUpRequest.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyUpRequest.java new file mode 100644 index 0000000..61d660c --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/PropertyUpRequest.java @@ -0,0 +1,50 @@ +package com.hdl.sdk.connect.bean; + +import java.io.Serializable; +import java.util.List; + +/** + * Created by Tong on 2021/10/8. + */ +public class PropertyUpRequest implements Serializable { + + private String sid; + private List<StatusBean> status; + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + + public List<StatusBean> getStatus() { + return status; + } + + public void setStatus(List<StatusBean> status) { + this.status = status; + } + + public static class StatusBean implements Serializable{ + private String key; + private String value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java new file mode 100644 index 0000000..26679ab --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java @@ -0,0 +1,81 @@ +package com.hdl.sdk.connect.protocol; + + +import com.hdl.sdk.common.event.EventDispatcher; +import com.hdl.sdk.common.utils.ByteUtils; +import com.hdl.sdk.connect.bean.LinkResponse; +import com.hdl.sdk.connect.utils.ProtocolParse; +import com.hdl.sdk.socket.codec.ByteToMessageDecoder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Tong on 2021/9/22. + * link鍗忚绮樺寘鎷嗗寘 + */ +public class LinkMessageDecoder extends ByteToMessageDecoder<LinkResponse> { + + private final List<Byte> bytes; + + private final byte[] head = "Topic:".getBytes(); + private final byte[] body = "\r\n\r\n".getBytes(); + + public LinkMessageDecoder() { + this.bytes = new ArrayList<>(); + } + + @Override + protected LinkResponse decoder(Object msg) throws Exception { + LinkResponse response = new LinkResponse(); + if (msg instanceof byte[]) { + //瑙f瀽娴� + byte[] data = (byte[]) msg; + bytes.addAll(ByteUtils.toByteList(data)); + + byte[] byteArray = ByteUtils.toByteArray(bytes); + int headIndex = ByteUtils.getByteIndexOf(byteArray, head); + if (headIndex > 0) { + //绉诲姩鍒癶ead 寮�濮嬩綅缃� + bytes.subList(0, headIndex).clear(); + byteArray = ByteUtils.toByteArray(bytes); + } + + int bodyIndex = ByteUtils.getByteIndexOf(byteArray, body); + if (bodyIndex < 0) { + //澶撮儴鏈幏鍙栧畬鎴� + return null; + } + int bodyStartIndex = bodyIndex + body.length; + + //瑙f瀽澶撮儴 + ProtocolParse parse = new ProtocolParse(byteArray); + response.setTopic(parse.getTopic()); + + int bodyLength = parse.getLength(); + if (bodyLength > 0) { + if (byteArray.length >= bodyLength + bodyStartIndex) { + byte[] body = ByteUtils.getRangeBytes(bytes, bodyStartIndex, bodyStartIndex + bodyLength); + response.setData(new String(body, "utf-8")); + + if (byteArray.length >= bodyLength + bodyStartIndex) { + //淇濆瓨浣欑暀 + byte[] remaining = ByteUtils.getRangeBytes(bytes, bodyStartIndex + bodyLength, byteArray.length); + bytes.clear(); + for (byte b : remaining) { + bytes.add(b); + } + } + //瑙f瀽瀹屾垚,topic鍙戦�佷竴娆� + EventDispatcher.getInstance().post(response.getTopic(), response); + return response; + } + } else if (bodyLength == 0) { + //body涓虹┖ + return response; + } + + } + return null; + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageEncoder.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageEncoder.java new file mode 100644 index 0000000..d24f715 --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageEncoder.java @@ -0,0 +1,16 @@ +package com.hdl.sdk.connect.protocol; + + +import com.hdl.sdk.socket.codec.MessageToByteEncoder; + +/** + * Created by Tong on 2021/9/22. + * link鍗忚鍚堝寘 + */ +public class LinkMessageEncoder extends MessageToByteEncoder { + + @Override + protected byte[] encode(byte[] data) throws Exception { + return data; + } +} diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ProtocolParse.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ProtocolParse.java new file mode 100644 index 0000000..d29c09d --- /dev/null +++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/utils/ProtocolParse.java @@ -0,0 +1,74 @@ +package com.hdl.sdk.connect.utils; + +import android.text.TextUtils; + +/** + * Created by Tong on 2021/9/22. + * 瑙f瀽Link鍗忚 + */ +public class ProtocolParse { + + private String topic; + private int length; + private int dataIndex; + + public ProtocolParse(byte[] bytes) { + parse(bytes); + } + + private void parse(byte[] bytes) { + try { + String[] split = new String(bytes, "utf-8").split("\r\n"); + setTopic(parseTopic(split)); + setLength(parseLength(split)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static String parseTopic(String[] bytes) { + try { + for (String s : bytes) { + if (s.startsWith("Topic:")) { + return s.replace("Topic:", ""); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private static int parseLength(String[] bytes) { + try { + for (String s : bytes) { + if (!TextUtils.isEmpty(s) && s.startsWith("Length:")) { + return Integer.parseInt(s.replace("Length:", "")); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return -1; + } + + + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + +} diff --git a/HDLSDK/hdl-connect/src/test/java/com/hdl/sdk/connect/ExampleUnitTest.java b/HDLSDK/hdl-connect/src/test/java/com/hdl/sdk/connect/ExampleUnitTest.java new file mode 100644 index 0000000..652b170 --- /dev/null +++ b/HDLSDK/hdl-connect/src/test/java/com/hdl/sdk/connect/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.hdl.sdk.connect; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/HDLSDK/hdl-socket/.gitignore b/HDLSDK/hdl-socket/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/HDLSDK/hdl-socket/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/HDLSDK/hdl-socket/README.md b/HDLSDK/hdl-socket/README.md new file mode 100644 index 0000000..40be08b --- /dev/null +++ b/HDLSDK/hdl-socket/README.md @@ -0,0 +1,8 @@ +# hdl-socket搴� + +##璇存槑 +tcp+udp 閫氱敤灏佽,瀹炵幇鍩烘湰杩炴帴 + +##鐢ㄦ硶 +1銆佸垱寤篢cp瀵硅薄 +2銆佸垱寤篣dp瀵硅薄 diff --git a/HDLSDK/hdl-socket/build.gradle b/HDLSDK/hdl-socket/build.gradle new file mode 100644 index 0000000..ecffc90 --- /dev/null +++ b/HDLSDK/hdl-socket/build.gradle @@ -0,0 +1,33 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion rootProject.compileSdkVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + api project(path: ':hdl-common') + +} \ No newline at end of file diff --git a/HDLSDK/hdl-socket/consumer-rules.pro b/HDLSDK/hdl-socket/consumer-rules.pro new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/HDLSDK/hdl-socket/consumer-rules.pro diff --git a/HDLSDK/hdl-socket/proguard-rules.pro b/HDLSDK/hdl-socket/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/HDLSDK/hdl-socket/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 \ No newline at end of file diff --git a/HDLSDK/hdl-socket/src/androidTest/java/com/hdl/sdk/socket/ExampleInstrumentedTest.java b/HDLSDK/hdl-socket/src/androidTest/java/com/hdl/sdk/socket/ExampleInstrumentedTest.java new file mode 100644 index 0000000..903bb2e --- /dev/null +++ b/HDLSDK/hdl-socket/src/androidTest/java/com/hdl/sdk/socket/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.hdl.sdk.socket; + +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.hdl.sdk.socket.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/HDLSDK/hdl-socket/src/main/AndroidManifest.xml b/HDLSDK/hdl-socket/src/main/AndroidManifest.xml new file mode 100644 index 0000000..92ea344 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.hdl.sdk.socket"> + +</manifest> \ No newline at end of file diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java new file mode 100644 index 0000000..a66c148 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java @@ -0,0 +1,327 @@ +package com.hdl.sdk.socket; + +import android.text.TextUtils; +import android.util.Log; + +import androidx.collection.ArrayMap; + +import com.hdl.sdk.common.utils.ThreadToolUtils; +import com.hdl.sdk.socket.annotation.ConnectStatus; +import com.hdl.sdk.socket.client.IClient; +import com.hdl.sdk.socket.listener.SendListener; + +import java.net.ConnectException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Tong on 2021/9/26. + * Tcp/Udp 鍚姩鍣� + */ +public class SocketBoot { + + private ExecutorService connectThread; + private ScheduledExecutorService heartbeatThread; + private ExecutorService sendThread; + private ExecutorService receiveThread; + private ScheduledExecutorService delayThread; + + private final IClient client; + + /** + * socket鏄惁鍦ㄨ繍琛� + */ + private final AtomicBoolean isRun = new AtomicBoolean(false); + + private final AtomicBoolean isOpenRetry = new AtomicBoolean(false); + + private final AtomicInteger resendCount = new AtomicInteger(0); + + private final BlockingQueue<SocketRequest> mMessageQueue = new LinkedBlockingDeque<>(); + + private final ArrayMap<String, SendListener> sendMap = new ArrayMap<>(); + + public SocketBoot(IClient client) { + this.client = client; + } + + public ScheduledExecutorService getHeartBeat() { + if (heartbeatThread == null) { + heartbeatThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1); + } + return heartbeatThread; + } + + public void connect() { + resendCount.set(0); + resetConnect(true); + isOpenRetry.set(true); + } + + public synchronized void resetConnect(boolean isFirst) { + final int maxRetry = client.getOptions().getMaxRetry(); + if (maxRetry == 0 && resendCount.get() > 0 || + (maxRetry > 0 && maxRetry + 1 < resendCount.get())) { + Log.d("====", "===閲嶈繛娆℃暟杈惧埌鏈�澶�=="); + return; + } + if (!client.isConnect()) { + if (connectThread == null) { + connectThread = ThreadToolUtils.getInstance().newFixedThreadPool(1); + } + connectThread.execute(new Runnable() { + @Override + public void run() { + client.onConnectStatus(ConnectStatus.CONNECTING); + if (!isFirst) { + try { + resendCount.set(resendCount.get() + 1); + Thread.sleep(300L); + Log.d("====", "==閲嶈繛绗�" + resendCount + "娆�=="); + } catch (Exception ignored) { + } + } + try { + client.connect(); + isRun.set(true); + if (client.isConnect()) { + Log.d("====", "====杩炴帴鎴愬姛===="); + startHeartbeat(); + + initSendThread(); + initReceiveThread(); + + client.onConnectStatus(ConnectStatus.CONNECTED); + resendCount.set(0); + } else { + throw new ConnectException(); + } + } catch (Exception e) { + e.printStackTrace(); + Log.d("====", "===杩炴帴澶辫触===" + e); + //鍐嶅垽鏂竴涓嬫湁娌℃湁杩炴帴 + if (!client.isConnect()) { + isRun.set(false); + client.onConnectStatus(ConnectStatus.DISCONNECT); + stopHeartbeat(); + disconnectError(); + } + } + } + }); + } + } + + public void initSendThread() { + if (sendThread == null) { + sendThread = ThreadToolUtils.getInstance().newFixedThreadPool(1); + } + sendThread.execute(new Runnable() { + @Override + public void run() { + while (isRun.get()) { + if (client.isConnect()) { + Log.d("=====", "==鍙戦�佹暟鎹�=="); + try { + SocketRequest socketRequest = mMessageQueue.take(); + final String action = socketRequest.getAction(); + try { + client.sendMsg(socketRequest.getData()); + if (!TextUtils.isEmpty(action)) { + SendListener sendListener = sendMap.get(action); + if (sendListener != null) { + sendListener.onSucceed(); + } + } + } catch (Exception e) { + if (!TextUtils.isEmpty(action)) { + SendListener sendListener = sendMap.get(action); + if (sendListener != null) { + sendListener.onError(); + } + } + + stopHeartbeat(); + if (sendThread != null) { + sendThread.shutdownNow(); + } + if (isRun.get()) { + disconnectError(); + } + + } + } catch (InterruptedException ignored) { + + } + + } + + } + Log.d("=====", "==鍙戦�佺嚎绋嬪叧闂�=="); + } + }); + + } + + public void initReceiveThread() { + if (receiveThread == null) { + receiveThread = ThreadToolUtils.getInstance().newFixedThreadPool(1); + } + receiveThread.execute(new Runnable() { + @Override + public void run() { + while (isRun.get()) { + if (client.isConnect()) { + try { + //璇诲彇鏁版嵁 + client.onHandleResponse(); + } catch (Exception e) { + e.printStackTrace(); + Log.d("====", "鏂紑杩炴帴" + e.getMessage()); + disconnectError(); + } + } + } + } + }); + + } + + + public void startHeartbeat() { + if (heartbeatThread != null) { + heartbeatThread.shutdownNow(); + heartbeatThread = null; + } + if (client.getOptions() == null || client.getOptions().getHeartbeatTimeInterval() <= 0 || !client.getOptions().isEnabledHeartbeat()) { + return; + } + getHeartBeat().scheduleWithFixedDelay(new Runnable() { + @Override + public void run() { + if (isRun.get()) { + Log.d("====", "===鍙戦�佸績璺冲寘==="); + if (client.getOptions() != null) { + final byte[] heartBeat = client.getOptions().getHeartbeatData(); + if (heartBeat != null) { + sendMsg(heartBeat, false, null); + } else { + sendMsg(new byte[0], false, null); + } + } + } + } + }, client.getOptions().getHeartbeatTimeInterval(), client.getOptions().getHeartbeatTimeInterval(), TimeUnit.MILLISECONDS); + } + + public void stopHeartbeat() { + if (heartbeatThread != null) { + heartbeatThread.shutdownNow(); + heartbeatThread = null; + } + } + + public void sendMsg(byte[] msg) { + sendMsg(msg, true, null); + } + + public void sendMsg(byte[] msg, SendListener listener) { + sendMsg(msg, true, listener); + } + + /** + * @param listener 涓�鑸儏鍐垫棤闇�鐩戝惉 + */ + private void sendMsg(byte[] msg, boolean isRefreshRetry, SendListener listener) { + if (isRefreshRetry) { + //閲嶇疆杩炴帴娆℃暟 + resendCount.set(0); + } + try { + SocketRequest request = new SocketRequest(msg); + if (listener != null && !TextUtils.isEmpty(request.getAction())) { + sendMap.put(request.getAction(), listener); + } + mMessageQueue.put(request); + } catch (InterruptedException ignored) { + + } + if (!client.isConnect()) { + resetConnect(false); + } + + } + + /** + * 鍙戠敓閿欒锛岄噸杩� + */ + private void disconnectError() { + disconnect(); + isRun.set(false); + if (isOpenRetry.get()) { + if (delayThread != null) { + delayThread.shutdownNow(); + } + delayThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1); + delayThread.schedule(new Runnable() { + @Override + public void run() { + if (!client.isConnect() && isOpenRetry.get()) { + resetConnect(false); + } + + } + }, 3000, TimeUnit.MILLISECONDS); + } + + } + + private synchronized void disconnect() { + if (client.isConnect()) { + client.disconnect(); + //鏂紑杩炴帴 + client.onConnectStatus(ConnectStatus.DISCONNECT); + } + } + + public synchronized void close() { + isOpenRetry.set(false); + isRun.set(false); + if (connectThread != null) { + connectThread.shutdownNow(); + connectThread = null; + } + if (heartbeatThread != null) { + heartbeatThread.shutdownNow(); + heartbeatThread = null; + } + if (sendThread != null) { + sendThread.shutdownNow(); + sendThread = null; + } + if (receiveThread != null) { + receiveThread.shutdownNow(); + receiveThread = null; + } + sendMap.clear(); + client.disconnect(); + mMessageQueue.clear(); + + } + + public synchronized void release() { + close(); + if (client != null && client.getOptions() != null) { + client.getOptions().clearConnectStatusListener(); + } + } + + public boolean isConnect() { + return client.isConnect(); + } +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java new file mode 100644 index 0000000..83a3bc5 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java @@ -0,0 +1,130 @@ +package com.hdl.sdk.socket; + + +import com.hdl.sdk.socket.codec.IHandleMessage; +import com.hdl.sdk.socket.listener.ConnectStatusListener; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Tong on 2021/9/22. + * socket閰嶇疆 + */ +public class SocketOptions { + + //璁剧疆璇诲彇缂撳瓨 + private int readMaxBufferSize = 512; + + //鍙戦�佸績璺冲寘 + private boolean isEnabledHeartbeat = true; + + //蹇冭烦鍖� + private byte[] heartbeatData; + + //蹇冭烦鍖呮椂闂撮棿闅� + private long heartbeatTimeInterval = 300L; + + //澶勭悊鏁版嵁 + private IHandleMessage handleMessage; + + //鐩戝惉鐘舵�� + private List<ConnectStatusListener> mConnectStatusListener; + + //鏈�澶ч噸杩炴鏁�,灏忎簬0鏃犻檺娆℃暟,绛変簬0涓嶉噸杩� + private int maxRetry = -1; + + private boolean isTcpNoDelay; + private boolean isReuseAddress; + //淇濇寔娲诲姩鐘舵�� + private boolean isKeepAlive; + private boolean isOOBInline; + private int sendBufferSize; + private int receiveBufferSize; + private int soTimeout; + private boolean soLinger; + + + public IHandleMessage getHandleMessage() { + return handleMessage; + } + + public void setHandleMessage(IHandleMessage handleMessage) { + this.handleMessage = handleMessage; + } + + public boolean isEnabledHeartbeat() { + return isEnabledHeartbeat; + } + + public void setEnabledHeartbeat(boolean enabledHeartbeat) { + isEnabledHeartbeat = enabledHeartbeat; + } + + public byte[] getHeartbeatData() { + return heartbeatData; + } + + public void setHeartbeatData(byte[] heartbeatData) { + this.heartbeatData = heartbeatData; + } + + public void setHeartbeatData(String heartbeatData) { + try { + this.heartbeatData = heartbeatData.getBytes("utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + public long getHeartbeatTimeInterval() { + return heartbeatTimeInterval; + } + + public void setHeartbeatTimeInterval(long heartbeatTimeInterval) { + this.heartbeatTimeInterval = heartbeatTimeInterval; + } + + public void clearConnectStatusListener() { + if (mConnectStatusListener != null && !mConnectStatusListener.isEmpty()) { + mConnectStatusListener.clear(); + } + } + + public void addConnectStatusListener(ConnectStatusListener connectStatusListener) { + if (mConnectStatusListener == null) { + mConnectStatusListener = new ArrayList<>(); + } + mConnectStatusListener.add(connectStatusListener); + } + + public void removeConnectStatusListener(ConnectStatusListener connectStatusListener) { + if (mConnectStatusListener != null) { + mConnectStatusListener.remove(connectStatusListener); + } + } + + + public List<ConnectStatusListener> getConnectStatusListener() { + return mConnectStatusListener; + } + + + public int getMaxRetry() { + return maxRetry; + } + + public void setMaxRetry(int maxRetry) { + this.maxRetry = maxRetry; + } + + public int getReadMaxBufferSize() { + return readMaxBufferSize; + } + + public void setReadMaxBufferSize(int readMaxBufferSize) { + this.readMaxBufferSize = readMaxBufferSize; + } + +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketRequest.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketRequest.java new file mode 100644 index 0000000..924719e --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketRequest.java @@ -0,0 +1,34 @@ +package com.hdl.sdk.socket; + +import java.util.UUID; + +/** + * Created by Tong on 2021/9/22. + */ +public class SocketRequest { + + private String action; + + private byte[] data; + + public SocketRequest(byte[] data) { + this.data = data; + action = UUID.randomUUID().toString(); + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/annotation/ConnectStatus.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/annotation/ConnectStatus.java new file mode 100644 index 0000000..2ec7809 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/annotation/ConnectStatus.java @@ -0,0 +1,31 @@ +package com.hdl.sdk.socket.annotation; + +import androidx.annotation.IntDef; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * Created by Tong on 2021/9/22. + */ +@Target({ElementType.TYPE_PARAMETER, ElementType.PARAMETER}) +@IntDef({ConnectStatus.CONNECTING, + ConnectStatus.CONNECTED, + ConnectStatus.DISCONNECT}) +public @interface ConnectStatus { + + /** + * 杩炴帴涓� + */ + int CONNECTING = 0; + + /** + * 杩炴帴鎴愬姛 + */ + int CONNECTED = 1; + + /** + * 杩炴帴鍏抽棴 + */ + int DISCONNECT = 2; +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/ClientPool.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/ClientPool.java new file mode 100644 index 0000000..9faeeb1 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/ClientPool.java @@ -0,0 +1,57 @@ +package com.hdl.sdk.socket.client; + +import android.net.Uri; + + +import androidx.collection.ArrayMap; + +import java.net.DatagramSocket; +import java.net.Socket; +import java.net.SocketException; + +/** + * Created by Tong on 2021/10/8. + */ +public class ClientPool { + + private final ArrayMap<String, Socket> mTcpPool = new ArrayMap<>(); + private final ArrayMap<String, DatagramSocket> mUdpPool = new ArrayMap<>(); + + private ClientPool() { + } + + private static class SingletonInstance { + private static final ClientPool INSTANCE = new ClientPool(); + } + + public static ClientPool getInstance() { + return SingletonInstance.INSTANCE; + } + + public Socket getTcpSocket(String ip, int port) { + final StringBuilder key = new StringBuilder(); + key.append(ip).append(":").append(port); + if (mTcpPool.containsKey(key)) { + Socket socket = mTcpPool.get(key); + if (socket != null && !socket.isClosed()) { + return socket; + } + + } + return new Socket(); + } + + public DatagramSocket getUdpSocket(String ip, int port) throws SocketException { + final StringBuilder key = new StringBuilder(); + key.append(ip).append(":").append(port); + if (mUdpPool.containsKey(key)) { + DatagramSocket socket = mUdpPool.get(key); + if (socket != null && !socket.isClosed()) { + return socket; + } + + } + return new DatagramSocket(port); + } + +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java new file mode 100644 index 0000000..e768514 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java @@ -0,0 +1,37 @@ +package com.hdl.sdk.socket.client; + + +import com.hdl.sdk.socket.SocketOptions; + +/** + * Created by Tong on 2021/9/22. + */ +public interface IClient { + + void connect() throws Exception; + + void disconnect(); + + /** + * 鏄惁宸茬粡杩炴帴 + */ + boolean isConnect(); + + + SocketOptions getOptions(); + + /** + * 鐩戝惉鏁版嵁 + */ + void onHandleResponse() throws Exception; + + /** + * 鍙戦�佹秷鎭� + */ + void sendMsg(byte[] msg) throws Exception; + + /** + * 杩炴帴鐘舵�� + */ + void onConnectStatus(int status); +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java new file mode 100644 index 0000000..51a03d8 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java @@ -0,0 +1,176 @@ +package com.hdl.sdk.socket.client; + + + +import com.hdl.sdk.common.utils.ThreadToolUtils; +import com.hdl.sdk.socket.SocketBoot; +import com.hdl.sdk.socket.SocketOptions; +import com.hdl.sdk.socket.annotation.ConnectStatus; +import com.hdl.sdk.socket.codec.IHandleMessage; +import com.hdl.sdk.socket.listener.ConnectStatusListener; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.List; + + +/** + * Created by Tong on 2021/9/15. + */ +public final class TcpClient implements IClient { + + private SocketOptions socketOptions; + + private final String ip; + private final int port; + + private Socket mSocket; + + private byte[] readBuffer; + + private TcpClient(String ip, int port, SocketOptions socketOptions) { + this.socketOptions = socketOptions; + this.ip = ip; + this.port = port; + } + + public static SocketBoot init(String ip, int port, SocketOptions options) { + return new SocketBoot(new TcpClient(ip, port, options)); + } + + + @Override + public void connect() throws Exception { + mSocket = getSocket(); + SocketOptions options = getOptions(); + mSocket.connect(new InetSocketAddress(ip, port)); + mSocket.setTcpNoDelay(true); + mSocket.setReuseAddress(true); + mSocket.setKeepAlive(true); + readBuffer = new byte[options.getReadMaxBufferSize()]; + } + + + @Override + public void disconnect() { + if (mSocket != null) { + try { + mSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public boolean isConnect() { + if (mSocket == null) { + return false; + } + + return mSocket.isConnected() && !mSocket.isClosed(); + } + + + @Override + public synchronized SocketOptions getOptions() { + if (socketOptions == null) { + socketOptions = new SocketOptions(); + } + return socketOptions; + } + + @Override + public void onHandleResponse() throws Exception { + final InputStream stream = getInputStream(); + + if (stream != null && getOptions() != null) { + readBuffer = new byte[1024]; + while ((getInputStream().read(readBuffer)) != -1) { + IHandleMessage handleMessage = getOptions().getHandleMessage(); + if (handleMessage != null) { + handleMessage.read(readBuffer); + } + } + } + } + + @Override + public void sendMsg(byte[] msg) throws Exception { + final OutputStream outputStream = getOutStream(); + if (outputStream != null && getOptions() != null) { + try { + IHandleMessage handleMessage = getOptions().getHandleMessage(); + handleMessage.write(handleMessage.write(msg)); + getOutStream().write(msg); + + } finally { + outputStream.flush(); + } + } + } + + + /** + * 澶勭悊杩炴帴鐘舵�� + */ + public void onConnectStatus(int status) { + ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { + @Override + public void run() { + final List<ConnectStatusListener> list = getOptions().getConnectStatusListener(); + if (list != null && !list.isEmpty()) { + for (ConnectStatusListener listener : list) { + switch (status) { + case ConnectStatus + .CONNECTING: + listener.onConnecting(); + break; + case ConnectStatus + .CONNECTED: + listener.onConnected(); + break; + case ConnectStatus + .DISCONNECT: + listener.onConnectFailed(); + break; + } + } + } + } + }); + } + + + private synchronized Socket getSocket() { + return new Socket(); + } + + private InputStream getInputStream() { + if (mSocket != null && mSocket.isConnected() && !mSocket.isClosed()) { + try { + return mSocket.getInputStream(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + + private OutputStream getOutStream() { + if (mSocket != null && mSocket.isConnected() && !mSocket.isClosed()) { + try { + return mSocket.getOutputStream(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java new file mode 100644 index 0000000..fc81bb6 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java @@ -0,0 +1,206 @@ +package com.hdl.sdk.socket.client; + + +import android.util.Log; + +import com.hdl.sdk.common.HDLSdk; +import com.hdl.sdk.common.utils.IpUtils; +import com.hdl.sdk.common.utils.ThreadToolUtils; +import com.hdl.sdk.socket.SocketBoot; +import com.hdl.sdk.socket.SocketOptions; +import com.hdl.sdk.socket.annotation.ConnectStatus; +import com.hdl.sdk.socket.codec.IHandleMessage; +import com.hdl.sdk.socket.listener.ConnectStatusListener; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + + +/** + * Created by Tong on 2021/9/15. + * 缁勬挱闇�瑕乤ndroid.permission.CHANGE_WIFI_MULTICAST_STATE鏉冮檺 + * MulticastSocket + */ +public class UdpClient implements IClient { + + private static DatagramSocket mSocket; + + private DatagramPacket receivePacket; + + private final int BUFFER = 4 * 1024; + + private final byte[] receiveByte; + + private final String ip; + + private final int port; + + private int monitorPort; + private int sendPort; + + private SocketOptions socketOptions; + + private final AtomicBoolean isConnect = new AtomicBoolean(false); + + /** + * @param sendPort -1 琛ㄧず闅忔満绔彛 + */ + private UdpClient(String ip, int port, int monitorPort, int sendPort, SocketOptions socketOptions) { + this.socketOptions = socketOptions; + this.ip = ip; + this.port = port; + this.sendPort = sendPort; + this.monitorPort = monitorPort; + this.receiveByte = new byte[BUFFER]; + } + + public UdpClient(String ip, int port) { + this.ip = ip; + this.port = port; + this.receiveByte = new byte[BUFFER]; + } + + public static SocketBoot init(String ip, int port, int monitorPort, int sendPort, SocketOptions options) { + return new SocketBoot(new UdpClient(ip, port, monitorPort, sendPort, options)); + } + + public static SocketBoot init(String ip, int port, int monitorPort, SocketOptions options) { + return init(ip, port, monitorPort, -1, options); + } + + public static SocketBoot init(String ip, int port, SocketOptions options) { + return init(ip, port, port, -1, options); + } + + @Override + public void connect() throws Exception { + + try { + mSocket = ClientPool.getInstance().getUdpSocket(ip, monitorPort); + mSocket.setBroadcast(true); + mSocket.setReuseAddress(true); + + isConnect.set(true); + if (receivePacket == null) { + receivePacket = new DatagramPacket(receiveByte, BUFFER); + } + } catch (Exception e) { + isConnect.set(false); + throw e; + } + + + } + + @Override + public void disconnect() { + if (mSocket != null) { + mSocket.close(); + } + isConnect.set(false); + } + + @Override + public boolean isConnect() { + return isConnect.get(); + } + + @Override + public synchronized SocketOptions getOptions() { + if (socketOptions == null) { + socketOptions = new SocketOptions(); + } + return socketOptions; + } + + @Override + public void onHandleResponse() throws Exception { + if (receivePacket == null || mSocket == null) { + return; + } + try { + mSocket.receive(receivePacket); + } catch (IOException e) { + e.printStackTrace(); + isConnect.set(false); + } + if (receivePacket.getLength() == 0) { + return; + } + //鎺掗櫎鑷繁鍙戝嚭鍘荤殑 + try { + if (receivePacket.getAddress().getHostAddress() + .equals(IpUtils.getIP(HDLSdk.getInstance().getContext()))) { + return; + } + } catch (Exception ignored) { + + } + + IHandleMessage handleMessage = getOptions().getHandleMessage(); + if (handleMessage != null) { + handleMessage.read(receivePacket.getData()); + } + final String receive = new String(receivePacket.getData(), 0, receivePacket.getLength()); + + Log.d("---->", receive + " from " + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort()); + + //閲嶇疆闀垮害 + if (receivePacket != null) { + receivePacket.setLength(BUFFER); + } + } + + @Override + public void sendMsg(byte[] msg) throws Exception { + if (msg == null) { + msg = new byte[1]; + } + InetAddress serverAddress = InetAddress.getByName(ip); + final DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, serverAddress, port); + if (sendPort < 0) { + final DatagramSocket sendSocket = new DatagramSocket(); + sendSocket.send(sendPacket); + sendSocket.close(); + } else if (sendPort == monitorPort) { + mSocket.send(sendPacket); + } else { + final DatagramSocket sendSocket = new DatagramSocket(sendPort); + sendSocket.send(sendPacket); + sendSocket.close(); + } + + } + + @Override + public void onConnectStatus(int status) { + ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { + @Override + public void run() { + final List<ConnectStatusListener> list = getOptions().getConnectStatusListener(); + if (list != null && !list.isEmpty()) { + for (ConnectStatusListener listener : list) { + switch (status) { + case ConnectStatus + .CONNECTING: + listener.onConnecting(); + break; + case ConnectStatus + .CONNECTED: + listener.onConnected(); + break; + case ConnectStatus + .DISCONNECT: + listener.onConnectFailed(); + break; + } + } + } + } + }); + } +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/ByteToMessageDecoder.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/ByteToMessageDecoder.java new file mode 100644 index 0000000..ec8da44 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/ByteToMessageDecoder.java @@ -0,0 +1,20 @@ +package com.hdl.sdk.socket.codec; + +/** + * Created by Tong on 2021/9/22. + */ +public abstract class ByteToMessageDecoder<T> implements IHandleFlow<T> { + + protected abstract T decoder(Object msg) + throws Exception; + + @Override + public final T read(Object data) throws Exception { + return decoder(data); + } + + @Override + public final byte[] write(byte[] data) { + return data; + } +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleFlow.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleFlow.java new file mode 100644 index 0000000..ef62efe --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleFlow.java @@ -0,0 +1,12 @@ +package com.hdl.sdk.socket.codec; + +/** + * Created by Tong on 2021/9/23. + */ +public interface IHandleFlow<T> { + + T read(Object data) throws Exception; + + byte[] write(byte[] data) throws Exception; + +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleMessage.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleMessage.java new file mode 100644 index 0000000..3234d83 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IHandleMessage.java @@ -0,0 +1,10 @@ +package com.hdl.sdk.socket.codec; + +/** + * Created by Tong on 2021/9/27. + */ +public interface IHandleMessage { + void read(byte[] data) throws Exception; + + byte[] write(byte[] data) throws Exception; +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IMessagePipeLine.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IMessagePipeLine.java new file mode 100644 index 0000000..5acb78a --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/IMessagePipeLine.java @@ -0,0 +1,11 @@ +package com.hdl.sdk.socket.codec; + +/** + * Created by Tong on 2021/9/23. + */ +public interface IMessagePipeLine { + + void add(IHandleFlow flow); + + void clear(); +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessagePipeLine.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessagePipeLine.java new file mode 100644 index 0000000..b5e8195 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessagePipeLine.java @@ -0,0 +1,51 @@ +package com.hdl.sdk.socket.codec; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Created by Tong on 2021/9/23. + */ +public class MessagePipeLine implements IMessagePipeLine, IHandleMessage { + + public final static List<IHandleFlow> queue = new ArrayList<>(); + + @Override + public void add(IHandleFlow flow) { + queue.add(flow); + } + + @Override + public synchronized void clear() { + queue.clear(); + } + + @Override + public void read(byte[] data) throws Exception { + Object out = data; + for (int i = 0; i < queue.size(); i++) { + IHandleFlow flow = queue.get(i); + Object read = flow.read(out); + try { + out = Objects.requireNonNull(read); + } catch (Exception ignored) { + } + } + } + + @Override + public byte[] write(byte[] data) throws Exception { + byte[] out = data; + for (int i = 0; i < queue.size(); i++) { + IHandleFlow flow = queue.get(i); + byte[] write = flow.write(out); + try { + out = Objects.requireNonNull(write); + } catch (Exception ignored) { + + } + } + return new byte[0]; + } +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessageToByteEncoder.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessageToByteEncoder.java new file mode 100644 index 0000000..13a8201 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/codec/MessageToByteEncoder.java @@ -0,0 +1,24 @@ +package com.hdl.sdk.socket.codec; + + +/** + * Created by Tong on 2021/9/22. + */ +public abstract class MessageToByteEncoder implements IHandleFlow { + + + protected abstract byte[] encode(byte[] data) + throws Exception; + + @Override + public final Object read(Object data) { + return data; + } + + @Override + public byte[] write(byte[] data) throws Exception { + return encode(data); + } + + +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/ConnectStatusListener.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/ConnectStatusListener.java new file mode 100644 index 0000000..17ac30f --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/ConnectStatusListener.java @@ -0,0 +1,27 @@ +package com.hdl.sdk.socket.listener; + +/** + * Created by Tong on 2021/9/22. + * 杩炴帴鐘舵�� + */ +public interface ConnectStatusListener { + + /** + * 杩炴帴涓� + */ + default void onConnecting() { + } + + /** + * 杩炴帴鎴愬姛 + */ + default void onConnected() { + } + + /** + * 杩炴帴澶辫触 + */ + default void onConnectFailed() { + } + +} diff --git a/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/SendListener.java b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/SendListener.java new file mode 100644 index 0000000..9ecb288 --- /dev/null +++ b/HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/listener/SendListener.java @@ -0,0 +1,11 @@ +package com.hdl.sdk.socket.listener; + +/** + * Created by Tong on 2021/9/22. + */ +public interface SendListener { + + void onSucceed(); + + void onError(); +} diff --git a/HDLSDK/hdl-socket/src/test/java/com/hdl/sdk/socket/ExampleUnitTest.java b/HDLSDK/hdl-socket/src/test/java/com/hdl/sdk/socket/ExampleUnitTest.java new file mode 100644 index 0000000..a59034b --- /dev/null +++ b/HDLSDK/hdl-socket/src/test/java/com/hdl/sdk/socket/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.hdl.sdk.socket; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/HDLSDK/settings.gradle b/HDLSDK/settings.gradle new file mode 100644 index 0000000..5a72944 --- /dev/null +++ b/HDLSDK/settings.gradle @@ -0,0 +1,6 @@ + +include ':app' +include ':hdl-socket' +include ':hdl-connect' +include ':hdl-common' + -- Gitblit v1.8.0