diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 35c9024..2ea7409 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -91,6 +91,10 @@ + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 35c9024..2ea7409 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -91,6 +91,10 @@ + + diff --git a/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt new file mode 100644 index 0000000..239d538 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt @@ -0,0 +1,153 @@ +package com.casic.br.operationsite.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.R +import com.casic.br.operationsite.utils.CommandCreator +import com.casic.br.operationsite.utils.LocaleConstant +import com.casic.br.operationsite.utils.OnTcpConnectStateListener +import com.casic.br.operationsite.utils.TcpClient +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler + +class CameraInspectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + private val kTag = "InspectionService" + private val notificationId = 2 + 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 handleMessage(msg: Message): Boolean { + when (msg.what) { + LocaleConstant.CONNECT_CAMERA_TCP_CODE -> { + tcpClient.start() + } + + LocaleConstant.ADD_POINT_CODE -> { + if (lineIndex < 8) { + if (pointIndex >= 8) { + //如果一条线添加满了,则换一条线 + lineIndex++ + pointIndex = 1 + } + //先设置一级类(92,表示巡航) + weakReferenceHandler?.post(firstTypeRunnable) + } else { + "最多能添加8条巡航线".show(this) + } + } + } + return true + } + + private val firstTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(92)) + Log.d(kTag, "run: 设置一级类") + //再设置二级类(01~08,表示巡航线) + weakReferenceHandler?.postDelayed(secondTypeRunnable, 500) + } + } + + private var lineIndex = 1 + + private val secondTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(lineIndex)) + Log.d(kTag, "run: 设置二级类 ===> $lineIndex") + //最后设置三级类(01~08,表示巡航点) + weakReferenceHandler?.postDelayed(thirdTypeRunnable, 500) + } + } + + private var pointIndex = 1 + + private val thirdTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(pointIndex)) + Log.d(kTag, "run: 设置三级类 ===> $pointIndex") + pointIndex++ + } + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "camera_inspection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for camera inspection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "camera_inspection_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) + } + val cameraIP = SaveKeyValues.getValue( + LocaleConstant.SAFE_TREE_CAMERA_IP_KEY, "192.168.10.137" + ) as String + tcpClient.start(cameraIP, LocaleConstant.CAMERA_TCP_PORT) + Log.d(kTag, "onStartCommand: CameraInspectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("自动巡航服务已连接") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("自动巡航服务断开连接") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("自动巡航服务连接出错,开始重连") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + Log.d(kTag, bytes.contentToString()) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: CameraInspectionService") + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 35c9024..2ea7409 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -91,6 +91,10 @@ + + diff --git a/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt new file mode 100644 index 0000000..239d538 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt @@ -0,0 +1,153 @@ +package com.casic.br.operationsite.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.R +import com.casic.br.operationsite.utils.CommandCreator +import com.casic.br.operationsite.utils.LocaleConstant +import com.casic.br.operationsite.utils.OnTcpConnectStateListener +import com.casic.br.operationsite.utils.TcpClient +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler + +class CameraInspectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + private val kTag = "InspectionService" + private val notificationId = 2 + 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 handleMessage(msg: Message): Boolean { + when (msg.what) { + LocaleConstant.CONNECT_CAMERA_TCP_CODE -> { + tcpClient.start() + } + + LocaleConstant.ADD_POINT_CODE -> { + if (lineIndex < 8) { + if (pointIndex >= 8) { + //如果一条线添加满了,则换一条线 + lineIndex++ + pointIndex = 1 + } + //先设置一级类(92,表示巡航) + weakReferenceHandler?.post(firstTypeRunnable) + } else { + "最多能添加8条巡航线".show(this) + } + } + } + return true + } + + private val firstTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(92)) + Log.d(kTag, "run: 设置一级类") + //再设置二级类(01~08,表示巡航线) + weakReferenceHandler?.postDelayed(secondTypeRunnable, 500) + } + } + + private var lineIndex = 1 + + private val secondTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(lineIndex)) + Log.d(kTag, "run: 设置二级类 ===> $lineIndex") + //最后设置三级类(01~08,表示巡航点) + weakReferenceHandler?.postDelayed(thirdTypeRunnable, 500) + } + } + + private var pointIndex = 1 + + private val thirdTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(pointIndex)) + Log.d(kTag, "run: 设置三级类 ===> $pointIndex") + pointIndex++ + } + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "camera_inspection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for camera inspection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "camera_inspection_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) + } + val cameraIP = SaveKeyValues.getValue( + LocaleConstant.SAFE_TREE_CAMERA_IP_KEY, "192.168.10.137" + ) as String + tcpClient.start(cameraIP, LocaleConstant.CAMERA_TCP_PORT) + Log.d(kTag, "onStartCommand: CameraInspectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("自动巡航服务已连接") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("自动巡航服务断开连接") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("自动巡航服务连接出错,开始重连") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + Log.d(kTag, bytes.contentToString()) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: CameraInspectionService") + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt index aadb0b7..ee75550 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt @@ -214,4 +214,36 @@ fun closeVoiceTips(): ByteArray { return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x97.toByte(), 0x00, 0x00, 0x98.toByte()) } + + /** + * 添加预置点,范围:1~255 + * + * + * 只要是设置巡航点,就都要先调用一个92号预置位,再调用1号预置位,开始设置巡航点, + * 然后添加点位的才是实际的巡航点, + * 最后再调用一次92和9预置位保存巡航点信息 + * */ + fun addPoint(index: Int): ByteArray { + val bytes = byteArrayOf( + 0xFF.toByte(), + 0x01, + 0x00, + 0x03.toByte(), + 0x00.toByte(), + 0x00.toByte(), + 0x00.toByte() + ) + + // 将 index 转换为 2 字节的高位和低位 + bytes[4] = (index ushr 8).toByte() // 高位字节 + bytes[5] = (index and 0xFF).toByte() // 低位字节 + + //计算校验位。 + var sum = 0 + for (l in 1 until bytes.size - 1) { + sum += bytes[l] + } + bytes[6] = sum.toByte() + return bytes + } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 35c9024..2ea7409 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -91,6 +91,10 @@ + + diff --git a/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt new file mode 100644 index 0000000..239d538 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/service/CameraInspectionService.kt @@ -0,0 +1,153 @@ +package com.casic.br.operationsite.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.R +import com.casic.br.operationsite.utils.CommandCreator +import com.casic.br.operationsite.utils.LocaleConstant +import com.casic.br.operationsite.utils.OnTcpConnectStateListener +import com.casic.br.operationsite.utils.TcpClient +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.utils.WeakReferenceHandler + +class CameraInspectionService : Service(), OnTcpConnectStateListener, Handler.Callback { + + companion object { + var weakReferenceHandler: WeakReferenceHandler? = null + } + + private val kTag = "InspectionService" + private val notificationId = 2 + 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 handleMessage(msg: Message): Boolean { + when (msg.what) { + LocaleConstant.CONNECT_CAMERA_TCP_CODE -> { + tcpClient.start() + } + + LocaleConstant.ADD_POINT_CODE -> { + if (lineIndex < 8) { + if (pointIndex >= 8) { + //如果一条线添加满了,则换一条线 + lineIndex++ + pointIndex = 1 + } + //先设置一级类(92,表示巡航) + weakReferenceHandler?.post(firstTypeRunnable) + } else { + "最多能添加8条巡航线".show(this) + } + } + } + return true + } + + private val firstTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(92)) + Log.d(kTag, "run: 设置一级类") + //再设置二级类(01~08,表示巡航线) + weakReferenceHandler?.postDelayed(secondTypeRunnable, 500) + } + } + + private var lineIndex = 1 + + private val secondTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(lineIndex)) + Log.d(kTag, "run: 设置二级类 ===> $lineIndex") + //最后设置三级类(01~08,表示巡航点) + weakReferenceHandler?.postDelayed(thirdTypeRunnable, 500) + } + } + + private var pointIndex = 1 + + private val thirdTypeRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.addPoint(pointIndex)) + Log.d(kTag, "run: 设置三级类 ===> $pointIndex") + pointIndex++ + } + } + + override fun onCreate() { + super.onCreate() + val name = "${resources.getString(R.string.app_name)}前台服务" + val channel = NotificationChannel( + "camera_inspection_service_channel", name, NotificationManager.IMPORTANCE_HIGH + ) + channel.description = "Channel for camera inspection service" + notificationManager.createNotificationChannel(channel) + notificationBuilder = NotificationCompat.Builder(this, "camera_inspection_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) + } + val cameraIP = SaveKeyValues.getValue( + LocaleConstant.SAFE_TREE_CAMERA_IP_KEY, "192.168.10.137" + ) as String + tcpClient.start(cameraIP, LocaleConstant.CAMERA_TCP_PORT) + Log.d(kTag, "onStartCommand: CameraInspectionService") + return START_STICKY + } + + override fun onConnected() { + notificationBuilder?.setContentTitle("自动巡航服务已连接") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onDisconnected() { + notificationBuilder?.setContentTitle("自动巡航服务断开连接") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onConnectFailed() { + notificationBuilder?.setContentTitle("自动巡航服务连接出错,开始重连") + val notification = notificationBuilder?.build() + notificationManager.notify(notificationId, notification) + } + + override fun onMessageReceived(bytes: ByteArray?) { + if (bytes == null) { + return + } + Log.d(kTag, bytes.contentToString()) + } + + override fun onDestroy() { + super.onDestroy() + tcpClient.stop(false) + stopForeground(STOP_FOREGROUND_REMOVE) + Log.d(kTag, "onDestroy: CameraInspectionService") + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt index aadb0b7..ee75550 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt @@ -214,4 +214,36 @@ fun closeVoiceTips(): ByteArray { return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x97.toByte(), 0x00, 0x00, 0x98.toByte()) } + + /** + * 添加预置点,范围:1~255 + * + * + * 只要是设置巡航点,就都要先调用一个92号预置位,再调用1号预置位,开始设置巡航点, + * 然后添加点位的才是实际的巡航点, + * 最后再调用一次92和9预置位保存巡航点信息 + * */ + fun addPoint(index: Int): ByteArray { + val bytes = byteArrayOf( + 0xFF.toByte(), + 0x01, + 0x00, + 0x03.toByte(), + 0x00.toByte(), + 0x00.toByte(), + 0x00.toByte() + ) + + // 将 index 转换为 2 字节的高位和低位 + bytes[4] = (index ushr 8).toByte() // 高位字节 + bytes[5] = (index and 0xFF).toByte() // 低位字节 + + //计算校验位。 + var sum = 0 + for (l in 1 until bytes.size - 1) { + sum += bytes[l] + } + bytes[6] = sum.toByte() + return bytes + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/DeviceControlActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/DeviceControlActivity.kt index b6f3685..0b52ab4 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/DeviceControlActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/DeviceControlActivity.kt @@ -1,6 +1,7 @@ package com.casic.br.operationsite.view import android.content.Intent +import android.graphics.Color import android.os.Bundle import android.os.Handler import android.os.Message @@ -26,6 +27,7 @@ import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.TitleBarView +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet class DeviceControlActivity : KotlinBaseActivity(), Handler.Callback { @@ -110,7 +112,27 @@ } override fun onRightClick() { - SocketConnectionService.weakReferenceHandler?.sendEmptyMessage(LocaleConstant.CONNECT_TCP_CODE) + BottomActionSheet.Builder() + .setContext(this@DeviceControlActivity) + .setActionItemTitle(arrayListOf("重连甲烷检测服务", "重连自动巡航服务")) + .setItemTextColor(Color.BLUE) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> { + SocketConnectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONNECT_TCP_CODE + ) + } + + 1 -> { + CameraInspectionService.weakReferenceHandler?.sendEmptyMessage( + LocaleConstant.CONNECT_CAMERA_TCP_CODE + ) + } + } + } + }).build().show() } }) }