diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt index 0ef28fa..5aa28cc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt @@ -3,14 +3,14 @@ import android.app.Dialog import android.content.Context import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetAllCommandBinding -import com.casic.br.operationsite.test.extensions.convert import com.casic.br.operationsite.test.model.CommandModel -import com.casic.br.operationsite.test.util.tcp.SocketManager +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.util.LocaleConstant import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter @@ -21,7 +21,6 @@ import com.pengxh.kt.lite.extensions.getScreenHeight import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.readAssetsFile -import com.pengxh.kt.lite.extensions.show class AllCommandSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle) { @@ -31,7 +30,7 @@ private fun Dialog.resetParams() { val window = this.window ?: return - window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) window.decorView.setBackgroundColor(Color.TRANSPARENT) window.setGravity(Gravity.BOTTOM) //设置Dialog出现的动画 @@ -66,11 +65,12 @@ commandAdapter.setOnItemClickedListener(object : NormalRecyclerAdapter.OnItemClickedListener { override fun onItemClicked(position: Int, t: CommandModel) { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(context) - return + SocketConnectionService.weakReferenceHandler?.let { + val message = it.obtainMessage() + message.what = LocaleConstant.COMMAND_TEST_CODE + message.obj = t.command + it.sendMessage(message) } - SocketManager.get.send(t.command.convert()) } }) binding.sheetCancelButton.setOnClickListener { dismiss() } diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt index 0ef28fa..5aa28cc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt @@ -3,14 +3,14 @@ import android.app.Dialog import android.content.Context import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetAllCommandBinding -import com.casic.br.operationsite.test.extensions.convert import com.casic.br.operationsite.test.model.CommandModel -import com.casic.br.operationsite.test.util.tcp.SocketManager +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.util.LocaleConstant import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter @@ -21,7 +21,6 @@ import com.pengxh.kt.lite.extensions.getScreenHeight import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.readAssetsFile -import com.pengxh.kt.lite.extensions.show class AllCommandSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle) { @@ -31,7 +30,7 @@ private fun Dialog.resetParams() { val window = this.window ?: return - window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) window.decorView.setBackgroundColor(Color.TRANSPARENT) window.setGravity(Gravity.BOTTOM) //设置Dialog出现的动画 @@ -66,11 +65,12 @@ commandAdapter.setOnItemClickedListener(object : NormalRecyclerAdapter.OnItemClickedListener { override fun onItemClicked(position: Int, t: CommandModel) { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(context) - return + SocketConnectionService.weakReferenceHandler?.let { + val message = it.obtainMessage() + message.what = LocaleConstant.COMMAND_TEST_CODE + message.obj = t.command + it.sendMessage(message) } - SocketManager.get.send(t.command.convert()) } }) binding.sheetCancelButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt index db6bbcc..80ee657 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt @@ -3,42 +3,43 @@ import android.annotation.SuppressLint import android.app.Dialog import android.content.Context +import android.graphics.Color import android.os.Bundle import android.view.Gravity import android.view.MotionEvent -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner +import android.view.WindowManager +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetBottomControlBinding import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.vm.DeviceViewModel import com.pengxh.kt.lite.extensions.binding -import com.pengxh.kt.lite.extensions.resetParams +import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.utils.SaveKeyValues -class BottomControlSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle), - ViewModelStoreOwner { +class BottomControlSheet( + private val context: Context, + private val deviceViewModel: DeviceViewModel +) : Dialog(context, R.style.BottomControlSheetStyle) { private val kTag = "BottomControlSheet" private val binding: SheetBottomControlBinding by binding() - private lateinit var viewModelStore: ViewModelStore - private lateinit var deviceViewModel: DeviceViewModel private var speed = 5 - override fun getViewModelStore(): ViewModelStore { - return viewModelStore - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - viewModelStore.clear() - } - @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 1f) + val window = this.window ?: return + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.BOTTOM) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.ActionSheetDialogAnimation) + val params = window.attributes + params.width = context.getScreenWidth() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + setCancelable(true) setCanceledOnTouchOutside(true) @@ -50,9 +51,6 @@ LocaleConstant.DEVICE_CONTROL_SERVER_CONFIG, LocaleConstant.CAMERA_IP ) - viewModelStore = ViewModelStore() - deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] - binding.leftButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> executeCommand("Left") diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt index 0ef28fa..5aa28cc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt @@ -3,14 +3,14 @@ import android.app.Dialog import android.content.Context import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetAllCommandBinding -import com.casic.br.operationsite.test.extensions.convert import com.casic.br.operationsite.test.model.CommandModel -import com.casic.br.operationsite.test.util.tcp.SocketManager +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.util.LocaleConstant import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter @@ -21,7 +21,6 @@ import com.pengxh.kt.lite.extensions.getScreenHeight import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.readAssetsFile -import com.pengxh.kt.lite.extensions.show class AllCommandSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle) { @@ -31,7 +30,7 @@ private fun Dialog.resetParams() { val window = this.window ?: return - window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) window.decorView.setBackgroundColor(Color.TRANSPARENT) window.setGravity(Gravity.BOTTOM) //设置Dialog出现的动画 @@ -66,11 +65,12 @@ commandAdapter.setOnItemClickedListener(object : NormalRecyclerAdapter.OnItemClickedListener { override fun onItemClicked(position: Int, t: CommandModel) { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(context) - return + SocketConnectionService.weakReferenceHandler?.let { + val message = it.obtainMessage() + message.what = LocaleConstant.COMMAND_TEST_CODE + message.obj = t.command + it.sendMessage(message) } - SocketManager.get.send(t.command.convert()) } }) binding.sheetCancelButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt index db6bbcc..80ee657 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt @@ -3,42 +3,43 @@ import android.annotation.SuppressLint import android.app.Dialog import android.content.Context +import android.graphics.Color import android.os.Bundle import android.view.Gravity import android.view.MotionEvent -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner +import android.view.WindowManager +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetBottomControlBinding import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.vm.DeviceViewModel import com.pengxh.kt.lite.extensions.binding -import com.pengxh.kt.lite.extensions.resetParams +import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.utils.SaveKeyValues -class BottomControlSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle), - ViewModelStoreOwner { +class BottomControlSheet( + private val context: Context, + private val deviceViewModel: DeviceViewModel +) : Dialog(context, R.style.BottomControlSheetStyle) { private val kTag = "BottomControlSheet" private val binding: SheetBottomControlBinding by binding() - private lateinit var viewModelStore: ViewModelStore - private lateinit var deviceViewModel: DeviceViewModel private var speed = 5 - override fun getViewModelStore(): ViewModelStore { - return viewModelStore - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - viewModelStore.clear() - } - @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 1f) + val window = this.window ?: return + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.BOTTOM) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.ActionSheetDialogAnimation) + val params = window.attributes + params.width = context.getScreenWidth() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + setCancelable(true) setCanceledOnTouchOutside(true) @@ -50,9 +51,6 @@ LocaleConstant.DEVICE_CONTROL_SERVER_CONFIG, LocaleConstant.CAMERA_IP ) - viewModelStore = ViewModelStore() - deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] - binding.leftButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> executeCommand("Left") diff --git a/app/src/main/res/drawable/button_check_selector.xml b/app/src/main/res/drawable/button_check_selector.xml deleted file mode 100644 index 46c4f6b..0000000 --- a/app/src/main/res/drawable/button_check_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt index 0ef28fa..5aa28cc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt @@ -3,14 +3,14 @@ import android.app.Dialog import android.content.Context import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetAllCommandBinding -import com.casic.br.operationsite.test.extensions.convert import com.casic.br.operationsite.test.model.CommandModel -import com.casic.br.operationsite.test.util.tcp.SocketManager +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.util.LocaleConstant import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter @@ -21,7 +21,6 @@ import com.pengxh.kt.lite.extensions.getScreenHeight import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.readAssetsFile -import com.pengxh.kt.lite.extensions.show class AllCommandSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle) { @@ -31,7 +30,7 @@ private fun Dialog.resetParams() { val window = this.window ?: return - window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) window.decorView.setBackgroundColor(Color.TRANSPARENT) window.setGravity(Gravity.BOTTOM) //设置Dialog出现的动画 @@ -66,11 +65,12 @@ commandAdapter.setOnItemClickedListener(object : NormalRecyclerAdapter.OnItemClickedListener { override fun onItemClicked(position: Int, t: CommandModel) { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(context) - return + SocketConnectionService.weakReferenceHandler?.let { + val message = it.obtainMessage() + message.what = LocaleConstant.COMMAND_TEST_CODE + message.obj = t.command + it.sendMessage(message) } - SocketManager.get.send(t.command.convert()) } }) binding.sheetCancelButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt index db6bbcc..80ee657 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt @@ -3,42 +3,43 @@ import android.annotation.SuppressLint import android.app.Dialog import android.content.Context +import android.graphics.Color import android.os.Bundle import android.view.Gravity import android.view.MotionEvent -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner +import android.view.WindowManager +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetBottomControlBinding import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.vm.DeviceViewModel import com.pengxh.kt.lite.extensions.binding -import com.pengxh.kt.lite.extensions.resetParams +import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.utils.SaveKeyValues -class BottomControlSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle), - ViewModelStoreOwner { +class BottomControlSheet( + private val context: Context, + private val deviceViewModel: DeviceViewModel +) : Dialog(context, R.style.BottomControlSheetStyle) { private val kTag = "BottomControlSheet" private val binding: SheetBottomControlBinding by binding() - private lateinit var viewModelStore: ViewModelStore - private lateinit var deviceViewModel: DeviceViewModel private var speed = 5 - override fun getViewModelStore(): ViewModelStore { - return viewModelStore - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - viewModelStore.clear() - } - @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 1f) + val window = this.window ?: return + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.BOTTOM) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.ActionSheetDialogAnimation) + val params = window.attributes + params.width = context.getScreenWidth() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + setCancelable(true) setCanceledOnTouchOutside(true) @@ -50,9 +51,6 @@ LocaleConstant.DEVICE_CONTROL_SERVER_CONFIG, LocaleConstant.CAMERA_IP ) - viewModelStore = ViewModelStore() - deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] - binding.leftButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> executeCommand("Left") diff --git a/app/src/main/res/drawable/button_check_selector.xml b/app/src/main/res/drawable/button_check_selector.xml deleted file mode 100644 index 46c4f6b..0000000 --- a/app/src/main/res/drawable/button_check_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt index 0ef28fa..5aa28cc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt @@ -3,14 +3,14 @@ import android.app.Dialog import android.content.Context import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetAllCommandBinding -import com.casic.br.operationsite.test.extensions.convert import com.casic.br.operationsite.test.model.CommandModel -import com.casic.br.operationsite.test.util.tcp.SocketManager +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.util.LocaleConstant import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter @@ -21,7 +21,6 @@ import com.pengxh.kt.lite.extensions.getScreenHeight import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.readAssetsFile -import com.pengxh.kt.lite.extensions.show class AllCommandSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle) { @@ -31,7 +30,7 @@ private fun Dialog.resetParams() { val window = this.window ?: return - window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) window.decorView.setBackgroundColor(Color.TRANSPARENT) window.setGravity(Gravity.BOTTOM) //设置Dialog出现的动画 @@ -66,11 +65,12 @@ commandAdapter.setOnItemClickedListener(object : NormalRecyclerAdapter.OnItemClickedListener { override fun onItemClicked(position: Int, t: CommandModel) { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(context) - return + SocketConnectionService.weakReferenceHandler?.let { + val message = it.obtainMessage() + message.what = LocaleConstant.COMMAND_TEST_CODE + message.obj = t.command + it.sendMessage(message) } - SocketManager.get.send(t.command.convert()) } }) binding.sheetCancelButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt index db6bbcc..80ee657 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt @@ -3,42 +3,43 @@ import android.annotation.SuppressLint import android.app.Dialog import android.content.Context +import android.graphics.Color import android.os.Bundle import android.view.Gravity import android.view.MotionEvent -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner +import android.view.WindowManager +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetBottomControlBinding import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.vm.DeviceViewModel import com.pengxh.kt.lite.extensions.binding -import com.pengxh.kt.lite.extensions.resetParams +import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.utils.SaveKeyValues -class BottomControlSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle), - ViewModelStoreOwner { +class BottomControlSheet( + private val context: Context, + private val deviceViewModel: DeviceViewModel +) : Dialog(context, R.style.BottomControlSheetStyle) { private val kTag = "BottomControlSheet" private val binding: SheetBottomControlBinding by binding() - private lateinit var viewModelStore: ViewModelStore - private lateinit var deviceViewModel: DeviceViewModel private var speed = 5 - override fun getViewModelStore(): ViewModelStore { - return viewModelStore - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - viewModelStore.clear() - } - @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 1f) + val window = this.window ?: return + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.BOTTOM) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.ActionSheetDialogAnimation) + val params = window.attributes + params.width = context.getScreenWidth() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + setCancelable(true) setCanceledOnTouchOutside(true) @@ -50,9 +51,6 @@ LocaleConstant.DEVICE_CONTROL_SERVER_CONFIG, LocaleConstant.CAMERA_IP ) - viewModelStore = ViewModelStore() - deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] - binding.leftButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> executeCommand("Left") diff --git a/app/src/main/res/drawable/button_check_selector.xml b/app/src/main/res/drawable/button_check_selector.xml deleted file mode 100644 index 46c4f6b..0000000 --- a/app/src/main/res/drawable/button_check_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml index b0b948c..88592cd 100644 --- a/app/src/main/res/layout/activity_big_image.xml +++ b/app/src/main/res/layout/activity_big_image.xml @@ -1,41 +1,35 @@ - + android:background="@color/black"> - + android:layout_height="match_parent" /> - + - + android:layout_centerVertical="true" + android:layout_marginStart="@dimen/lib_dp_10" + android:src="@drawable/ic_title_left" /> - - - - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore index c472770..e929963 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ .cxx local.properties app/old -app/release \ No newline at end of file +app/release +/.kotlin \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 361554e..7660f21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,17 +1,20 @@ import java.text.SimpleDateFormat -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + id('com.android.application') + id('org.jetbrains.kotlin.android') +} android { - compileSdkVersion 33 + namespace 'com.casic.br.operationsite.test' + compileSdk 35 defaultConfig { - applicationId "com.casic.br.operationsite.test" - minSdkVersion 23 - targetSdkVersion 33 + applicationId 'com.casic.br.operationsite.test' + minSdk 26 + targetSdk 35 versionCode 1080 - versionName "1.0.8.0" + versionName '1.0.8.0' } buildTypes { @@ -30,48 +33,41 @@ jvmTarget = '1.8' } - kotlin { - experimental { - coroutines 'enable' - } - } - buildFeatures { - viewBinding true + buildConfig = true + viewBinding = true } - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "XCGZ_YS_" + getBuildDate() + "_" + defaultConfig.versionName + ".apk" + applicationVariants.configureEach { + outputs.configureEach { + outputFileName = 'XCGZ_YS_' + getBuildDate() + '_' + defaultConfig.versionName + '.apk' } } } static def getBuildDate() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA) + SimpleDateFormat dateFormat = new SimpleDateFormat('yyyyMMdd', Locale.CHINA) return dateFormat.format(System.currentTimeMillis()) } dependencies { -//基础依赖库 - implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.0.10' - implementation 'androidx.core:core-ktx:1.9.0' - def base_version = "1.6.1" - implementation "androidx.appcompat:appcompat:${base_version}" - implementation "com.google.android.material:material:${base_version}" + //基础依赖库 + implementation 'com.github.AndroidCoderPeng:Kotlin-lite-lib:1.1.5' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' //Google官方授权框架 implementation 'pub.devrel:easypermissions:3.0.0' //沉浸式状态栏。基础依赖包,必须要依赖 - implementation 'com.gyf.immersionbar:immersionbar:3.0.0' - def vm_version = "2.5.1" + implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' //Kotlin协程 - implementation "androidx.lifecycle:lifecycle-runtime-ktx:${vm_version}" + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' //MVVM+LiveData - implementation "androidx.lifecycle:lifecycle-livedata-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${vm_version}" - implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' //图片加载框架 - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation 'com.github.bumptech.glide:glide:4.14.2' //图片选择框架 implementation 'io.github.lucksiege:pictureselector:v3.11.1' //图片压缩 @@ -84,26 +80,25 @@ implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' //网络请求和接口封装 implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.12.0' //官方Json解析库 implementation 'com.google.code.gson:gson:2.10.1' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //CameraX - def camerax_version = '1.2.3' - implementation "androidx.camera:camera-core:$camerax_version" + implementation 'androidx.camera:camera-core:1.2.3' // CameraX Camera2 extensions - implementation "androidx.camera:camera-camera2:$camerax_version" + implementation 'androidx.camera:camera-camera2:1.2.3' // CameraX Lifecycle library - implementation "androidx.camera:camera-lifecycle:$camerax_version" + implementation 'androidx.camera:camera-lifecycle:1.2.3' // CameraX View class - implementation "androidx.camera:camera-view:$camerax_version" + implementation 'androidx.camera:camera-view:1.2.3' //TCP implementation 'io.netty:netty-all:4.1.23.Final' //视频播放器,RTSP流 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.4.0-release-jitpack' - //是否需要ExoPlayer模式 - implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.4.0-release-jitpack' - //更多ijk的编码支持 - implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.4.0-release-jitpack' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-java:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-exo2:v10.1.0' + implementation 'com.github.CarGuo.GSYVideoPlayer:gsyvideoplayer-ex_so:v10.1.0' + //大图 + implementation 'com.github.chrisbanes:PhotoView:2.3.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ede224a..bb07476 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + @@ -37,7 +40,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> @@ -49,14 +52,14 @@ - - - + - + diff --git a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt index 90aa34e..7a487d2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/extensions/String.kt @@ -3,32 +3,27 @@ import android.content.Context import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.JsonParser +import com.google.gson.Gson +import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.createCompressImageDir import com.pengxh.kt.lite.utils.SaveKeyValues import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File +val gson by lazy { Gson() } + /** * String扩展方法 */ -fun String.getResponseCode(): Int { +fun String.getResponseHeader(): Pair { if (this.isBlank()) { - return 404 + return Pair(404, "Invalid Response") } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("code").asInt -} - -fun String.getResponseMessage(): String { - if (this.isBlank()) { - return "" - } - val element = JsonParser.parseString(this) - val jsonObject = element.asJsonObject - return jsonObject.get("message").asString + val jsonObject = gson.fromJson(this, JsonObject::class.java) + val code = jsonObject.get("code").asInt + val message = jsonObject.get("message").asString + return Pair(code, message) } //拼接图片地址 diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java deleted file mode 100644 index 758b3bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/AirConditionModel.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class AirConditionModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private double o2; - private int h2s; - private int co; - private int ch4; - - public double getO2() { - return o2; - } - - public void setO2(double o2) { - this.o2 = o2; - } - - public int getH2s() { - return h2s; - } - - public void setH2s(int h2s) { - this.h2s = h2s; - } - - public int getCo() { - return co; - } - - public void setCo(int co) { - this.co = co; - } - - public int getCh4() { - return ch4; - } - - public void setCh4(int ch4) { - this.ch4 = ch4; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java index f0a8f63..70228ef 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteListModel.java @@ -65,13 +65,26 @@ } public static class RowsModel { + private String borderPointCount; private String createTime; + private String deptFullName; + private String deptId; + private String deptName; + private List deviceList; + private String finishTime; + private String groupDeviceCode; + private String groupDeviceId; private String id; private String imageUrl; + private String locationTime; + private List pointLocation; + private String pointLocationJson; private String projectState; private String projectStateName; private String registerTime; + private String startTime; private String updateTime; + private String valid; private String workPerson; private String workPersonDeptId; private String workPersonDeptName; @@ -80,6 +93,16 @@ private String workRoad; private String workSiteDesc; private String workTitle; + private String workType; + private String workTypeName; + + public String getBorderPointCount() { + return borderPointCount; + } + + public void setBorderPointCount(String borderPointCount) { + this.borderPointCount = borderPointCount; + } public String getCreateTime() { return createTime; @@ -89,6 +112,62 @@ this.createTime = createTime; } + public String getDeptFullName() { + return deptFullName; + } + + public void setDeptFullName(String deptFullName) { + this.deptFullName = deptFullName; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } + + public String getFinishTime() { + return finishTime; + } + + public void setFinishTime(String finishTime) { + this.finishTime = finishTime; + } + + public String getGroupDeviceCode() { + return groupDeviceCode; + } + + public void setGroupDeviceCode(String groupDeviceCode) { + this.groupDeviceCode = groupDeviceCode; + } + + public String getGroupDeviceId() { + return groupDeviceId; + } + + public void setGroupDeviceId(String groupDeviceId) { + this.groupDeviceId = groupDeviceId; + } + public String getId() { return id; } @@ -105,6 +184,30 @@ this.imageUrl = imageUrl; } + public String getLocationTime() { + return locationTime; + } + + public void setLocationTime(String locationTime) { + this.locationTime = locationTime; + } + + public List getPointLocation() { + return pointLocation; + } + + public void setPointLocation(List pointLocation) { + this.pointLocation = pointLocation; + } + + public String getPointLocationJson() { + return pointLocationJson; + } + + public void setPointLocationJson(String pointLocationJson) { + this.pointLocationJson = pointLocationJson; + } + public String getProjectState() { return projectState; } @@ -129,6 +232,14 @@ this.registerTime = registerTime; } + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + public String getUpdateTime() { return updateTime; } @@ -137,6 +248,14 @@ this.updateTime = updateTime; } + public String getValid() { + return valid; + } + + public void setValid(String valid) { + this.valid = valid; + } + public String getWorkPerson() { return workPerson; } @@ -200,6 +319,43 @@ public void setWorkTitle(String workTitle) { this.workTitle = workTitle; } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getWorkTypeName() { + return workTypeName; + } + + public void setWorkTypeName(String workTypeName) { + this.workTypeName = workTypeName; + } + + public static class PointLocationModel { + private String lng; + private String lat; + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + } } } } diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java new file mode 100644 index 0000000..5d87443 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/model/WorkSiteWorkerModel.java @@ -0,0 +1,487 @@ +package com.casic.br.operationsite.test.model; + +import java.util.List; + +public class WorkSiteWorkerModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private boolean alarmFlag; + private String createTime; + private String deptId; + private String deptName; + private String enterReason; + private String gender; + private String genderName; + private HealthModel health; + private String id; + private String idCardNumber; + private String isRegister; + private LocationModel location; + private MultiGasModel multiGas; + private String ownerShip; + private String phoneNumber; + private String registerTime; + private String status; + private String statusName; + private String workerAvatar; + private String workerName; + private String workerType; + private String workerTypeName; + + public boolean isAlarmFlag() { + return alarmFlag; + } + + public void setAlarmFlag(boolean alarmFlag) { + this.alarmFlag = alarmFlag; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getEnterReason() { + return enterReason; + } + + public void setEnterReason(String enterReason) { + this.enterReason = enterReason; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getGenderName() { + return genderName; + } + + public void setGenderName(String genderName) { + this.genderName = genderName; + } + + public HealthModel getHealth() { + return health; + } + + public void setHealth(HealthModel health) { + this.health = health; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIdCardNumber() { + return idCardNumber; + } + + public void setIdCardNumber(String idCardNumber) { + this.idCardNumber = idCardNumber; + } + + public String getIsRegister() { + return isRegister; + } + + public void setIsRegister(String isRegister) { + this.isRegister = isRegister; + } + + public LocationModel getLocation() { + return location; + } + + public void setLocation(LocationModel location) { + this.location = location; + } + + public MultiGasModel getMultiGas() { + return multiGas; + } + + public void setMultiGas(MultiGasModel multiGas) { + this.multiGas = multiGas; + } + + public String getOwnerShip() { + return ownerShip; + } + + public void setOwnerShip(String ownerShip) { + this.ownerShip = ownerShip; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(String registerTime) { + this.registerTime = registerTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getWorkerAvatar() { + return workerAvatar; + } + + public void setWorkerAvatar(String workerAvatar) { + this.workerAvatar = workerAvatar; + } + + public String getWorkerName() { + return workerName; + } + + public void setWorkerName(String workerName) { + this.workerName = workerName; + } + + public String getWorkerType() { + return workerType; + } + + public void setWorkerType(String workerType) { + this.workerType = workerType; + } + + public String getWorkerTypeName() { + return workerTypeName; + } + + public void setWorkerTypeName(String workerTypeName) { + this.workerTypeName = workerTypeName; + } + + public static class HealthModel { + private String bloodOxygen; + private String deviceCode; + private String deviceId; + private String groupCode; + private String heartRate; + private String projectId; + private String uploadTimestamp; + + public String getBloodOxygen() { + return bloodOxygen; + } + + public void setBloodOxygen(String bloodOxygen) { + this.bloodOxygen = bloodOxygen; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getHeartRate() { + return heartRate; + } + + public void setHeartRate(String heartRate) { + this.heartRate = heartRate; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class LocationModel { + private String deviceCode; + private String deviceId; + private String gdLat; + private String gdLng; + private String groupCode; + private String lat; + private String lng; + private String projectId; + private String uploadTimestamp; + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getGdLat() { + return gdLat; + } + + public void setGdLat(String gdLat) { + this.gdLat = gdLat; + } + + public String getGdLng() { + return gdLng; + } + + public void setGdLng(String gdLng) { + this.gdLng = gdLng; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLng() { + return lng; + } + + public void setLng(String lng) { + this.lng = lng; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + + public static class MultiGasModel { + private String coValue; + private String deviceCode; + private String deviceId; + private String exValue; + private String groupCode; + private String h2sValue; + private String o2Value; + private String projectId; + private String projectName; + private String uploadTimestamp; + + public String getCoValue() { + return coValue; + } + + public void setCoValue(String coValue) { + this.coValue = coValue; + } + + public String getDeviceCode() { + return deviceCode; + } + + public void setDeviceCode(String deviceCode) { + this.deviceCode = deviceCode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getExValue() { + return exValue; + } + + public void setExValue(String exValue) { + this.exValue = exValue; + } + + public String getGroupCode() { + return groupCode; + } + + public void setGroupCode(String groupCode) { + this.groupCode = groupCode; + } + + public String getH2sValue() { + return h2sValue; + } + + public void setH2sValue(String h2sValue) { + this.h2sValue = h2sValue; + } + + public String getO2Value() { + return o2Value; + } + + public void setO2Value(String o2Value) { + this.o2Value = o2Value; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getUploadTimestamp() { + return uploadTimestamp; + } + + public void setUploadTimestamp(String uploadTimestamp) { + this.uploadTimestamp = uploadTimestamp; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java b/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java deleted file mode 100644 index e32edab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/model/WorkerModel.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.casic.br.operationsite.test.model; - -import java.util.List; - -public class WorkerModel { - - private int code; - private List data; - private String message; - private boolean success; - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public static class DataModel { - private boolean alarmFlag; - private String bloodOxygen; - private String braceletCode; - private String cell; - private String co; - private String gas; - private String gasTime; - private String h2s; - private String hatCode; - private String hatId; - private String heartRate; - private String lat; - private String lng; - private String location; - private String o2; - private String signal; - private String time; - private String vastCode; - private String workerId; - private String workerName; - - public boolean isAlarmFlag() { - return alarmFlag; - } - - public void setAlarmFlag(boolean alarmFlag) { - this.alarmFlag = alarmFlag; - } - - public String getBloodOxygen() { - return bloodOxygen; - } - - public void setBloodOxygen(String bloodOxygen) { - this.bloodOxygen = bloodOxygen; - } - - public String getBraceletCode() { - return braceletCode; - } - - public void setBraceletCode(String braceletCode) { - this.braceletCode = braceletCode; - } - - public String getCell() { - return cell; - } - - public void setCell(String cell) { - this.cell = cell; - } - - public String getCo() { - return co; - } - - public void setCo(String co) { - this.co = co; - } - - public String getGas() { - return gas; - } - - public void setGas(String gas) { - this.gas = gas; - } - - public String getGasTime() { - return gasTime; - } - - public void setGasTime(String gasTime) { - this.gasTime = gasTime; - } - - public String getH2s() { - return h2s; - } - - public void setH2s(String h2s) { - this.h2s = h2s; - } - - public String getHatCode() { - return hatCode; - } - - public void setHatCode(String hatCode) { - this.hatCode = hatCode; - } - - public String getHatId() { - return hatId; - } - - public void setHatId(String hatId) { - this.hatId = hatId; - } - - public String getHeartRate() { - return heartRate; - } - - public void setHeartRate(String heartRate) { - this.heartRate = heartRate; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getO2() { - return o2; - } - - public void setO2(String o2) { - this.o2 = o2; - } - - public String getSignal() { - return signal; - } - - public void setSignal(String signal) { - this.signal = signal; - } - - public String getTime() { - return time; - } - - public void setTime(String time) { - this.time = time; - } - - public String getVastCode() { - return vastCode; - } - - public void setVastCode(String vastCode) { - this.vastCode = vastCode; - } - - public String getWorkerId() { - return workerId; - } - - public void setWorkerId(String workerId) { - this.workerId = workerId; - } - - public String getWorkerName() { - return workerName; - } - - public void setWorkerName(String workerName) { - this.workerName = workerName; - } - } -} diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt index 4d68464..f56e8a1 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitService.kt @@ -2,7 +2,15 @@ import okhttp3.MultipartBody import okhttp3.RequestBody -import retrofit2.http.* +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Query interface RetrofitService { /** @@ -41,7 +49,7 @@ /** * 实施中列表 */ - @GET("/site/listPage") + @GET("/v3/site/listPage") suspend fun getProjectListByPage( @Header("token") token: String, @Query("keywords") keywords: String, @@ -53,19 +61,13 @@ /** * 获取工作区域作业人员 */ - @GET("/overview/workerList") - suspend fun getWorkers( + @GET("/v3/overview/workerList") + suspend fun getWorkSiteWorkers( @Header("token") token: String, @Query("projectId") projectId: String ): String /** - * 获取四合一数据 - */ - @GET("/emergency/startCheckOxygen") - suspend fun getAirCondition(@Header("token") token: String): String - - /** * 上报每个大阶段场景 * */ @GET("/emergency/notifyStageFinished") diff --git a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt index ed19c9f..a813fb0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/retrofit/RetrofitServiceManager.kt @@ -3,7 +3,7 @@ import android.util.Log import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson +import com.casic.br.operationsite.test.util.RuntimeCache import com.google.gson.JsonObject import com.pengxh.kt.lite.extensions.toJson import com.pengxh.kt.lite.utils.RetrofitFactory @@ -11,14 +11,13 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File object RetrofitServiceManager { private const val kTag = "RetrofitServiceManager" - private val gson by lazy { Gson() } private val api by lazy { val httpConfig = SaveKeyValues.getValue( @@ -67,27 +66,20 @@ /** * 获取工作区域作业人员 */ - suspend fun getWorkers(projectId: String): String { - return api.getWorkers(AuthenticationHelper.token!!, projectId) + suspend fun getWorkSiteWorkers(): String { + return api.getWorkSiteWorkers(AuthenticationHelper.token!!, RuntimeCache.projectId) } /** * 上传图片 */ suspend fun uploadImage(image: File): String { - val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val requestBody = image.asRequestBody("image/png".toMediaTypeOrNull()) val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) return api.uploadImage(AuthenticationHelper.token!!, imagePart) } /** - * 获取四合一数据 - */ - suspend fun getAirCondition(): String { - return api.getAirCondition(AuthenticationHelper.token!!) - } - - /** * 上报每个大阶段场景 */ suspend fun notifyStageFinished(operationId: String?, stage: String): String { diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt new file mode 100644 index 0000000..337aaf1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/service/SocketConnectionService.kt @@ -0,0 +1,125 @@ +package com.casic.br.operationsite.test.service + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.Service +import android.content.Intent +import android.os.Handler +import android.os.IBinder +import android.os.Message +import android.util.Log +import androidx.core.app.NotificationCompat +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.extensions.convert +import com.casic.br.operationsite.test.util.LocaleConstant +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient + +class SocketConnectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + override fun handleMessage(msg: Message): Boolean { + if (!tcpClient.isRunning()) { + "数据通讯服务断开连接,指令发送失败".show(this) + return true + } + + when (msg.what) { + LocaleConstant.COMMAND_TEST_CODE -> { + val commandStr = msg.obj as String + tcpClient.sendMessage(commandStr.convert()) + } + + LocaleConstant.GAS_ALARM_CODE -> { + tcpClient.sendMessage(LocaleConstant.GAS_ALARM_COMMAND) + } + + LocaleConstant.CONFIRM_AIR_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.CONFIRM_AIR_COMMAND) + } + + LocaleConstant.START_VIDEO_COMMAND_CODE -> { + tcpClient.sendMessage(LocaleConstant.START_VIDEO_COMMAND) + } + } + return true + } + + private val kTag = "SocketService" + private val notificationId = 1 + private val tcpClient by lazy { TcpClient(this) } + private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } + private var notificationBuilder: NotificationCompat.Builder? = null + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "socket_connection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for socket connection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "socket_connection_service_channel") + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("数据通讯服务连接中...") + .setContentText("为保证程序正常运行,请勿移除此通知") + .setPriority(NotificationCompat.PRIORITY_HIGH) // 设置通知优先级 + .setOngoing(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + + val notification = notificationBuilder?.build() + startForeground(notificationId, notification) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + if (weakReferenceHandler == null) { + weakReferenceHandler = WeakReferenceHandler(this) + } + tcpClient.start(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) + Log.d(kTag, "onStartCommand: SocketConnectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("数据通讯服务已连接") + "数据通讯服务连接成功,现在可以下发指令了".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("数据通讯服务断开连接") + "数据通讯服务断开连接".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("数据通讯服务连接出错,开始重连") + "数据通讯服务连接出错,开始重连".show(this) + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: SocketConnectionService") + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt b/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt deleted file mode 100644 index bc3c0ca..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/service/TcpMessageService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.casic.br.operationsite.test.service - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.IBinder -import android.os.Message -import com.casic.br.operationsite.test.util.LocaleConstant -import com.casic.br.operationsite.test.util.tcp.SocketManager -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler - -class TcpMessageService : Service(), Handler.Callback { - - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - - private val kTag = "TcpMessageService" - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - override fun onCreate() { - super.onCreate() - weakReferenceHandler = WeakReferenceHandler(this) - SocketManager.get.connectTcpServer(LocaleConstant.GAS_BASE_IP, LocaleConstant.TCP_PORT) - } - - override fun onDestroy() { - super.onDestroy() - SocketManager.get.close() - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == LocaleConstant.TCP_CONNECTED_CODE) { - "指令连接成功,现在可以下发指令了".show(this) - } else { - "指令连接断开,开始自动重连".show(this) - } - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt b/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt deleted file mode 100644 index 56bc436..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/GlideLoadEngine.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.casic.br.operationsite.test.util - -import android.content.Context -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.CenterCrop -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.casic.br.operationsite.test.R -import com.luck.picture.lib.engine.ImageEngine -import com.luck.picture.lib.utils.ActivityCompatHelper - - -class GlideLoadEngine private constructor() : ImageEngine { - - companion object { - val get: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { - GlideLoadEngine() - } - } - - override fun loadImage(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context).load(url).into(imageView); - } - - override fun loadImage( - context: Context, - imageView: ImageView, - url: String, - maxWidth: Int, - maxHeight: Int - ) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .load(url) - .override(maxWidth, maxHeight) - .into(imageView) - } - - override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { - if (!ActivityCompatHelper.assertValidRequest(context)) { - return - } - Glide.with(context) - .asBitmap() - .load(url) - .override(180, 180) - .sizeMultiplier(0.5f) - .transform(CenterCrop(), RoundedCorners(8)) - .placeholder(R.drawable.ps_image_placeholder) - .into(imageView) - } - - override fun pauseRequests(context: Context?) { - context?.let { Glide.with(it).pauseRequests() } - } - - override fun resumeRequests(context: Context?) { - context?.let { Glide.with(it).resumeRequests() } - } - - override fun loadGridImage(context: Context, url: String, imageView: ImageView) { - Glide.with(context) - .load(url) - .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) - .into(imageView) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt index ec57ebc..92cf048 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/HttpRequestHelper.kt @@ -1,13 +1,13 @@ package com.casic.br.operationsite.test.util import android.util.Log -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope import com.google.gson.Gson import com.google.gson.JsonObject +import com.pengxh.kt.lite.utils.LiteKitConstant +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType @@ -21,10 +21,9 @@ /** * Service里面的Http请求 * */ -class HttpRequestHelper(builder: Builder) : LifecycleOwner { +class HttpRequestHelper(builder: Builder) { private val kTag = "HttpRequestHelper" - private val registry = LifecycleRegistry(this) private val gson by lazy { Gson() } class Builder { @@ -68,6 +67,9 @@ } fun build(): HttpRequestHelper { + if (!::key.isInitialized || !::value.isInitialized || !::url.isInitialized || !::httpRequestCallback.isInitialized) { + throw IllegalStateException("All properties must be initialized before building.") + } return HttpRequestHelper(this) } } @@ -81,7 +83,7 @@ /** * 发起网络请求 * */ - fun start() { + fun start(timeoutSeconds: Long = LiteKitConstant.HTTP_TIMEOUT) { val param = JsonObject() map.forEach { param.add(it.key, gson.toJsonTree(it.value)) @@ -91,30 +93,43 @@ ) //构建Request val request = Request.Builder().addHeader(key, value).post(requestBody).url(url).build() - lifecycleScope.launch(Dispatchers.IO) { - val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { - override fun log(message: String) { - Log.d(kTag, ">>>>> $message") - } - }) - interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) - val client = OkHttpClient.Builder() - .addInterceptor(interceptor) - .readTimeout(10, TimeUnit.SECONDS) - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build() + + val logLevel = HttpLoggingInterceptor.Level.NONE + val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Log.d(kTag, ">>>>> $message") + } + }).setLevel(logLevel) + + val client = OkHttpClient.Builder() + .addInterceptor(interceptor) + .readTimeout(timeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(timeoutSeconds, TimeUnit.SECONDS) + .build() + + val job = SupervisorJob() + val scope = CoroutineScope(Dispatchers.Main + job) + scope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, throwable -> + callback.onFailure(throwable) + }) { try { - val response = client.newCall(request).execute() - response.body?.apply { - withContext(Dispatchers.Main) { - callback.onSuccess(string()) + val response = withContext(Dispatchers.IO) { + client.newCall(request).execute() + } + if (response.isSuccessful) { + response.body?.string()?.let { + callback.onSuccess(it) + } ?: run { + callback.onFailure(IOException("Response body is null")) } + } else { + callback.onFailure(IOException("Unexpected code ${response.code}")) } - } catch (e: IOException) { - withContext(Dispatchers.Main) { - callback.onFailure(e) - } + } catch (e: Exception) { + callback.onFailure(e) + } finally { + job.cancel() } } } @@ -124,8 +139,4 @@ fun onFailure(throwable: Throwable) } - - override fun getLifecycle(): Lifecycle { - return registry - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt index 63ae413..68584bb 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/LocaleConstant.kt @@ -28,8 +28,8 @@ ) } -// const val SERVER_BASE_URL = "http://192.168.9.99:8085" - const val SERVER_BASE_URL = "http://139.198.19.235:22006" + const val SERVER_BASE_URL = "http://111.198.10.15:22006" +// const val SERVER_BASE_URL = "http://139.198.19.235:22006" const val IMAGE_BED_URL = "${SERVER_BASE_URL}/emergency/prepareUpload" @@ -51,7 +51,8 @@ const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" - const val USER_DETAIL_MODEL = "userDetailModel" + const val USER_NAME_KEY = "USER_NAME_KEY" + const val USER_ID_KEY = "USER_ID_KEY" const val PERMISSIONS_CODE = 999 const val PAGE_LIMIT = 10 @@ -61,8 +62,10 @@ const val WEBSOCKET_MESSAGE_CODE = 101 const val WEBSOCKET_DISCONNECTED_CODE = 102 - const val TCP_CONNECTED_CODE = 103 - const val TCP_DISCONNECTED_CODE = 104 + const val COMMAND_TEST_CODE = 202506001 + const val GAS_ALARM_CODE = 202506002 + const val CONFIRM_AIR_COMMAND_CODE = 202506003 + const val START_VIDEO_COMMAND_CODE = 202506004 //作业前检测 val CONFIRM_AIR_COMMAND = @@ -73,6 +76,6 @@ byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x11, 0x00, 0xA5.toByte()) //甲烷阈值报警 - val GAS_COMMAND = + val GAS_ALARM_COMMAND = byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x93.toByte(), 0x14, 0x00, 0xA8.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt index f044fd3..14514a0 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/util/VideoPlayerManager.kt @@ -3,11 +3,11 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager import com.shuyu.gsyvideoplayer.model.VideoOptionModel import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.NormalGSYVideoPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer object VideoPlayerManager { - fun setGSYVideoPlayerOptions(videoPlayer: StandardGSYVideoPlayer, url: String) { + fun setGSYVideoPlayerOptions(videoPlayer: NormalGSYVideoPlayer, url: String) { val list = ArrayList() //开启软解码,硬解码:1、打开,0、关闭 diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt deleted file mode 100644 index a00a2a8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/ISocketListener.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -interface ISocketListener { - companion object { - const val STATUS_CONNECT_SUCCESS: Byte = 1 //连接成功 - const val STATUS_CONNECT_CLOSED: Byte = 0 //关闭连接 - const val STATUS_CONNECT_ERROR: Byte = -1 //连接失败 - } - - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray?) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Byte) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt deleted file mode 100644 index 8963268..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketChannelHandle.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.util.Log -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener?) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_CLOSED) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - listener?.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - Log.d(kTag, "exceptionCaught ===> $cause") - listener?.onServiceStatusConnectChanged(ISocketListener.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt deleted file mode 100644 index 12d4ac8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketClient.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.util.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.AdaptiveRecvByteBufAllocator -import io.netty.channel.Channel -import io.netty.channel.ChannelFuture -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelInitializer -import io.netty.channel.ChannelOption -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - - private var host: String? = null - private var port = 9000 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - - //现在连接的状态 - var connectStatus = false //判断是否已连接 - private var reconnectNum = Int.MAX_VALUE //定义的重连到时候用 - private var isNeedReconnect = true //是否需要重连 - var isConnecting = false //是否正在连接 - private set - private var reconnectIntervalTime: Long = 5000 //重连的时间 - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(host: String, port: Int) { - this.host = host - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread: Thread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this@SocketClient) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - //参数1:代表读套接字超时的时间,没收到数据会触发读超时回调; - //参数2:代表写套接字超时时间,没进行写会触发写超时回调; - //参数3:将在未执行读取或写入时触发超时回调,0代表不处理; - //读超时尽量设置大于写超时,代表多次写超时时写心跳包,多次写了心跳数据仍然读超时代表当前连接错误,即可断开连接重新连接 - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(host, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_CONNECTED_CODE - ) - } else { - connectStatus = false - TcpMessageService.weakReferenceHandler.sendEmptyMessage( - LocaleConstant.TCP_DISCONNECTED_CODE - ) - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (!future.isSuccess) { - future.channel().close() - nioEventLoopGroup!!.shutdownGracefully() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt deleted file mode 100644 index fa76606..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/util/tcp/SocketManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.casic.br.operationsite.test.util.tcp - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketManager private constructor() : LifecycleOwner, ISocketListener { - - private val kTag = "SocketManager" - private val registry = LifecycleRegistry(this) - var nettyClient: SocketClient = SocketClient() - - companion object { - val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SocketManager() } - } - - fun connectTcpServer(hostname: String, port: Int) { - lifecycleScope.launch(Dispatchers.IO) { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this@SocketManager) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - } - } - - override fun onMessageResponse(data: ByteArray?) { - - } - - override fun onServiceStatusConnectChanged(statusCode: Byte) { - - } - - fun send(data: ByteArray) { - lifecycleScope.launch(Dispatchers.IO) { - nettyClient.sendData(data) - } - } - - fun close() { - nettyClient.disconnect() - } - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt index ce95949..5586699 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/BigImageActivity.kt @@ -1,41 +1,42 @@ package com.casic.br.operationsite.test.view -import android.content.Context import android.graphics.Color import android.media.MediaScannerConnection import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import androidx.viewpager.widget.PagerAdapter -import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.viewpager2.widget.ViewPager2 import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityBigImageBinding -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.luck.picture.lib.photoview.PhotoView +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.utils.FileDownloadManager +import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File class BigImageActivity : KotlinBaseActivity() { private val kTag = "BigImageActivity" + private val context = this + private val insetsController by lazy { + WindowCompat.getInsetsController(window, binding.rootView) + } override fun initViewBinding(): ActivityBigImageBinding { return ActivityBigImageBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.black) + ImmersionBar.with(this).statusBarDarkFont(false).init() + insetsController.hide(WindowInsetsCompat.Type.statusBars()) binding.leftBackView.setOnClickListener { finish() } } @@ -49,123 +50,92 @@ } override fun initEvent() { - val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) - val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) - if (urls == null || urls.size == 0) { + val index = intent.getIntExtra(LiteKitConstant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(LiteKitConstant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.isEmpty()) { return } val imageSize = urls.size - binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") - binding.imagePagerView.adapter = BigImageAdapter(this, urls) - binding.imagePagerView.currentItem = index - binding.imagePagerView.offscreenPageLimit = imageSize - binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrolled( - position: Int, positionOffset: Float, positionOffsetPixels: Int - ) { - } + binding.indexView.text = String.format("(${(index + 1)}/${imageSize})") + val adapter = object : NormalRecyclerAdapter(R.layout.item_big_image, urls) { + override fun convertView(viewHolder: ViewHolder, position: Int, item: String) { + viewHolder.setImageResource(R.id.photoView, item) + .setOnLongClickListener(R.id.photoView) { + BottomActionSheet.Builder() + .setContext(context) + .setActionItemTitle(arrayListOf("保存")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : + BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> updateSystemAlbum(item) + } + } + + }).build().show() + true + } + } + } + binding.viewPager.adapter = adapter + binding.viewPager.currentItem = index + adapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked(position: Int, item: String) { + finish() + } + }) + + binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { - binding.pageNumberView.text = - String.format("(" + (position + 1) + "/" + imageSize + ")") + binding.indexView.text = String.format("(${(position + 1)}/${imageSize})") } - - override fun onPageScrollStateChanged(state: Int) {} }) } - inner class BigImageAdapter( - private val context: Context, private val data: ArrayList - ) : PagerAdapter() { - - override fun getCount(): Int = data.size - - override fun isViewFromObject(view: View, any: Any): Boolean { - return view == any - } - - override fun instantiateItem(container: ViewGroup, position: Int): Any { - val view = LayoutInflater.from(context).inflate( - R.layout.item_big_picture, container, false - ) - val photoView = view.findViewById(R.id.photoView) - - val path = data[position] - /** - * DisclosureActivity -> http://111.198.10.15:22006/static/2024-06/b237b332b00c4ce99585c61f860f30b7.jpeg - * EnvironmentActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628110803.jpg - * SuppliesActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111403.jpg - * GuardiansActivity -> //storage/emulated/0/Android/data/com.casic.br.operationsite.test/files/Pictures/IMG20240628111506.jpg - * */ - - Glide.with(context).load(path).into(photoView) - photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE - container.addView(view) - //点击大图取消预览 - photoView.setOnClickListener { finish() } - - photoView.setOnLongClickListener { - BottomActionSheet.Builder() - .setContext(context) - .setActionItemTitle(arrayListOf("保存")) - .setItemTextColor(Color.BLUE) - .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { - override fun onActionItemClick(position: Int) { - when (position) { - 0 -> updateSystemAlbum(path) - } - } - - - }).build().show() - true - } - return view - } - - private fun updateSystemAlbum(imagePath: String) { - if (imagePath.startsWith("http") || imagePath.startsWith("https")) { - //需要将图片保存在本地 - FileDownloadManager.Builder().setDownloadFileSource(imagePath) - .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) - .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { - override fun onDownloadEnd(file: File) { - scanFile(file) - } - - override fun onFailure(throwable: Throwable) { - - } - - override fun onProgressChanged(progress: Int) { - - } - }).build().start() - } else { - scanFile(File(imagePath)) - } - } - - private fun scanFile(file: File) { - MediaStore.Images.Media.insertImage( - contentResolver, - file.absolutePath, file.name, resources.getString(R.string.app_name) - ) - - MediaScannerConnection.scanFile(context, arrayOf(file.absolutePath), null, - object : MediaScannerConnection.MediaScannerConnectionClient { - override fun onMediaScannerConnected() { + private fun updateSystemAlbum(imagePath: String) { + if (imagePath.startsWith("http") || imagePath.startsWith("https")) { + //需要将图片保存在本地 + FileDownloadManager.Builder().setDownloadFileSource(imagePath) + .setFileSuffix("jpg").setFileSaveDirectory(createDownloadFileDir()) + .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { + override fun onDownloadStart(total: Long) { } - override fun onScanCompleted(path: String?, uri: Uri?) { - "保存到相册成功".show(context) + override fun onDownloadEnd(file: File) { + scanFile(file) } - }) - } - override fun destroyItem(container: ViewGroup, position: Int, any: Any) { - container.removeView(any as View) + override fun onDownloadFailed(t: Throwable) { + + } + + override fun onProgressChanged(progress: Long) { + + } + }).build().start() + } else { + scanFile(File(imagePath)) } } + + private fun scanFile(file: File) { + MediaStore.Images.Media.insertImage( + contentResolver, file.absolutePath, file.name, resources.getString(R.string.app_name) + ) + MediaScannerConnection.scanFile( + this, arrayOf(file.absolutePath), null, + object : MediaScannerConnection.MediaScannerConnectionClient { + override fun onMediaScannerConnected() { + + } + + override fun onScanCompleted(path: String?, uri: Uri?) { + "保存到相册成功".show(context) + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt index 6197330..028d7d8 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/DisclosureActivity.kt @@ -6,12 +6,13 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityDisclosureBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet import com.casic.br.operationsite.test.widget.BottomControlSheet @@ -21,23 +22,35 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class DisclosureActivity : KotlinBaseActivity() { private val kTag = "DisclosureActivity" - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var sceneViewModel: SceneViewModel + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } override fun initEvent() { binding.startCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } //通知一体机开始算法 - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "brief") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "brief", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -45,7 +58,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } binding.confirmAirButton.setOnClickListener { @@ -54,10 +67,16 @@ .setPositiveButton("确定").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - sceneViewModel.notifyStageFinished(null, "Environment") + sceneViewModel.notifyStageFinished(null, "Environment") { + if (it) { + "四合一消息上传成功".show(this@DisclosureActivity) + } + } //下发指令 - SocketManager.get.send(LocaleConstant.CONFIRM_AIR_COMMAND) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONFIRM_AIR_COMMAND_CODE + ) //跳转 navigatePageTo() @@ -73,14 +92,6 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] - sceneViewModel.notifyStageResult.observe(this) { - if (it) { - "四合一消息上传成功".show(this) - } - } - //动态设置rtspPlayerView宽高 val rtspViewParams = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams val videoWidth = getScreenWidth() - 20.dp2px(this) diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt index a68b34c..adff1bc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/GuardiansActivity.kt @@ -4,20 +4,20 @@ import android.os.Handler import android.os.Message import android.text.TextUtils -import android.util.Log import android.view.View import android.widget.FrameLayout import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityGuardiansBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.AlarmViewModel import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.RegionViewModel import com.casic.br.operationsite.test.vm.WorkSiteViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -30,8 +30,7 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView @@ -50,14 +49,14 @@ private val kTag = "GuardiansActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val regionViewModel by lazy { ViewModelProvider(this)[RegionViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val alarmViewModel by lazy { ViewModelProvider(this)[AlarmViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var alarmViewModel: AlarmViewModel - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var regionViewModel: RegionViewModel private lateinit var imageAdapter: EditableImageAdapter private lateinit var timer: Timer - private var isEndTask = false override fun initEvent() { binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked -> @@ -146,13 +145,30 @@ binding.setVideoRegionButton.setOnClickListener { val region = binding.regionView.getConfirmedRegion() - - regionViewModel.setVideoRegion("YTJ_010002", region) + regionViewModel.setVideoRegion("YTJ_010002", region) { + if (it) { + "电子围栏设置成功".show(this) + } + } } binding.startVideoCheckButton.setOnClickListener { RuntimeCache.currentScene = CurrentScene.Guardian - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "in_operation") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "in_operation", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "监护人员检测开启成功".show(this) + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } binding.showOtherCommandButton.setOnClickListener { @@ -160,7 +176,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -210,63 +226,32 @@ ) binding.rtspPlayerView.startPlayLogic() - alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] - alarmViewModel.getAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.stateResult.observe(this) { - if (it.code == 200) { + alarmViewModel.getAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { binding.alarmCheckbox.isChecked = it.data.state == "1" - } - } + }, + onFailed = { it.show(this) } + ) - alarmViewModel.getOtherAlarmState(this, LocaleConstant.AI_BASE_IP, LocaleConstant.CAMERA_IP) - alarmViewModel.otherStateResult.observe(this) { result -> - if (result.code == 200) { - result.data.let { - binding.noneSupervisorCheckbox.isChecked = it.no_supervisor_alarm == "1" - binding.intrudeCheckbox.isChecked = it.break_alarm == "1" - binding.smokeCheckbox.isChecked = it.smoke_alarm == "1" - } - } - } - - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - constructionCheckViewModel.setCurrentPhaseResult.observe(this) { - if (it) { - if (isEndTask) { - ActivityStackManager.finishAllActivity() - navigatePageTo() - finish() - } else { - "监护人员检测开启成功".show(this) - } - } - } - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - workSiteViewModel.workerResult.observe(this) { - if (it.code == 200) { - it.data.first().apply { - if (gas.toFloat().toInt() >= 5 - && SocketManager.get.nettyClient.connectStatus - ) { - Log.d(kTag, "initOnCreate: 发送甲烷浓度超限报警") - SocketManager.get.send(LocaleConstant.GAS_COMMAND) - } - } - } - } - - regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] - regionViewModel.setVideoRegionResult.observe(this) { - if (it) { - "电子围栏设置成功".show(this) - } - } + alarmViewModel.getOtherAlarmState( + LocaleConstant.AI_BASE_IP, + LocaleConstant.CAMERA_IP, + onLoading = {}, + onSuccess = { + binding.noneSupervisorCheckbox.isChecked = it.data.no_supervisor_alarm == "1" + binding.intrudeCheckbox.isChecked = it.data.break_alarm == "1" + binding.smokeCheckbox.isChecked = it.data.smoke_alarm == "1" + }, + onFailed = { it.show(this) } + ) timer = Timer() timer.schedule(object : TimerTask() { override fun run() { - workSiteViewModel.getWorkers(context, RuntimeCache.projectId) + getWorkSiteWorkers() } }, 0, 5000) @@ -279,11 +264,27 @@ binding.recyclerView.adapter = imageAdapter } + private fun getWorkSiteWorkers() { + workSiteViewModel.getWorkSiteWorkers( + onLoading = {}, + onSuccess = { + it.data.first().apply { + if (multiGas.exValue.toFloat().toInt() >= 5) { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.GAS_ALARM_CODE + ) + } + } + }, + onFailed = { it.show(this) } + ) + } + override fun handleMessage(msg: Message): Boolean { if (msg.what == LocaleConstant.WEBSOCKET_MESSAGE_CODE) { val imagePath = msg.obj as String if (recyclerViewImages.size == 3) { - recyclerViewImages.removeFirst() + recyclerViewImages.removeAt(0) imageAdapter.notifyDataSetChanged() } recyclerViewImages.add(imagePath) @@ -297,22 +298,7 @@ } override fun observeRequestState() { - constructionCheckViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> { - LoadingDialogHub.show(this, "数据提交中,请稍后...") - } - LoadState.Success -> { - LoadingDialogHub.dismiss() - } - - else -> { - "数据提交失败,请重试...".show(this) - LoadingDialogHub.dismiss() - } - } - } } override fun setupTopBarLayout() { @@ -334,8 +320,23 @@ .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { - isEndTask = true - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "stop") + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "stop", + onLoading = { + LoadingDialog.show(context, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + ActivityStackManager.finishAllActivity() + navigatePageTo() + finish() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(context) + } + ) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt index 3f05f81..b211864 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/LoginActivity.kt @@ -5,25 +5,25 @@ import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.ActivityLoginBinding import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.util.AuthenticationHelper import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RSAUtils import com.casic.br.operationsite.test.vm.AuthenticateViewModel import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.UserDetailViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.SaveKeyValues +import pub.devrel.easypermissions.EasyPermissions -class LoginActivity : KotlinBaseActivity() { +class LoginActivity : KotlinBaseActivity(), + EasyPermissions.PermissionCallbacks { - private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var loginViewModel: LoginViewModel - private lateinit var userDetailViewModel: UserDetailViewModel + private val authenticateViewModel by lazy { ViewModelProvider(this)[AuthenticateViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } override fun initViewBinding(): ActivityLoginBinding { return ActivityLoginBinding.inflate(layoutInflater) @@ -35,23 +35,25 @@ override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) + + if (!EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { + EasyPermissions.requestPermissions( + this, + resources.getString(R.string.app_name) + "需要获取相关权限", + LocaleConstant.PERMISSIONS_CODE, + *LocaleConstant.USER_PERMISSIONS + ) + } + // 设置默认账号密码 binding.userNameView.setText(SaveKeyValues.getValue(LocaleConstant.ACCOUNT, "") as String) binding.userPasswordView.setText( SaveKeyValues.getValue(LocaleConstant.PASSWORD, "") as String ) - authenticateViewModel = ViewModelProvider(this)[AuthenticateViewModel::class.java] - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] } override fun observeRequestState() { - loginViewModel.loadState.observe(this) { loginState -> - when (loginState) { - is LoadState.Loading -> LoadingDialogHub.show(this, "登录中,请稍后...") - else -> LoadingDialogHub.dismiss() - } - } + } override fun initEvent() { @@ -68,37 +70,65 @@ } SaveKeyValues.putValue(LocaleConstant.ACCOUNT, account) SaveKeyValues.putValue(LocaleConstant.PASSWORD, userPassword) - authenticateViewModel.getPublicKey(this) + authenticateViewModel.getPublicKey( + onLoading = {}, + onSuccess = { startLogin(it) }, + onFailed = { it.show(this) } + ) } - authenticateViewModel.keyModel.observe(this) { - if (it.code == 200) {//用code判断,别的判断可能有坑 - val keyString = it.data!!.publicKey!! - /** - * 修改密码需要用到key,先存着 - * */ - AuthenticationHelper.savePublicKey(keyString) - val publicKey = RSAUtils.keyStrToPublicKey(keyString) + } - val account = binding.userNameView.text.toString() - val userPassword = binding.userPasswordView.text.toString() - val dataByPublicKey = RSAUtils.encryptDataByPublicKey( - userPassword.toByteArray(), publicKey!! - ) - //登录并获取Token,POST请求 - loginViewModel.enter(this, it.data!!.sid!!, account, dataByPublicKey) - loginViewModel.enterResultModel.observe(this) { loginResult -> - if (loginResult.code == 200) { - AuthenticationHelper.saveToken(loginResult.data!!.token!!) - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - //验证成功登录 - navigatePageTo() + private fun startLogin(it: PublicKeyModel) { + it.data?.let { data -> + val keyString = data.publicKey + /** + * 修改密码需要用到key,先存着 + * */ + AuthenticationHelper.savePublicKey(keyString) + val publicKey = RSAUtils.keyStrToPublicKey(keyString) + + val account = binding.userNameView.text.toString() + val userPassword = binding.userPasswordView.text.toString() + val dataByPublicKey = RSAUtils.encryptDataByPublicKey( + userPassword.toByteArray(), publicKey!! + ) + //登录并获取Token,POST请求 + loginViewModel.enter( + data.sid, + account, + dataByPublicKey, + onLoading = { + LoadingDialog.show(this, "登录中,请稍后...") + }, + onSuccess = { result -> + result.run { + LoadingDialog.dismiss() + AuthenticationHelper.saveToken(this.data.token) + navigatePageTo() finish() + "登录成功".show(this@LoginActivity) } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) } - } + ) } } + + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt new file mode 100644 index 0000000..92eee74 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/view/MainActivity.kt @@ -0,0 +1,193 @@ +package com.casic.br.operationsite.test.view + +import android.content.Intent +import android.os.Bundle +import androidx.lifecycle.ViewModelProvider +import com.casic.br.operationsite.test.R +import com.casic.br.operationsite.test.databinding.ActivityMainBinding +import com.casic.br.operationsite.test.extensions.initImmersionBar +import com.casic.br.operationsite.test.model.WorkSiteListModel +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.service.WebSocketService +import com.casic.br.operationsite.test.util.AuthenticationHelper +import com.casic.br.operationsite.test.util.LocaleConstant +import com.casic.br.operationsite.test.util.RuntimeCache +import com.casic.br.operationsite.test.vm.LoginViewModel +import com.casic.br.operationsite.test.vm.UserViewModel +import com.casic.br.operationsite.test.vm.WorkSiteViewModel +import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter +import com.pengxh.kt.lite.adapter.ViewHolder +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets +import com.pengxh.kt.lite.extensions.dp2px +import com.pengxh.kt.lite.extensions.navigatePageTo +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.AlertControlDialog + +class MainActivity : KotlinBaseActivity() { + + private val context = this + private val marginOffset by lazy { 15.dp2px(this) } + private val workSiteViewModel by lazy { ViewModelProvider(this)[WorkSiteViewModel::class.java] } + private val loginViewModel by lazy { ViewModelProvider(this)[LoginViewModel::class.java] } + private val userViewModel by lazy { ViewModelProvider(this)[UserViewModel::class.java] } + private lateinit var workSiteAdapter: NormalRecyclerAdapter + private var page = 1 + private var isRefresh = false + private var isLoadMore = false + + override fun initViewBinding(): ActivityMainBinding { + return ActivityMainBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) + binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { + override fun onLeftClick() { + finish() + } + + override fun onRightClick() { + AlertControlDialog.Builder() + .setContext(context) + .setTitle("退出登录") + .setMessage("确定要退出吗?") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + loginViewModel.out( + onLoading = {}, + onSuccess = { + AuthenticationHelper.removeToken() + ActivityStackManager.finishAllActivity() + navigatePageTo() + }, + onFailed = {} + ) + } + + override fun onCancelClick() {} + }).build().show() + } + }) + } + + override fun initEvent() { + binding.refreshView.setOnRefreshListener { + isRefresh = true + page = 1 + getProjectListByPage() + } + binding.refreshView.setOnLoadMoreListener { + isLoadMore = true + page++ + getProjectListByPage() + } + } + + private fun getProjectListByPage() { + workSiteViewModel.getProjectListByPage( + "", + "", + page, + onLoading = { + if (isRefresh || isLoadMore) { + return@getProjectListByPage + } + LoadingDialog.show(this, "数据加载中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + it.data?.let { data -> + val dataRows = data.rows + when { + isRefresh -> { + binding.refreshView.finishRefresh() + isRefresh = false + workSiteAdapter.refresh(dataRows) + } + + isLoadMore -> { + binding.refreshView.finishLoadMore() + isLoadMore = false + if (dataRows.isEmpty()) { + "到底了,别拉了".show(this) + return@getProjectListByPage + } + workSiteAdapter.loadMore(dataRows) + } + + else -> initRecyclerView(dataRows) + } + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(this) + } + ) + } + + override fun initOnCreate(savedInstanceState: Bundle?) { + ActivityStackManager.addActivity(this) + + startService(Intent(this, SocketConnectionService::class.java)) + startService(Intent(this, WebSocketService::class.java)) + + getProjectListByPage() + + userViewModel.getUserDetail( + onLoading = {}, + onSuccess = { + it.data?.let { data -> + SaveKeyValues.putValue(LocaleConstant.USER_NAME_KEY, data.name) + SaveKeyValues.putValue(LocaleConstant.USER_ID_KEY, data.id) + } + }, + onFailed = {} + ) + } + + private fun initRecyclerView(dataRows: MutableList) { + workSiteAdapter = object : NormalRecyclerAdapter( + R.layout.item_working_rv, dataRows + ) { + override fun convertView( + viewHolder: ViewHolder, position: Int, item: WorkSiteListModel.DataModel.RowsModel + ) { + viewHolder.setText(R.id.workSiteNameView, item.workTitle) + .setText(R.id.constructionUnitView, item.workPersonDeptName) + .setText(R.id.constructionDateView, item.registerTime) + .setText(R.id.leaderNameView, item.workPersonName) + .setText(R.id.leaderPhoneView, item.workPersonPhoneNumber) + .setText(R.id.workSiteView, item.workSiteDesc) + } + } + binding.recyclerView.adapter = workSiteAdapter + binding.recyclerView.addItemDecoration( + RecyclerViewItemOffsets( + marginOffset, marginOffset shr 1, marginOffset, marginOffset shr 1 + ) + ) + workSiteAdapter.setOnItemClickedListener(object : + NormalRecyclerAdapter.OnItemClickedListener { + override fun onItemClicked( + position: Int, t: WorkSiteListModel.DataModel.RowsModel + ) { + RuntimeCache.projectId = t.id + RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() + navigatePageTo() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt deleted file mode 100644 index f8006bd..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/PermissionActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.util.LocaleConstant -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks - -class PermissionActivity : AppCompatActivity(), PermissionCallbacks { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - ActivityStackManager.addActivity(this) - //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 - if (EasyPermissions.hasPermissions(this, *LocaleConstant.USER_PERMISSIONS)) { - startSplashScreenActivity() - } else { - EasyPermissions.requestPermissions( - this@PermissionActivity, - resources.getString(R.string.app_name) + "需要获取相关权限", - LocaleConstant.PERMISSIONS_CODE, - *LocaleConstant.USER_PERMISSIONS - ) - } - } - - private fun startSplashScreenActivity() { - navigatePageTo() - finish() - } - - override fun onRequestPermissionsResult( - requestCode: Int, permissions: Array, grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) - } - - override fun onPermissionsGranted(requestCode: Int, perms: List) { - startSplashScreenActivity() - } - - override fun onPermissionsDenied(requestCode: Int, perms: List) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt deleted file mode 100644 index 54d68ab..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SplashScreenActivity.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.annotation.SuppressLint -import android.os.Bundle -import android.os.CountDownTimer -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.databinding.ActivitySplashBinding -import com.casic.br.operationsite.test.vm.UserDetailViewModel -import com.gyf.immersionbar.ImmersionBar -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.utils.ActivityStackManager - -@SuppressLint("CustomSplashScreen") -class SplashScreenActivity : KotlinBaseActivity() { - - private val kTag = "SplashScreenActivity" - private lateinit var userDetailViewModel: UserDetailViewModel - - override fun initViewBinding(): ActivitySplashBinding { - return ActivitySplashBinding.inflate(layoutInflater) - } - - - override fun setupTopBarLayout() { - ImmersionBar.with(this).init() - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - userDetailViewModel = ViewModelProvider(this)[UserDetailViewModel::class.java] - } - - override fun observeRequestState() { - - } - - override fun initEvent() { - countDownTimer.start() - } - - private val countDownTimer = object : CountDownTimer(1000, 500) { - override fun onFinish() { - /** - * 获取token之后保存用户信息 - * */ - userDetailViewModel.getUserDetail() - userDetailViewModel.flag.observe(this@SplashScreenActivity) { - if (it) { - navigatePageTo() - } else { - navigatePageTo() - } - finish() - } - } - - override fun onTick(millisUntilFinished: Long) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt index 93577d8..466a937 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/view/SuppliesActivity.kt @@ -7,19 +7,19 @@ import android.view.View import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.lifecycleScope import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.callback.OnImageCompressListener import com.casic.br.operationsite.test.databinding.ActivitySuppliesBinding import com.casic.br.operationsite.test.extensions.compressImage import com.casic.br.operationsite.test.extensions.initImmersionBar import com.casic.br.operationsite.test.extensions.upload +import com.casic.br.operationsite.test.service.SocketConnectionService import com.casic.br.operationsite.test.util.CurrentScene import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.util.RuntimeCache import com.casic.br.operationsite.test.util.VideoPlayerManager -import com.casic.br.operationsite.test.util.tcp.SocketManager import com.casic.br.operationsite.test.vm.ConstructionCheckViewModel +import com.casic.br.operationsite.test.vm.DeviceViewModel import com.casic.br.operationsite.test.vm.SceneViewModel import com.casic.br.operationsite.test.vm.UploadFileViewModel import com.casic.br.operationsite.test.widget.AllCommandSheet @@ -32,13 +32,11 @@ import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.ActivityStackManager +import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.shuyu.gsyvideoplayer.GSYVideoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.io.File import java.util.UUID @@ -51,21 +49,17 @@ private val kTag = "SuppliesActivity" private val context = this private val marginOffset by lazy { 1.dp2px(this) } + private val uploadFileViewModel by lazy { ViewModelProvider(this)[UploadFileViewModel::class.java] } + private val sceneViewModel by lazy { ViewModelProvider(this)[SceneViewModel::class.java] } + private val constructionCheckViewModel by lazy { ViewModelProvider(this)[ConstructionCheckViewModel::class.java] } + private val deviceViewModel by lazy { ViewModelProvider(this)[DeviceViewModel::class.java] } private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径 - private lateinit var constructionCheckViewModel: ConstructionCheckViewModel - private lateinit var uploadFileViewModel: UploadFileViewModel - private lateinit var sceneViewModel: SceneViewModel private lateinit var imageAdapter: EditableImageAdapter private var index = 1 private var clickTimes = 1 override fun initEvent() { binding.startSuppliesCheckButton.setOnClickListener { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(this) - return@setOnClickListener - } - if (clickTimes > 1) { AlertControlDialog.Builder() .setContext(this) @@ -98,7 +92,7 @@ } binding.showControlViewButton.setOnClickListener { - BottomControlSheet(this).show() + BottomControlSheet(this, deviceViewModel).show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -137,44 +131,30 @@ } private fun sendCommand() { - lifecycleScope.launch(Dispatchers.IO) { - RuntimeCache.currentScene = CurrentScene.Supply - constructionCheckViewModel.setCurrentPhase( - LocaleConstant.AI_BASE_IP, "before_operation_protection" - ) - withContext(Dispatchers.Main) { + RuntimeCache.currentScene = CurrentScene.Supply + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "before_operation_protection", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) binding.stepView.text = "稍后开始检查第一项:三脚架,请准备" clickTimes++ + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) } - } + ) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) - constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java] - - uploadFileViewModel = ViewModelProvider(this)[UploadFileViewModel::class.java] - uploadFileViewModel.resultModel.observe(this) { - if (it.code == 200) { - val path = it.data.toString() - if (path.isNotBlank()) { - val map = HashMap() - map["id"] = RuntimeCache.uploadFileTaskId - map["deviceCode"] = "YTJ_010002" - map["imageId"] = UUID.randomUUID().toString() - map["scenario"] = "before_operation_protection" - map["image"] = path - map["index"] = index.toString() - map["base64"] = "" - map.upload() - index++ - } - } - } - - sceneViewModel = ViewModelProvider(this)[SceneViewModel::class.java] //动态设置rtspPlayerView宽高 val params = binding.rtspPlayerView.layoutParams as LinearLayout.LayoutParams @@ -206,7 +186,32 @@ override fun onSuccess(file: File) { Log.d(kTag, "absolutePath: ${file.absolutePath}") //上传图片 - uploadFileViewModel.uploadImage(context, file) + uploadFileViewModel.uploadImage( + file, + onLoading = { + LoadingDialog.show(context, "图片上传中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + val path = it.data.toString() + if (path.isNotBlank()) { + val map = HashMap() + map["id"] = RuntimeCache.uploadFileTaskId + map["deviceCode"] = "YTJ_010002" + map["imageId"] = UUID.randomUUID().toString() + map["scenario"] = "before_operation_protection" + map["image"] = path + map["index"] = index.toString() + map["base64"] = "" + map.upload() + index++ + } + }, + onFailed = { + LoadingDialog.dismiss() + it.show(context) + } + ) } override fun onError(e: Throwable) { @@ -241,10 +246,26 @@ } private fun intentActivity() { - sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") - constructionCheckViewModel.setCurrentPhase(LocaleConstant.AI_BASE_IP, "Stop") - SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND) - navigatePageTo() + sceneViewModel.notifyStageFinished(RuntimeCache.uploadFileTaskId, "Supply") {} + constructionCheckViewModel.setCurrentPhase( + LocaleConstant.AI_BASE_IP, + "Stop", + onLoading = { + LoadingDialog.show(this, "指令发送中,请稍后...") + }, + onSuccess = { + LoadingDialog.dismiss() + "指令发送成功".show(this) + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.START_VIDEO_COMMAND_CODE + ) + navigatePageTo() + }, + onFailed = { + LoadingDialog.dismiss() + "指令发送失败,请确认是否处于同一网段".show(this) + } + ) } override fun initViewBinding(): ActivitySuppliesBinding { diff --git a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt b/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt deleted file mode 100644 index 52678e4..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/view/WorkTaskActivity.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.casic.br.operationsite.test.view - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Message -import androidx.lifecycle.ViewModelProvider -import com.casic.br.operationsite.test.R -import com.casic.br.operationsite.test.databinding.ActivityWorkTaskBinding -import com.casic.br.operationsite.test.extensions.combineImagePath -import com.casic.br.operationsite.test.extensions.initImmersionBar -import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.service.TcpMessageService -import com.casic.br.operationsite.test.service.WebSocketService -import com.casic.br.operationsite.test.util.AuthenticationHelper -import com.casic.br.operationsite.test.util.RuntimeCache -import com.casic.br.operationsite.test.vm.LoginViewModel -import com.casic.br.operationsite.test.vm.WorkSiteViewModel -import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter -import com.pengxh.kt.lite.adapter.ViewHolder -import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.divider.RecyclerViewItemDivider -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.ActivityStackManager -import com.pengxh.kt.lite.utils.LoadState -import com.pengxh.kt.lite.utils.LoadingDialogHub -import com.pengxh.kt.lite.utils.WeakReferenceHandler -import com.pengxh.kt.lite.widget.TitleBarView -import com.pengxh.kt.lite.widget.dialog.AlertControlDialog - -class WorkTaskActivity : KotlinBaseActivity(), Handler.Callback { - - private val context = this - private lateinit var weakReferenceHandler: WeakReferenceHandler - private lateinit var workingListAdapter: NormalRecyclerAdapter - private lateinit var workSiteViewModel: WorkSiteViewModel - private lateinit var loginViewModel: LoginViewModel - private var dataBeans: MutableList = ArrayList() - private var page = 1 - private var isRefresh = false - private var isLoadMore = false - - override fun initEvent() { - binding.refreshLayout.setOnRefreshListener { - isRefresh = true - page = 1 - getProjectListByPage() - } - binding.refreshLayout.setOnLoadMoreListener { - isLoadMore = true - page++ - getProjectListByPage() - } - } - - private fun getProjectListByPage() { - workSiteViewModel.getProjectListByPage(this, "", "1", page) - } - - override fun initOnCreate(savedInstanceState: Bundle?) { - ActivityStackManager.addActivity(this) - - weakReferenceHandler = WeakReferenceHandler(this) - - startService(Intent(this, TcpMessageService::class.java)) - startService(Intent(this, WebSocketService::class.java)) - - workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java] - getProjectListByPage() - workSiteViewModel.worksiteModel.observe(this) { - if (it.code == 200) { - val dataRows = it.data?.rows!! - when { - isRefresh -> { - workingListAdapter.setRefreshData(dataRows) - binding.refreshLayout.finishRefresh() - isRefresh = false - } - - isLoadMore -> { - if (dataRows.size == 0) { - "到底了,别拉了".show(this) - } - workingListAdapter.setLoadMoreData(dataRows) - binding.refreshLayout.finishLoadMore() - isLoadMore = false - } - - else -> { - dataBeans = dataRows - weakReferenceHandler.sendEmptyMessage(2022071101) - } - } - } - } - - loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] - loginViewModel.outResultModel.observe(this) { - if (it.code == 200) { - AuthenticationHelper.removeToken() - ActivityStackManager.finishAllActivity() - navigatePageTo() - } - } - } - - override fun handleMessage(msg: Message): Boolean { - if (msg.what == 2022071101) { - workingListAdapter = object : - NormalRecyclerAdapter( - R.layout.item_working_rv, dataBeans - ) { - override fun convertView( - viewHolder: ViewHolder, position: Int, - item: WorkSiteListModel.DataModel.RowsModel - ) { - if (item.imageUrl.isNullOrBlank()) { - viewHolder.setImageResource( - R.id.workSiteImageView, R.mipmap.ic_launcher - ) - } else { - viewHolder.setImageResource( - R.id.workSiteImageView, item.imageUrl.combineImagePath() - ) - } - viewHolder.setText(R.id.workTitleView, item.workTitle) - .setText(R.id.workPersonView, "现场负责人:${item.workPersonName}") - .setText( - R.id.connectionPhoneView, "联系电话:${item.workPersonPhoneNumber}" - ) - .setText(R.id.workSiteView, "现场描述:${item.workSiteDesc}") - } - } - binding.recyclerView.addItemDecoration( - RecyclerViewItemDivider(1, Color.LTGRAY) - ) - binding.recyclerView.adapter = workingListAdapter - workingListAdapter.setOnItemClickedListener(object : - NormalRecyclerAdapter.OnItemClickedListener { - override fun onItemClicked( - position: Int, t: WorkSiteListModel.DataModel.RowsModel - ) { - RuntimeCache.projectId = t.id - RuntimeCache.uploadFileTaskId = System.currentTimeMillis().toString() - navigatePageTo() - } - }) - } - return true - } - - override fun initViewBinding(): ActivityWorkTaskBinding { - return ActivityWorkTaskBinding.inflate(layoutInflater) - } - - override fun observeRequestState() { - workSiteViewModel.loadState.observe(this) { - when (it) { - LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中,请稍后...") - - else -> LoadingDialogHub.dismiss() - } - } - } - - override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) - binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { - override fun onLeftClick() { - finish() - } - - override fun onRightClick() { - AlertControlDialog.Builder() - .setContext(context) - .setTitle("退出登录") - .setMessage("确定要退出吗?") - .setNegativeButton("取消") - .setPositiveButton("确定") - .setOnDialogButtonClickListener(object : - AlertControlDialog.OnDialogButtonClickListener { - override fun onConfirmClick() { - loginViewModel.out() - } - - override fun onCancelClick() {} - }).build().show() - } - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt deleted file mode 100644 index 0a6b01f..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AirViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.AirConditionModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState - -class AirViewModel : BaseViewModel() { - - private val gson = Gson() - val airConditionResult = MutableLiveData() - - fun getAirCondition(context: Context) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getAirCondition() - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - airConditionResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } - } - }, { - loadState.value = LoadState.Fail - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt index 1a83282..f33a4b4 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AlarmViewModel.kt @@ -1,43 +1,37 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.AlarmStateModel import com.casic.br.operationsite.test.model.OtherAlarmStateModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AlarmViewModel : BaseViewModel() { - - private val gson = Gson() - val stateResult = MutableLiveData() - val otherStateResult = MutableLiveData() +class AlarmViewModel : ViewModel() { fun changeAlarmState(httpConfig: String, deviceIp: String, state: String) = launch({ RetrofitServiceManager.changeAlarmState(httpConfig, deviceIp, state) }) - fun getAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getAlarmState( + httpConfig: String, + deviceIp: String, + onLoading: () -> Unit, + onSuccess: (AlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - stateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) /** @@ -52,20 +46,22 @@ /** * 查询其他报警状态 */ - fun getOtherAlarmState(context: Context, httpConfig: String, deviceIp: String) = launch({ + fun getOtherAlarmState( + httpConfig: String, deviceIp: String, + onLoading: () -> Unit, + onSuccess: (OtherAlarmStateModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.getOtherAlarmState(httpConfig, deviceIp) - when (response.getResponseCode()) { - 200 -> { - otherStateResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt index 3f5087f..3a48a76 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/AuthenticateViewModel.kt @@ -1,36 +1,28 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.PublicKeyModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.unpackingResponse -class AuthenticateViewModel : BaseViewModel() { - - private val gson = Gson() - val keyModel = MutableLiveData() - - fun getPublicKey(context: Context) = launch({ +class AuthenticateViewModel : ViewModel() { + fun getPublicKey( + onLoading: () -> Unit, + onSuccess: (PublicKeyModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.authenticate() - when (response.getResponseCode()) { - 200 -> { - keyModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt index 12662a5..7996626 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/ConstructionCheckViewModel.kt @@ -1,19 +1,28 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class ConstructionCheckViewModel : BaseViewModel() { +class ConstructionCheckViewModel : ViewModel() { - val setCurrentPhaseResult = MutableLiveData() - - fun setCurrentPhase(httpConfig: String, phase: String) = launch({ + fun setCurrentPhase( + httpConfig: String, phase: String, + onLoading: () -> Unit, + onSuccess: (Boolean) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.setCurrentPhase(httpConfig, phase) - setCurrentPhaseResult.value = response.getResponseCode() == 200 + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(true) + } else { + onFailed(header.second) + } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt index 6ffe0cf..f0a1314 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/LoginViewModel.kt @@ -1,55 +1,50 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage -import com.casic.br.operationsite.test.model.CommonResultModel +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.LoginResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse -class LoginViewModel : BaseViewModel() { +class LoginViewModel : ViewModel() { - private val gson = Gson() - val enterResultModel = MutableLiveData() - val outResultModel = MutableLiveData() - - fun enter(context: Context, sid: String, account: String, secretKey: String) = launch({ - loadState.value = LoadState.Loading + fun enter( + sid: String, + account: String, + secretKey: String, + onLoading: () -> Unit, + onSuccess: (LoginResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.login(sid, account, secretKey) - when (response.getResponseCode()) { - 200 -> { - enterResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - loadState.value = LoadState.Success - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun out() = launch({ + fun out( + onLoading: () -> Unit, + onSuccess: () -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.loginOut() - val responseCode = response.getResponseCode() - if (responseCode == 200) { - outResultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess() + } else { + onFailed(header.second) } }, { it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt index 6066e32..411e653 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/RegionViewModel.kt @@ -1,18 +1,17 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class RegionViewModel : BaseViewModel() { +class RegionViewModel : ViewModel() { - val setVideoRegionResult = MutableLiveData() - - fun setVideoRegion(stage: String, position: ArrayList) = launch({ + fun setVideoRegion( + stage: String, position: ArrayList, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.setVideoRegion(stage, position) - setVideoRegionResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }, { it.printStackTrace() }) diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt index 205e187..71625a2 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/SceneViewModel.kt @@ -1,17 +1,16 @@ package com.casic.br.operationsite.test.vm -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -class SceneViewModel : BaseViewModel() { +class SceneViewModel : ViewModel() { - val notifyStageResult = MutableLiveData() - - fun notifyStageFinished(operationId: String?, stage: String) = launch({ + fun notifyStageFinished( + operationId: String?, stage: String, onSuccess: (Boolean) -> Unit + ) = launch({ val response = RetrofitServiceManager.notifyStageFinished(operationId, stage) - notifyStageResult.value = response.getResponseCode() == 200 + onSuccess(response.getResponseHeader().first == 200) }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt index c3812df..c65606b 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UploadFileViewModel.kt @@ -1,42 +1,31 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.CommonResultModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse import java.io.File -class UploadFileViewModel : BaseViewModel() { +class UploadFileViewModel : ViewModel() { - private val gson = Gson() - val resultModel = MutableLiveData() - - fun uploadImage(context: Context, image: File) = launch({ - loadState.value = LoadState.Loading + fun uploadImage( + image: File, + onLoading: () -> Unit, + onSuccess: (CommonResultModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() val response = RetrofitServiceManager.uploadImage(image) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - resultModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt deleted file mode 100644 index 2eb48c6..0000000 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/UserDetailViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.br.operationsite.test.vm - -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.model.UserDetailModel -import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.casic.br.operationsite.test.util.LocaleConstant -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel -import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.utils.SaveKeyValues - -class UserDetailViewModel : BaseViewModel() { - - private val gson = Gson() - - //用户信息不用现取现用,布尔值标志用户token是否失效 - val flag = MutableLiveData() - - fun getUserDetail() = launch({ - val response = RetrofitServiceManager.getUserDetail() - when (response.getResponseCode()) { - 200 -> { - val userData = gson.fromJson( - response, object : TypeToken() {}.type - ).data - SaveKeyValues.putValue(LocaleConstant.USER_DETAIL_MODEL, gson.toJson(userData)) - flag.value = true - } - - else -> { - //如果此次获取不到用户信息,那么就清空之前的用户缓存,然后让用户重新登录 - SaveKeyValues.removeKey(LocaleConstant.USER_DETAIL_MODEL) - flag.value = false - } - } - }, { - it.printStackTrace() - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt new file mode 100644 index 0000000..b3f6406 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/UserViewModel.kt @@ -0,0 +1,28 @@ +package com.casic.br.operationsite.test.vm + +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader +import com.casic.br.operationsite.test.model.UserDetailModel +import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.unpackingResponse + +class UserViewModel : ViewModel() { + fun getUserDetail( + onLoading: () -> Unit, + onSuccess: (UserDetailModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getUserDetail() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) + } + }, { + it.printStackTrace() + onFailed(it.message ?: "Unknown error") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt index ee61d75..04a6e61 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/vm/WorkSiteViewModel.kt @@ -1,69 +1,54 @@ package com.casic.br.operationsite.test.vm -import android.content.Context -import androidx.lifecycle.MutableLiveData -import com.casic.br.operationsite.test.extensions.getResponseCode -import com.casic.br.operationsite.test.extensions.getResponseMessage +import androidx.lifecycle.ViewModel +import com.casic.br.operationsite.test.extensions.getResponseHeader import com.casic.br.operationsite.test.model.WorkSiteListModel -import com.casic.br.operationsite.test.model.WorkerModel +import com.casic.br.operationsite.test.model.WorkSiteWorkerModel import com.casic.br.operationsite.test.retrofit.RetrofitServiceManager -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.pengxh.kt.lite.base.BaseViewModel import com.pengxh.kt.lite.extensions.launch -import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.LoadState +import com.pengxh.kt.lite.extensions.unpackingResponse /** * 现场作业ViewModel * */ -class WorkSiteViewModel : BaseViewModel() { - - private val gson = Gson() - val worksiteModel = MutableLiveData() - val workerResult = MutableLiveData() +class WorkSiteViewModel : ViewModel() { fun getProjectListByPage( - context: Context, keywords: String, state: String, page: Int + keywords: String, + state: String, + page: Int, + onLoading: () -> Unit, + onSuccess: (WorkSiteListModel) -> Unit, + onFailed: (String) -> Unit ) = launch({ - loadState.value = LoadState.Loading + onLoading() val response = RetrofitServiceManager.getProjectListByPage(keywords, state, page) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - worksiteModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) - fun getWorkers(context: Context, projectId: String) = launch({ - loadState.value = LoadState.Loading - val response = RetrofitServiceManager.getWorkers(projectId) - when (response.getResponseCode()) { - 200 -> { - loadState.value = LoadState.Success - workerResult.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } - - else -> { - loadState.value = LoadState.Fail - response.getResponseMessage().show(context) - } + fun getWorkSiteWorkers( + onLoading: () -> Unit, + onSuccess: (WorkSiteWorkerModel) -> Unit, + onFailed: (String) -> Unit + ) = launch({ + onLoading() + val response = RetrofitServiceManager.getWorkSiteWorkers() + val header = response.getResponseHeader() + if (header.first == 200) { + onSuccess(unpackingResponse(response)) + } else { + onFailed(header.second) } }, { - loadState.value = LoadState.Fail it.printStackTrace() + onFailed(it.message ?: "Unknown error") }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt index 0ef28fa..5aa28cc 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/AllCommandSheet.kt @@ -3,14 +3,14 @@ import android.app.Dialog import android.content.Context import android.graphics.Color -import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetAllCommandBinding -import com.casic.br.operationsite.test.extensions.convert import com.casic.br.operationsite.test.model.CommandModel -import com.casic.br.operationsite.test.util.tcp.SocketManager +import com.casic.br.operationsite.test.service.SocketConnectionService +import com.casic.br.operationsite.test.util.LocaleConstant import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.adapter.NormalRecyclerAdapter @@ -21,7 +21,6 @@ import com.pengxh.kt.lite.extensions.getScreenHeight import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.readAssetsFile -import com.pengxh.kt.lite.extensions.show class AllCommandSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle) { @@ -31,7 +30,7 @@ private fun Dialog.resetParams() { val window = this.window ?: return - window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) window.decorView.setBackgroundColor(Color.TRANSPARENT) window.setGravity(Gravity.BOTTOM) //设置Dialog出现的动画 @@ -66,11 +65,12 @@ commandAdapter.setOnItemClickedListener(object : NormalRecyclerAdapter.OnItemClickedListener { override fun onItemClicked(position: Int, t: CommandModel) { - if (!SocketManager.get.nettyClient.connectStatus) { - "指令发送失败,请确认是否处于同一网段".show(context) - return + SocketConnectionService.weakReferenceHandler?.let { + val message = it.obtainMessage() + message.what = LocaleConstant.COMMAND_TEST_CODE + message.obj = t.command + it.sendMessage(message) } - SocketManager.get.send(t.command.convert()) } }) binding.sheetCancelButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt index db6bbcc..80ee657 100644 --- a/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt +++ b/app/src/main/java/com/casic/br/operationsite/test/widget/BottomControlSheet.kt @@ -3,42 +3,43 @@ import android.annotation.SuppressLint import android.app.Dialog import android.content.Context +import android.graphics.Color import android.os.Bundle import android.view.Gravity import android.view.MotionEvent -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner +import android.view.WindowManager +import androidx.core.graphics.drawable.toDrawable import com.casic.br.operationsite.test.R import com.casic.br.operationsite.test.databinding.SheetBottomControlBinding import com.casic.br.operationsite.test.util.LocaleConstant import com.casic.br.operationsite.test.vm.DeviceViewModel import com.pengxh.kt.lite.extensions.binding -import com.pengxh.kt.lite.extensions.resetParams +import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.utils.SaveKeyValues -class BottomControlSheet(context: Context) : Dialog(context, R.style.BottomControlSheetStyle), - ViewModelStoreOwner { +class BottomControlSheet( + private val context: Context, + private val deviceViewModel: DeviceViewModel +) : Dialog(context, R.style.BottomControlSheetStyle) { private val kTag = "BottomControlSheet" private val binding: SheetBottomControlBinding by binding() - private lateinit var viewModelStore: ViewModelStore - private lateinit var deviceViewModel: DeviceViewModel private var speed = 5 - override fun getViewModelStore(): ViewModelStore { - return viewModelStore - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - viewModelStore.clear() - } - @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - this.resetParams(Gravity.BOTTOM, R.style.ActionSheetDialogAnimation, 1f) + val window = this.window ?: return + window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.BOTTOM) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.ActionSheetDialogAnimation) + val params = window.attributes + params.width = context.getScreenWidth() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + setCancelable(true) setCanceledOnTouchOutside(true) @@ -50,9 +51,6 @@ LocaleConstant.DEVICE_CONTROL_SERVER_CONFIG, LocaleConstant.CAMERA_IP ) - viewModelStore = ViewModelStore() - deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] - binding.leftButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> executeCommand("Left") diff --git a/app/src/main/res/drawable/button_check_selector.xml b/app/src/main/res/drawable/button_check_selector.xml deleted file mode 100644 index 46c4f6b..0000000 --- a/app/src/main/res/drawable/button_check_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index fb34d0e..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml index b0b948c..88592cd 100644 --- a/app/src/main/res/layout/activity_big_image.xml +++ b/app/src/main/res/layout/activity_big_image.xml @@ -1,41 +1,35 @@ - + android:background="@color/black"> - + android:layout_height="match_parent" /> - + - + android:layout_centerVertical="true" + android:layout_marginStart="@dimen/lib_dp_10" + android:src="@drawable/ic_title_left" /> - - - - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_disclosure.xml b/app/src/main/res/layout/activity_disclosure.xml index c8fc741..e8336a9 100644 --- a/app/src/main/res/layout/activity_disclosure.xml +++ b/app/src/main/res/layout/activity_disclosure.xml @@ -13,12 +13,11 @@ android:layout_height="wrap_content" android:background="@color/mainThemeColor" app:tbv_left_image="@drawable/ic_title_left" - app:tbv_only_show_title="false" app:tbv_show_left_image="true" app:tbv_show_right_image="false" + app:tbv_smaller_title="true" app:tbv_text="现场交底" - app:tbv_text_color="@color/white" - app:tbv_text_size="@dimen/sp_18" /> + app:tbv_text_color="@color/white" /> + android:text="开始交底" />