diff --git a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt index 974e131..c976447 100644 --- a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt +++ b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt @@ -1,13 +1,11 @@ package com.casic.common.detector.gd.service import android.app.Service -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.os.Handler import android.os.IBinder import android.os.Message +import android.util.Base64 import android.util.Log import android.view.Gravity import android.widget.Toast @@ -20,20 +18,19 @@ import com.casic.common.detector.gd.utils.LocaleConstant import com.casic.common.detector.gd.utils.NtripAuthorizationCreator import com.casic.common.detector.gd.utils.RtkLocationTool -import com.casic.common.detector.gd.utils.tcp.ConnectState -import com.casic.common.detector.gd.utils.tcp.OnSocketConnectListener -import com.casic.common.detector.gd.utils.tcp.SocketClient import com.casic.common.detector.gd.view.MainActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler -import io.netty.buffer.Unpooled +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.OutputStream import java.nio.charset.StandardCharsets -class NtripConnectService : Service(), LifecycleOwner, OnSocketConnectListener, Handler.Callback { + +class NtripConnectService : Service(), LifecycleOwner, OnTcpConnectStateListener, Handler.Callback { companion object { var weakReferenceHandler: WeakReferenceHandler? = null @@ -41,10 +38,8 @@ private val kTag = "NtripConnectService" private val registry = LifecycleRegistry(this) - private var connectState = ConnectState.CLOSED - private var serialPortService: SerialPortService? = null + private val socketClient by lazy { TcpClient(this) } private var outStream: OutputStream? = null - private lateinit var socketClient: SocketClient override fun getLifecycle(): Lifecycle { return registry @@ -66,10 +61,8 @@ override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) - //绑定串口通信服务 - Intent(this, SerialPortService::class.java).also { - bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) - } + + connectQianXunServer() RtkLocationTool.getCurrentLocation(this) { val weakHandler = MainActivity.weakReferenceHandler ?: return@getCurrentLocation @@ -78,85 +71,96 @@ message.obj = "${it.longitude},${it.latitude}" weakHandler.sendMessage(message) - if (connectState == ConnectState.SUCCESS) { + if (socketClient.isRunning()) { //连接成功就发送千寻请求报文 val gga = it.convertToGPGGA() Log.d(kTag, gga) - socketClient.sendData(gga) + socketClient.sendMessage(gga.toByteArray()) } } } - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { - if (iBinder is SerialPortService.ServiceBinder) { - serialPortService = iBinder.getSerialPortService() - Log.d(kTag, "onServiceConnected: 服务已绑定") + /** + * Ntrip服务器需要两步验证: + * 第一步是connect, + * 第二步是发送check cmd。 + * 这二步是连续的,要不然服务器就会拒绝,显示一连就失败 + * */ + override fun onConnected() { + //连接成功就发送千寻请求报文 + val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String + val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String + + // base64加密用户名和密码 + val byteArray = "$account:$pwd".toByteArray() + val base64 = Base64.encodeToString(byteArray, Base64.DEFAULT) + + val msg = NtripAuthorizationCreator() + .append("GET /RTCM32_GGB HTTP/1.1") + .append("Host: ${LocaleConstant.QX_RTK_HOST}") + .append("Ntrip-Version: Ntrip/2.0") + .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") + .append("Accept: */*") + .append("Connection: close") + .append("Accept:*/*") + .append("Authorization: Basic $base64") + .toString() + socketClient.sendMessage(msg.toByteArray()) + } + + override fun onConnectFailed() { + + } + + override fun onDisconnected() { + + } + + override fun onMessageReceived(bytes: ByteArray?) { + bytes?.apply { + if (size == 14) { + /** + * 连接成功 + *

+ * ICY 200 OK + * */ + val result = String(this, StandardCharsets.UTF_8) + if (result.contains("ICY 200 OK")) { + lifecycleScope.launch(Dispatchers.Main) { + "高精度定位服务连接成功".show(this@NtripConnectService) + } + //连接服务即打开串口 + outStream = BaseApplication.get().getSerialPorts().first().outputStream + } + } else if (size == 153) { + Log.d(kTag, String(this, StandardCharsets.UTF_8)) + /** + * 账号到期 + *

+ * HTTP 401 Unauthorized + * Server: POP_GW_Ntrip_1.0_1729082016/1.0 + * Via: n108_10 + * Date: 2024/11/08 14:01:18 + * Content-Type: text/plain + * Connection: clos + * */ + lifecycleScope.launch(Dispatchers.Main) { + "差分定位服务鉴权失败,无法解析位置".show(this@NtripConnectService) + } + } else { + //居中显示 + lifecycleScope.launch(Dispatchers.Main) { + val toast = Toast.makeText( + this@NtripConnectService, "收到千寻数据,长度:${size}", Toast.LENGTH_SHORT + ) + toast.setGravity(Gravity.CENTER, 0, 0) + toast.show() + } + + outStream?.write(this) + outStream?.flush() } } - - override fun onServiceDisconnected(name: ComponentName?) { - - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - lifecycleScope.launch(Dispatchers.IO) { - connectQianXunServer() - } - return START_STICKY - } - - override fun onMessageResponse(data: ByteArray) { - if (data.size == 14) { - /** - * 连接成功,登录会返回 ICY 200 OK - *

- * 0d0a0d0a -> \r\n\r\n - * */ - val result = String(data, StandardCharsets.UTF_8) - if (result.contains("ICY 200 OK")) { - "高精度定位服务连接成功".show(this) - //连接服务即打开串口 - outStream = BaseApplication.get().getSerialPorts().first().outputStream - } - } else { - //居中显示 - val toast = Toast.makeText(this, "收到千寻数据,长度:${data.size}", Toast.LENGTH_SHORT) - toast.setGravity(Gravity.CENTER, 0, 0) - toast.show() - - outStream?.write(data) - outStream?.flush() - } - } - - override fun onServiceConnectStatusChanged(status: ConnectState) { - this.connectState = status - Log.d(kTag, "onServiceConnectStatusChanged: $status") - if (connectState == ConnectState.SUCCESS) { - //连接成功就发送千寻请求报文 - val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String - val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String - - // base64加密用户名和密码 - val byteArray = "$account:$pwd".toByteArray() - val base64 = android.util.Base64.encodeToString(byteArray, android.util.Base64.DEFAULT) - - val msg = NtripAuthorizationCreator() - .append("GET /RTCM32_GGB HTTP/1.1") - .append("Host: ${LocaleConstant.QX_RTK_HOST}") - .append("Ntrip-Version: Ntrip/2.0") - .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") - .append("Accept: */*") - .append("Connection: close") - .append("Accept:*/*") - .append("Authorization: Basic $base64") - .toString() - - val byteBuf = Unpooled.wrappedBuffer(msg.toByteArray()) - socketClient.sendData(byteBuf) - } } private fun connectQianXunServer() { @@ -168,17 +172,10 @@ LocaleConstant.RTK_PORT, "8003" ) as String - socketClient = SocketClient.Builder() - .setHostname(remoteHost) - .setPort(remotePort.toInt()) - .setTimeout(5000) - .setOnSocketListener(this) - .build() - socketClient.connect() - } + if (socketClient.isRunning()) { + return + } - override fun onDestroy() { - super.onDestroy() - unbindService(serviceConnection) + socketClient.start(remoteHost, remotePort.toInt()) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt index 974e131..c976447 100644 --- a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt +++ b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt @@ -1,13 +1,11 @@ package com.casic.common.detector.gd.service import android.app.Service -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.os.Handler import android.os.IBinder import android.os.Message +import android.util.Base64 import android.util.Log import android.view.Gravity import android.widget.Toast @@ -20,20 +18,19 @@ import com.casic.common.detector.gd.utils.LocaleConstant import com.casic.common.detector.gd.utils.NtripAuthorizationCreator import com.casic.common.detector.gd.utils.RtkLocationTool -import com.casic.common.detector.gd.utils.tcp.ConnectState -import com.casic.common.detector.gd.utils.tcp.OnSocketConnectListener -import com.casic.common.detector.gd.utils.tcp.SocketClient import com.casic.common.detector.gd.view.MainActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler -import io.netty.buffer.Unpooled +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.OutputStream import java.nio.charset.StandardCharsets -class NtripConnectService : Service(), LifecycleOwner, OnSocketConnectListener, Handler.Callback { + +class NtripConnectService : Service(), LifecycleOwner, OnTcpConnectStateListener, Handler.Callback { companion object { var weakReferenceHandler: WeakReferenceHandler? = null @@ -41,10 +38,8 @@ private val kTag = "NtripConnectService" private val registry = LifecycleRegistry(this) - private var connectState = ConnectState.CLOSED - private var serialPortService: SerialPortService? = null + private val socketClient by lazy { TcpClient(this) } private var outStream: OutputStream? = null - private lateinit var socketClient: SocketClient override fun getLifecycle(): Lifecycle { return registry @@ -66,10 +61,8 @@ override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) - //绑定串口通信服务 - Intent(this, SerialPortService::class.java).also { - bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) - } + + connectQianXunServer() RtkLocationTool.getCurrentLocation(this) { val weakHandler = MainActivity.weakReferenceHandler ?: return@getCurrentLocation @@ -78,85 +71,96 @@ message.obj = "${it.longitude},${it.latitude}" weakHandler.sendMessage(message) - if (connectState == ConnectState.SUCCESS) { + if (socketClient.isRunning()) { //连接成功就发送千寻请求报文 val gga = it.convertToGPGGA() Log.d(kTag, gga) - socketClient.sendData(gga) + socketClient.sendMessage(gga.toByteArray()) } } } - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { - if (iBinder is SerialPortService.ServiceBinder) { - serialPortService = iBinder.getSerialPortService() - Log.d(kTag, "onServiceConnected: 服务已绑定") + /** + * Ntrip服务器需要两步验证: + * 第一步是connect, + * 第二步是发送check cmd。 + * 这二步是连续的,要不然服务器就会拒绝,显示一连就失败 + * */ + override fun onConnected() { + //连接成功就发送千寻请求报文 + val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String + val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String + + // base64加密用户名和密码 + val byteArray = "$account:$pwd".toByteArray() + val base64 = Base64.encodeToString(byteArray, Base64.DEFAULT) + + val msg = NtripAuthorizationCreator() + .append("GET /RTCM32_GGB HTTP/1.1") + .append("Host: ${LocaleConstant.QX_RTK_HOST}") + .append("Ntrip-Version: Ntrip/2.0") + .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") + .append("Accept: */*") + .append("Connection: close") + .append("Accept:*/*") + .append("Authorization: Basic $base64") + .toString() + socketClient.sendMessage(msg.toByteArray()) + } + + override fun onConnectFailed() { + + } + + override fun onDisconnected() { + + } + + override fun onMessageReceived(bytes: ByteArray?) { + bytes?.apply { + if (size == 14) { + /** + * 连接成功 + *

+ * ICY 200 OK + * */ + val result = String(this, StandardCharsets.UTF_8) + if (result.contains("ICY 200 OK")) { + lifecycleScope.launch(Dispatchers.Main) { + "高精度定位服务连接成功".show(this@NtripConnectService) + } + //连接服务即打开串口 + outStream = BaseApplication.get().getSerialPorts().first().outputStream + } + } else if (size == 153) { + Log.d(kTag, String(this, StandardCharsets.UTF_8)) + /** + * 账号到期 + *

+ * HTTP 401 Unauthorized + * Server: POP_GW_Ntrip_1.0_1729082016/1.0 + * Via: n108_10 + * Date: 2024/11/08 14:01:18 + * Content-Type: text/plain + * Connection: clos + * */ + lifecycleScope.launch(Dispatchers.Main) { + "差分定位服务鉴权失败,无法解析位置".show(this@NtripConnectService) + } + } else { + //居中显示 + lifecycleScope.launch(Dispatchers.Main) { + val toast = Toast.makeText( + this@NtripConnectService, "收到千寻数据,长度:${size}", Toast.LENGTH_SHORT + ) + toast.setGravity(Gravity.CENTER, 0, 0) + toast.show() + } + + outStream?.write(this) + outStream?.flush() } } - - override fun onServiceDisconnected(name: ComponentName?) { - - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - lifecycleScope.launch(Dispatchers.IO) { - connectQianXunServer() - } - return START_STICKY - } - - override fun onMessageResponse(data: ByteArray) { - if (data.size == 14) { - /** - * 连接成功,登录会返回 ICY 200 OK - *

- * 0d0a0d0a -> \r\n\r\n - * */ - val result = String(data, StandardCharsets.UTF_8) - if (result.contains("ICY 200 OK")) { - "高精度定位服务连接成功".show(this) - //连接服务即打开串口 - outStream = BaseApplication.get().getSerialPorts().first().outputStream - } - } else { - //居中显示 - val toast = Toast.makeText(this, "收到千寻数据,长度:${data.size}", Toast.LENGTH_SHORT) - toast.setGravity(Gravity.CENTER, 0, 0) - toast.show() - - outStream?.write(data) - outStream?.flush() - } - } - - override fun onServiceConnectStatusChanged(status: ConnectState) { - this.connectState = status - Log.d(kTag, "onServiceConnectStatusChanged: $status") - if (connectState == ConnectState.SUCCESS) { - //连接成功就发送千寻请求报文 - val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String - val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String - - // base64加密用户名和密码 - val byteArray = "$account:$pwd".toByteArray() - val base64 = android.util.Base64.encodeToString(byteArray, android.util.Base64.DEFAULT) - - val msg = NtripAuthorizationCreator() - .append("GET /RTCM32_GGB HTTP/1.1") - .append("Host: ${LocaleConstant.QX_RTK_HOST}") - .append("Ntrip-Version: Ntrip/2.0") - .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") - .append("Accept: */*") - .append("Connection: close") - .append("Accept:*/*") - .append("Authorization: Basic $base64") - .toString() - - val byteBuf = Unpooled.wrappedBuffer(msg.toByteArray()) - socketClient.sendData(byteBuf) - } } private fun connectQianXunServer() { @@ -168,17 +172,10 @@ LocaleConstant.RTK_PORT, "8003" ) as String - socketClient = SocketClient.Builder() - .setHostname(remoteHost) - .setPort(remotePort.toInt()) - .setTimeout(5000) - .setOnSocketListener(this) - .build() - socketClient.connect() - } + if (socketClient.isRunning()) { + return + } - override fun onDestroy() { - super.onDestroy() - unbindService(serviceConnection) + socketClient.start(remoteHost, remotePort.toInt()) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt deleted file mode 100644 index c1707b4..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -enum class ConnectState { - /** - * 连接成功 - */ - SUCCESS, - - /** - * 关闭连接 - */ - CLOSED, - - /** - * 连接失败 - */ - ERROR -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt index 974e131..c976447 100644 --- a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt +++ b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt @@ -1,13 +1,11 @@ package com.casic.common.detector.gd.service import android.app.Service -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.os.Handler import android.os.IBinder import android.os.Message +import android.util.Base64 import android.util.Log import android.view.Gravity import android.widget.Toast @@ -20,20 +18,19 @@ import com.casic.common.detector.gd.utils.LocaleConstant import com.casic.common.detector.gd.utils.NtripAuthorizationCreator import com.casic.common.detector.gd.utils.RtkLocationTool -import com.casic.common.detector.gd.utils.tcp.ConnectState -import com.casic.common.detector.gd.utils.tcp.OnSocketConnectListener -import com.casic.common.detector.gd.utils.tcp.SocketClient import com.casic.common.detector.gd.view.MainActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler -import io.netty.buffer.Unpooled +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.OutputStream import java.nio.charset.StandardCharsets -class NtripConnectService : Service(), LifecycleOwner, OnSocketConnectListener, Handler.Callback { + +class NtripConnectService : Service(), LifecycleOwner, OnTcpConnectStateListener, Handler.Callback { companion object { var weakReferenceHandler: WeakReferenceHandler? = null @@ -41,10 +38,8 @@ private val kTag = "NtripConnectService" private val registry = LifecycleRegistry(this) - private var connectState = ConnectState.CLOSED - private var serialPortService: SerialPortService? = null + private val socketClient by lazy { TcpClient(this) } private var outStream: OutputStream? = null - private lateinit var socketClient: SocketClient override fun getLifecycle(): Lifecycle { return registry @@ -66,10 +61,8 @@ override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) - //绑定串口通信服务 - Intent(this, SerialPortService::class.java).also { - bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) - } + + connectQianXunServer() RtkLocationTool.getCurrentLocation(this) { val weakHandler = MainActivity.weakReferenceHandler ?: return@getCurrentLocation @@ -78,85 +71,96 @@ message.obj = "${it.longitude},${it.latitude}" weakHandler.sendMessage(message) - if (connectState == ConnectState.SUCCESS) { + if (socketClient.isRunning()) { //连接成功就发送千寻请求报文 val gga = it.convertToGPGGA() Log.d(kTag, gga) - socketClient.sendData(gga) + socketClient.sendMessage(gga.toByteArray()) } } } - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { - if (iBinder is SerialPortService.ServiceBinder) { - serialPortService = iBinder.getSerialPortService() - Log.d(kTag, "onServiceConnected: 服务已绑定") + /** + * Ntrip服务器需要两步验证: + * 第一步是connect, + * 第二步是发送check cmd。 + * 这二步是连续的,要不然服务器就会拒绝,显示一连就失败 + * */ + override fun onConnected() { + //连接成功就发送千寻请求报文 + val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String + val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String + + // base64加密用户名和密码 + val byteArray = "$account:$pwd".toByteArray() + val base64 = Base64.encodeToString(byteArray, Base64.DEFAULT) + + val msg = NtripAuthorizationCreator() + .append("GET /RTCM32_GGB HTTP/1.1") + .append("Host: ${LocaleConstant.QX_RTK_HOST}") + .append("Ntrip-Version: Ntrip/2.0") + .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") + .append("Accept: */*") + .append("Connection: close") + .append("Accept:*/*") + .append("Authorization: Basic $base64") + .toString() + socketClient.sendMessage(msg.toByteArray()) + } + + override fun onConnectFailed() { + + } + + override fun onDisconnected() { + + } + + override fun onMessageReceived(bytes: ByteArray?) { + bytes?.apply { + if (size == 14) { + /** + * 连接成功 + *

+ * ICY 200 OK + * */ + val result = String(this, StandardCharsets.UTF_8) + if (result.contains("ICY 200 OK")) { + lifecycleScope.launch(Dispatchers.Main) { + "高精度定位服务连接成功".show(this@NtripConnectService) + } + //连接服务即打开串口 + outStream = BaseApplication.get().getSerialPorts().first().outputStream + } + } else if (size == 153) { + Log.d(kTag, String(this, StandardCharsets.UTF_8)) + /** + * 账号到期 + *

+ * HTTP 401 Unauthorized + * Server: POP_GW_Ntrip_1.0_1729082016/1.0 + * Via: n108_10 + * Date: 2024/11/08 14:01:18 + * Content-Type: text/plain + * Connection: clos + * */ + lifecycleScope.launch(Dispatchers.Main) { + "差分定位服务鉴权失败,无法解析位置".show(this@NtripConnectService) + } + } else { + //居中显示 + lifecycleScope.launch(Dispatchers.Main) { + val toast = Toast.makeText( + this@NtripConnectService, "收到千寻数据,长度:${size}", Toast.LENGTH_SHORT + ) + toast.setGravity(Gravity.CENTER, 0, 0) + toast.show() + } + + outStream?.write(this) + outStream?.flush() } } - - override fun onServiceDisconnected(name: ComponentName?) { - - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - lifecycleScope.launch(Dispatchers.IO) { - connectQianXunServer() - } - return START_STICKY - } - - override fun onMessageResponse(data: ByteArray) { - if (data.size == 14) { - /** - * 连接成功,登录会返回 ICY 200 OK - *

- * 0d0a0d0a -> \r\n\r\n - * */ - val result = String(data, StandardCharsets.UTF_8) - if (result.contains("ICY 200 OK")) { - "高精度定位服务连接成功".show(this) - //连接服务即打开串口 - outStream = BaseApplication.get().getSerialPorts().first().outputStream - } - } else { - //居中显示 - val toast = Toast.makeText(this, "收到千寻数据,长度:${data.size}", Toast.LENGTH_SHORT) - toast.setGravity(Gravity.CENTER, 0, 0) - toast.show() - - outStream?.write(data) - outStream?.flush() - } - } - - override fun onServiceConnectStatusChanged(status: ConnectState) { - this.connectState = status - Log.d(kTag, "onServiceConnectStatusChanged: $status") - if (connectState == ConnectState.SUCCESS) { - //连接成功就发送千寻请求报文 - val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String - val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String - - // base64加密用户名和密码 - val byteArray = "$account:$pwd".toByteArray() - val base64 = android.util.Base64.encodeToString(byteArray, android.util.Base64.DEFAULT) - - val msg = NtripAuthorizationCreator() - .append("GET /RTCM32_GGB HTTP/1.1") - .append("Host: ${LocaleConstant.QX_RTK_HOST}") - .append("Ntrip-Version: Ntrip/2.0") - .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") - .append("Accept: */*") - .append("Connection: close") - .append("Accept:*/*") - .append("Authorization: Basic $base64") - .toString() - - val byteBuf = Unpooled.wrappedBuffer(msg.toByteArray()) - socketClient.sendData(byteBuf) - } } private fun connectQianXunServer() { @@ -168,17 +172,10 @@ LocaleConstant.RTK_PORT, "8003" ) as String - socketClient = SocketClient.Builder() - .setHostname(remoteHost) - .setPort(remotePort.toInt()) - .setTimeout(5000) - .setOnSocketListener(this) - .build() - socketClient.connect() - } + if (socketClient.isRunning()) { + return + } - override fun onDestroy() { - super.onDestroy() - unbindService(serviceConnection) + socketClient.start(remoteHost, remotePort.toInt()) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt deleted file mode 100644 index c1707b4..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -enum class ConnectState { - /** - * 连接成功 - */ - SUCCESS, - - /** - * 关闭连接 - */ - CLOSED, - - /** - * 连接失败 - */ - ERROR -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt deleted file mode 100644 index 35a32f2..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -interface OnSocketConnectListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceConnectStatusChanged(status: ConnectState) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt index 974e131..c976447 100644 --- a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt +++ b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt @@ -1,13 +1,11 @@ package com.casic.common.detector.gd.service import android.app.Service -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.os.Handler import android.os.IBinder import android.os.Message +import android.util.Base64 import android.util.Log import android.view.Gravity import android.widget.Toast @@ -20,20 +18,19 @@ import com.casic.common.detector.gd.utils.LocaleConstant import com.casic.common.detector.gd.utils.NtripAuthorizationCreator import com.casic.common.detector.gd.utils.RtkLocationTool -import com.casic.common.detector.gd.utils.tcp.ConnectState -import com.casic.common.detector.gd.utils.tcp.OnSocketConnectListener -import com.casic.common.detector.gd.utils.tcp.SocketClient import com.casic.common.detector.gd.view.MainActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler -import io.netty.buffer.Unpooled +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.OutputStream import java.nio.charset.StandardCharsets -class NtripConnectService : Service(), LifecycleOwner, OnSocketConnectListener, Handler.Callback { + +class NtripConnectService : Service(), LifecycleOwner, OnTcpConnectStateListener, Handler.Callback { companion object { var weakReferenceHandler: WeakReferenceHandler? = null @@ -41,10 +38,8 @@ private val kTag = "NtripConnectService" private val registry = LifecycleRegistry(this) - private var connectState = ConnectState.CLOSED - private var serialPortService: SerialPortService? = null + private val socketClient by lazy { TcpClient(this) } private var outStream: OutputStream? = null - private lateinit var socketClient: SocketClient override fun getLifecycle(): Lifecycle { return registry @@ -66,10 +61,8 @@ override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) - //绑定串口通信服务 - Intent(this, SerialPortService::class.java).also { - bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) - } + + connectQianXunServer() RtkLocationTool.getCurrentLocation(this) { val weakHandler = MainActivity.weakReferenceHandler ?: return@getCurrentLocation @@ -78,85 +71,96 @@ message.obj = "${it.longitude},${it.latitude}" weakHandler.sendMessage(message) - if (connectState == ConnectState.SUCCESS) { + if (socketClient.isRunning()) { //连接成功就发送千寻请求报文 val gga = it.convertToGPGGA() Log.d(kTag, gga) - socketClient.sendData(gga) + socketClient.sendMessage(gga.toByteArray()) } } } - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { - if (iBinder is SerialPortService.ServiceBinder) { - serialPortService = iBinder.getSerialPortService() - Log.d(kTag, "onServiceConnected: 服务已绑定") + /** + * Ntrip服务器需要两步验证: + * 第一步是connect, + * 第二步是发送check cmd。 + * 这二步是连续的,要不然服务器就会拒绝,显示一连就失败 + * */ + override fun onConnected() { + //连接成功就发送千寻请求报文 + val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String + val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String + + // base64加密用户名和密码 + val byteArray = "$account:$pwd".toByteArray() + val base64 = Base64.encodeToString(byteArray, Base64.DEFAULT) + + val msg = NtripAuthorizationCreator() + .append("GET /RTCM32_GGB HTTP/1.1") + .append("Host: ${LocaleConstant.QX_RTK_HOST}") + .append("Ntrip-Version: Ntrip/2.0") + .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") + .append("Accept: */*") + .append("Connection: close") + .append("Accept:*/*") + .append("Authorization: Basic $base64") + .toString() + socketClient.sendMessage(msg.toByteArray()) + } + + override fun onConnectFailed() { + + } + + override fun onDisconnected() { + + } + + override fun onMessageReceived(bytes: ByteArray?) { + bytes?.apply { + if (size == 14) { + /** + * 连接成功 + *

+ * ICY 200 OK + * */ + val result = String(this, StandardCharsets.UTF_8) + if (result.contains("ICY 200 OK")) { + lifecycleScope.launch(Dispatchers.Main) { + "高精度定位服务连接成功".show(this@NtripConnectService) + } + //连接服务即打开串口 + outStream = BaseApplication.get().getSerialPorts().first().outputStream + } + } else if (size == 153) { + Log.d(kTag, String(this, StandardCharsets.UTF_8)) + /** + * 账号到期 + *

+ * HTTP 401 Unauthorized + * Server: POP_GW_Ntrip_1.0_1729082016/1.0 + * Via: n108_10 + * Date: 2024/11/08 14:01:18 + * Content-Type: text/plain + * Connection: clos + * */ + lifecycleScope.launch(Dispatchers.Main) { + "差分定位服务鉴权失败,无法解析位置".show(this@NtripConnectService) + } + } else { + //居中显示 + lifecycleScope.launch(Dispatchers.Main) { + val toast = Toast.makeText( + this@NtripConnectService, "收到千寻数据,长度:${size}", Toast.LENGTH_SHORT + ) + toast.setGravity(Gravity.CENTER, 0, 0) + toast.show() + } + + outStream?.write(this) + outStream?.flush() } } - - override fun onServiceDisconnected(name: ComponentName?) { - - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - lifecycleScope.launch(Dispatchers.IO) { - connectQianXunServer() - } - return START_STICKY - } - - override fun onMessageResponse(data: ByteArray) { - if (data.size == 14) { - /** - * 连接成功,登录会返回 ICY 200 OK - *

- * 0d0a0d0a -> \r\n\r\n - * */ - val result = String(data, StandardCharsets.UTF_8) - if (result.contains("ICY 200 OK")) { - "高精度定位服务连接成功".show(this) - //连接服务即打开串口 - outStream = BaseApplication.get().getSerialPorts().first().outputStream - } - } else { - //居中显示 - val toast = Toast.makeText(this, "收到千寻数据,长度:${data.size}", Toast.LENGTH_SHORT) - toast.setGravity(Gravity.CENTER, 0, 0) - toast.show() - - outStream?.write(data) - outStream?.flush() - } - } - - override fun onServiceConnectStatusChanged(status: ConnectState) { - this.connectState = status - Log.d(kTag, "onServiceConnectStatusChanged: $status") - if (connectState == ConnectState.SUCCESS) { - //连接成功就发送千寻请求报文 - val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String - val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String - - // base64加密用户名和密码 - val byteArray = "$account:$pwd".toByteArray() - val base64 = android.util.Base64.encodeToString(byteArray, android.util.Base64.DEFAULT) - - val msg = NtripAuthorizationCreator() - .append("GET /RTCM32_GGB HTTP/1.1") - .append("Host: ${LocaleConstant.QX_RTK_HOST}") - .append("Ntrip-Version: Ntrip/2.0") - .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") - .append("Accept: */*") - .append("Connection: close") - .append("Accept:*/*") - .append("Authorization: Basic $base64") - .toString() - - val byteBuf = Unpooled.wrappedBuffer(msg.toByteArray()) - socketClient.sendData(byteBuf) - } } private fun connectQianXunServer() { @@ -168,17 +172,10 @@ LocaleConstant.RTK_PORT, "8003" ) as String - socketClient = SocketClient.Builder() - .setHostname(remoteHost) - .setPort(remotePort.toInt()) - .setTimeout(5000) - .setOnSocketListener(this) - .build() - socketClient.connect() - } + if (socketClient.isRunning()) { + return + } - override fun onDestroy() { - super.onDestroy() - unbindService(serviceConnection) + socketClient.start(remoteHost, remotePort.toInt()) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt deleted file mode 100644 index c1707b4..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -enum class ConnectState { - /** - * 连接成功 - */ - SUCCESS, - - /** - * 关闭连接 - */ - CLOSED, - - /** - * 连接失败 - */ - ERROR -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt deleted file mode 100644 index 35a32f2..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -interface OnSocketConnectListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceConnectStatusChanged(status: ConnectState) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt deleted file mode 100644 index 22f0a4e..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -import android.os.Looper -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketChannelHandler(private val listener: OnSocketConnectListener) : - SimpleChannelInboundHandler(), LifecycleOwner { - - private fun isOnMainThread(): Boolean { - return Looper.getMainLooper().thread == Thread.currentThread() - } - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.SUCCESS) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.SUCCESS) - } - } - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.CLOSED) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.CLOSED) - } - } - } - - override fun channelRead0(channelHandlerContext: ChannelHandlerContext, bytes: ByteArray?) { - if (bytes == null) { - return - } - if (isOnMainThread()) { - listener.onMessageResponse(bytes) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onMessageResponse(bytes) - } - } - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - ctx.close() - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.ERROR) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.ERROR) - } - } - } - - private val registry = LifecycleRegistry(this) - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt index 974e131..c976447 100644 --- a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt +++ b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt @@ -1,13 +1,11 @@ package com.casic.common.detector.gd.service import android.app.Service -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.os.Handler import android.os.IBinder import android.os.Message +import android.util.Base64 import android.util.Log import android.view.Gravity import android.widget.Toast @@ -20,20 +18,19 @@ import com.casic.common.detector.gd.utils.LocaleConstant import com.casic.common.detector.gd.utils.NtripAuthorizationCreator import com.casic.common.detector.gd.utils.RtkLocationTool -import com.casic.common.detector.gd.utils.tcp.ConnectState -import com.casic.common.detector.gd.utils.tcp.OnSocketConnectListener -import com.casic.common.detector.gd.utils.tcp.SocketClient import com.casic.common.detector.gd.view.MainActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler -import io.netty.buffer.Unpooled +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.OutputStream import java.nio.charset.StandardCharsets -class NtripConnectService : Service(), LifecycleOwner, OnSocketConnectListener, Handler.Callback { + +class NtripConnectService : Service(), LifecycleOwner, OnTcpConnectStateListener, Handler.Callback { companion object { var weakReferenceHandler: WeakReferenceHandler? = null @@ -41,10 +38,8 @@ private val kTag = "NtripConnectService" private val registry = LifecycleRegistry(this) - private var connectState = ConnectState.CLOSED - private var serialPortService: SerialPortService? = null + private val socketClient by lazy { TcpClient(this) } private var outStream: OutputStream? = null - private lateinit var socketClient: SocketClient override fun getLifecycle(): Lifecycle { return registry @@ -66,10 +61,8 @@ override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) - //绑定串口通信服务 - Intent(this, SerialPortService::class.java).also { - bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) - } + + connectQianXunServer() RtkLocationTool.getCurrentLocation(this) { val weakHandler = MainActivity.weakReferenceHandler ?: return@getCurrentLocation @@ -78,85 +71,96 @@ message.obj = "${it.longitude},${it.latitude}" weakHandler.sendMessage(message) - if (connectState == ConnectState.SUCCESS) { + if (socketClient.isRunning()) { //连接成功就发送千寻请求报文 val gga = it.convertToGPGGA() Log.d(kTag, gga) - socketClient.sendData(gga) + socketClient.sendMessage(gga.toByteArray()) } } } - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { - if (iBinder is SerialPortService.ServiceBinder) { - serialPortService = iBinder.getSerialPortService() - Log.d(kTag, "onServiceConnected: 服务已绑定") + /** + * Ntrip服务器需要两步验证: + * 第一步是connect, + * 第二步是发送check cmd。 + * 这二步是连续的,要不然服务器就会拒绝,显示一连就失败 + * */ + override fun onConnected() { + //连接成功就发送千寻请求报文 + val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String + val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String + + // base64加密用户名和密码 + val byteArray = "$account:$pwd".toByteArray() + val base64 = Base64.encodeToString(byteArray, Base64.DEFAULT) + + val msg = NtripAuthorizationCreator() + .append("GET /RTCM32_GGB HTTP/1.1") + .append("Host: ${LocaleConstant.QX_RTK_HOST}") + .append("Ntrip-Version: Ntrip/2.0") + .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") + .append("Accept: */*") + .append("Connection: close") + .append("Accept:*/*") + .append("Authorization: Basic $base64") + .toString() + socketClient.sendMessage(msg.toByteArray()) + } + + override fun onConnectFailed() { + + } + + override fun onDisconnected() { + + } + + override fun onMessageReceived(bytes: ByteArray?) { + bytes?.apply { + if (size == 14) { + /** + * 连接成功 + *

+ * ICY 200 OK + * */ + val result = String(this, StandardCharsets.UTF_8) + if (result.contains("ICY 200 OK")) { + lifecycleScope.launch(Dispatchers.Main) { + "高精度定位服务连接成功".show(this@NtripConnectService) + } + //连接服务即打开串口 + outStream = BaseApplication.get().getSerialPorts().first().outputStream + } + } else if (size == 153) { + Log.d(kTag, String(this, StandardCharsets.UTF_8)) + /** + * 账号到期 + *

+ * HTTP 401 Unauthorized + * Server: POP_GW_Ntrip_1.0_1729082016/1.0 + * Via: n108_10 + * Date: 2024/11/08 14:01:18 + * Content-Type: text/plain + * Connection: clos + * */ + lifecycleScope.launch(Dispatchers.Main) { + "差分定位服务鉴权失败,无法解析位置".show(this@NtripConnectService) + } + } else { + //居中显示 + lifecycleScope.launch(Dispatchers.Main) { + val toast = Toast.makeText( + this@NtripConnectService, "收到千寻数据,长度:${size}", Toast.LENGTH_SHORT + ) + toast.setGravity(Gravity.CENTER, 0, 0) + toast.show() + } + + outStream?.write(this) + outStream?.flush() } } - - override fun onServiceDisconnected(name: ComponentName?) { - - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - lifecycleScope.launch(Dispatchers.IO) { - connectQianXunServer() - } - return START_STICKY - } - - override fun onMessageResponse(data: ByteArray) { - if (data.size == 14) { - /** - * 连接成功,登录会返回 ICY 200 OK - *

- * 0d0a0d0a -> \r\n\r\n - * */ - val result = String(data, StandardCharsets.UTF_8) - if (result.contains("ICY 200 OK")) { - "高精度定位服务连接成功".show(this) - //连接服务即打开串口 - outStream = BaseApplication.get().getSerialPorts().first().outputStream - } - } else { - //居中显示 - val toast = Toast.makeText(this, "收到千寻数据,长度:${data.size}", Toast.LENGTH_SHORT) - toast.setGravity(Gravity.CENTER, 0, 0) - toast.show() - - outStream?.write(data) - outStream?.flush() - } - } - - override fun onServiceConnectStatusChanged(status: ConnectState) { - this.connectState = status - Log.d(kTag, "onServiceConnectStatusChanged: $status") - if (connectState == ConnectState.SUCCESS) { - //连接成功就发送千寻请求报文 - val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String - val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String - - // base64加密用户名和密码 - val byteArray = "$account:$pwd".toByteArray() - val base64 = android.util.Base64.encodeToString(byteArray, android.util.Base64.DEFAULT) - - val msg = NtripAuthorizationCreator() - .append("GET /RTCM32_GGB HTTP/1.1") - .append("Host: ${LocaleConstant.QX_RTK_HOST}") - .append("Ntrip-Version: Ntrip/2.0") - .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") - .append("Accept: */*") - .append("Connection: close") - .append("Accept:*/*") - .append("Authorization: Basic $base64") - .toString() - - val byteBuf = Unpooled.wrappedBuffer(msg.toByteArray()) - socketClient.sendData(byteBuf) - } } private fun connectQianXunServer() { @@ -168,17 +172,10 @@ LocaleConstant.RTK_PORT, "8003" ) as String - socketClient = SocketClient.Builder() - .setHostname(remoteHost) - .setPort(remotePort.toInt()) - .setTimeout(5000) - .setOnSocketListener(this) - .build() - socketClient.connect() - } + if (socketClient.isRunning()) { + return + } - override fun onDestroy() { - super.onDestroy() - unbindService(serviceConnection) + socketClient.start(remoteHost, remotePort.toInt()) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt deleted file mode 100644 index c1707b4..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -enum class ConnectState { - /** - * 连接成功 - */ - SUCCESS, - - /** - * 关闭连接 - */ - CLOSED, - - /** - * 连接失败 - */ - ERROR -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt deleted file mode 100644 index 35a32f2..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -interface OnSocketConnectListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceConnectStatusChanged(status: ConnectState) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt deleted file mode 100644 index 22f0a4e..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -import android.os.Looper -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketChannelHandler(private val listener: OnSocketConnectListener) : - SimpleChannelInboundHandler(), LifecycleOwner { - - private fun isOnMainThread(): Boolean { - return Looper.getMainLooper().thread == Thread.currentThread() - } - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.SUCCESS) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.SUCCESS) - } - } - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.CLOSED) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.CLOSED) - } - } - } - - override fun channelRead0(channelHandlerContext: ChannelHandlerContext, bytes: ByteArray?) { - if (bytes == null) { - return - } - if (isOnMainThread()) { - listener.onMessageResponse(bytes) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onMessageResponse(bytes) - } - } - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - ctx.close() - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.ERROR) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.ERROR) - } - } - } - - private val registry = LifecycleRegistry(this) - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketClient.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketClient.kt deleted file mode 100644 index 4675048..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketClient.kt +++ /dev/null @@ -1,128 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -import android.util.Log -import io.netty.bootstrap.Bootstrap -import io.netty.buffer.ByteBuf -import io.netty.buffer.Unpooled -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 -import java.util.concurrent.TimeUnit - -class SocketClient(builder: Builder) { - - private val kTag = "SocketClient" - private val hostname = builder.hostname - private val port = builder.port - private val timeout = builder.timeout - private val listener = builder.listener - - private var bootstrap: Bootstrap - private var channel: Channel? = null - - class Builder { - lateinit var hostname: String - var port = 0 - var timeout = 0L - lateinit var listener: OnSocketConnectListener - - fun setHostname(hostname: String): Builder { - this.hostname = hostname - return this - } - - fun setPort(port: Int): Builder { - this.port = port - return this - } - - fun setTimeout(timeout: Long): Builder { - this.timeout = timeout - return this - } - - fun setOnSocketListener(listener: OnSocketConnectListener): Builder { - this.listener = listener - return this - } - - fun build(): SocketClient { - return SocketClient(this) - } - } - - init { - val eventLoopGroup = NioEventLoopGroup() - bootstrap = Bootstrap() - bootstrap.group(eventLoopGroup) - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10 * 1000) //连接超时时间 - .option( - ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator(64, 2048, 65536) - ) - .handler(object : ChannelInitializer() { - override fun initChannel(socketChannel: SocketChannel) { - val pipeline = socketChannel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0, TimeUnit.SECONDS)) - .addLast(ByteArrayDecoder()) - .addLast(ByteArrayEncoder()) - .addLast(SocketChannelHandler(listener)) - } - }) - } - - fun connect() { - synchronized(this) { - try { - Log.d(kTag, "connect: 连接TCP服务器") - //连接监听 - val channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - channel = channelFuture.channel() - } - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - retryConnect() - } - } - } - - fun disconnect() { - channel?.close()?.addListener(ChannelFutureListener.CLOSE) - Log.d(kTag, "disconnect: 断开TCP服务器") - } - - private fun retryConnect() { - try { - Thread.sleep(timeout) - connect() - } catch (ex: InterruptedException) { - Log.d(kTag, "retryConnect: ${ex.localizedMessage}") - } - } - - fun sendData(message: String) { - val byteBuf = Unpooled.wrappedBuffer(message.toByteArray()) - sendData(byteBuf) - } - - fun sendData(buffer: ByteBuf) { - channel?.writeAndFlush(buffer) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt index 974e131..c976447 100644 --- a/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt +++ b/app/src/main/java/com/casic/common/detector/gd/service/NtripConnectService.kt @@ -1,13 +1,11 @@ package com.casic.common.detector.gd.service import android.app.Service -import android.content.ComponentName -import android.content.Context import android.content.Intent -import android.content.ServiceConnection import android.os.Handler import android.os.IBinder import android.os.Message +import android.util.Base64 import android.util.Log import android.view.Gravity import android.widget.Toast @@ -20,20 +18,19 @@ import com.casic.common.detector.gd.utils.LocaleConstant import com.casic.common.detector.gd.utils.NtripAuthorizationCreator import com.casic.common.detector.gd.utils.RtkLocationTool -import com.casic.common.detector.gd.utils.tcp.ConnectState -import com.casic.common.detector.gd.utils.tcp.OnSocketConnectListener -import com.casic.common.detector.gd.utils.tcp.SocketClient import com.casic.common.detector.gd.view.MainActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler -import io.netty.buffer.Unpooled +import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener +import com.pengxh.kt.lite.utils.socket.tcp.TcpClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.io.OutputStream import java.nio.charset.StandardCharsets -class NtripConnectService : Service(), LifecycleOwner, OnSocketConnectListener, Handler.Callback { + +class NtripConnectService : Service(), LifecycleOwner, OnTcpConnectStateListener, Handler.Callback { companion object { var weakReferenceHandler: WeakReferenceHandler? = null @@ -41,10 +38,8 @@ private val kTag = "NtripConnectService" private val registry = LifecycleRegistry(this) - private var connectState = ConnectState.CLOSED - private var serialPortService: SerialPortService? = null + private val socketClient by lazy { TcpClient(this) } private var outStream: OutputStream? = null - private lateinit var socketClient: SocketClient override fun getLifecycle(): Lifecycle { return registry @@ -66,10 +61,8 @@ override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) - //绑定串口通信服务 - Intent(this, SerialPortService::class.java).also { - bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) - } + + connectQianXunServer() RtkLocationTool.getCurrentLocation(this) { val weakHandler = MainActivity.weakReferenceHandler ?: return@getCurrentLocation @@ -78,85 +71,96 @@ message.obj = "${it.longitude},${it.latitude}" weakHandler.sendMessage(message) - if (connectState == ConnectState.SUCCESS) { + if (socketClient.isRunning()) { //连接成功就发送千寻请求报文 val gga = it.convertToGPGGA() Log.d(kTag, gga) - socketClient.sendData(gga) + socketClient.sendMessage(gga.toByteArray()) } } } - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { - if (iBinder is SerialPortService.ServiceBinder) { - serialPortService = iBinder.getSerialPortService() - Log.d(kTag, "onServiceConnected: 服务已绑定") + /** + * Ntrip服务器需要两步验证: + * 第一步是connect, + * 第二步是发送check cmd。 + * 这二步是连续的,要不然服务器就会拒绝,显示一连就失败 + * */ + override fun onConnected() { + //连接成功就发送千寻请求报文 + val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String + val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String + + // base64加密用户名和密码 + val byteArray = "$account:$pwd".toByteArray() + val base64 = Base64.encodeToString(byteArray, Base64.DEFAULT) + + val msg = NtripAuthorizationCreator() + .append("GET /RTCM32_GGB HTTP/1.1") + .append("Host: ${LocaleConstant.QX_RTK_HOST}") + .append("Ntrip-Version: Ntrip/2.0") + .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") + .append("Accept: */*") + .append("Connection: close") + .append("Accept:*/*") + .append("Authorization: Basic $base64") + .toString() + socketClient.sendMessage(msg.toByteArray()) + } + + override fun onConnectFailed() { + + } + + override fun onDisconnected() { + + } + + override fun onMessageReceived(bytes: ByteArray?) { + bytes?.apply { + if (size == 14) { + /** + * 连接成功 + *

+ * ICY 200 OK + * */ + val result = String(this, StandardCharsets.UTF_8) + if (result.contains("ICY 200 OK")) { + lifecycleScope.launch(Dispatchers.Main) { + "高精度定位服务连接成功".show(this@NtripConnectService) + } + //连接服务即打开串口 + outStream = BaseApplication.get().getSerialPorts().first().outputStream + } + } else if (size == 153) { + Log.d(kTag, String(this, StandardCharsets.UTF_8)) + /** + * 账号到期 + *

+ * HTTP 401 Unauthorized + * Server: POP_GW_Ntrip_1.0_1729082016/1.0 + * Via: n108_10 + * Date: 2024/11/08 14:01:18 + * Content-Type: text/plain + * Connection: clos + * */ + lifecycleScope.launch(Dispatchers.Main) { + "差分定位服务鉴权失败,无法解析位置".show(this@NtripConnectService) + } + } else { + //居中显示 + lifecycleScope.launch(Dispatchers.Main) { + val toast = Toast.makeText( + this@NtripConnectService, "收到千寻数据,长度:${size}", Toast.LENGTH_SHORT + ) + toast.setGravity(Gravity.CENTER, 0, 0) + toast.show() + } + + outStream?.write(this) + outStream?.flush() } } - - override fun onServiceDisconnected(name: ComponentName?) { - - } - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - lifecycleScope.launch(Dispatchers.IO) { - connectQianXunServer() - } - return START_STICKY - } - - override fun onMessageResponse(data: ByteArray) { - if (data.size == 14) { - /** - * 连接成功,登录会返回 ICY 200 OK - *

- * 0d0a0d0a -> \r\n\r\n - * */ - val result = String(data, StandardCharsets.UTF_8) - if (result.contains("ICY 200 OK")) { - "高精度定位服务连接成功".show(this) - //连接服务即打开串口 - outStream = BaseApplication.get().getSerialPorts().first().outputStream - } - } else { - //居中显示 - val toast = Toast.makeText(this, "收到千寻数据,长度:${data.size}", Toast.LENGTH_SHORT) - toast.setGravity(Gravity.CENTER, 0, 0) - toast.show() - - outStream?.write(data) - outStream?.flush() - } - } - - override fun onServiceConnectStatusChanged(status: ConnectState) { - this.connectState = status - Log.d(kTag, "onServiceConnectStatusChanged: $status") - if (connectState == ConnectState.SUCCESS) { - //连接成功就发送千寻请求报文 - val account = SaveKeyValues.getValue(LocaleConstant.ACK, "qxtmcr0087663") as String - val pwd = SaveKeyValues.getValue(LocaleConstant.ACS, "1f1f9b9") as String - - // base64加密用户名和密码 - val byteArray = "$account:$pwd".toByteArray() - val base64 = android.util.Base64.encodeToString(byteArray, android.util.Base64.DEFAULT) - - val msg = NtripAuthorizationCreator() - .append("GET /RTCM32_GGB HTTP/1.1") - .append("Host: ${LocaleConstant.QX_RTK_HOST}") - .append("Ntrip-Version: Ntrip/2.0") - .append("User-Agent: NTRIP GNSSInternetRadio 2.0.10") - .append("Accept: */*") - .append("Connection: close") - .append("Accept:*/*") - .append("Authorization: Basic $base64") - .toString() - - val byteBuf = Unpooled.wrappedBuffer(msg.toByteArray()) - socketClient.sendData(byteBuf) - } } private fun connectQianXunServer() { @@ -168,17 +172,10 @@ LocaleConstant.RTK_PORT, "8003" ) as String - socketClient = SocketClient.Builder() - .setHostname(remoteHost) - .setPort(remotePort.toInt()) - .setTimeout(5000) - .setOnSocketListener(this) - .build() - socketClient.connect() - } + if (socketClient.isRunning()) { + return + } - override fun onDestroy() { - super.onDestroy() - unbindService(serviceConnection) + socketClient.start(remoteHost, remotePort.toInt()) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt deleted file mode 100644 index c1707b4..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/ConnectState.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -enum class ConnectState { - /** - * 连接成功 - */ - SUCCESS, - - /** - * 关闭连接 - */ - CLOSED, - - /** - * 连接失败 - */ - ERROR -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt deleted file mode 100644 index 35a32f2..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/OnSocketConnectListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -interface OnSocketConnectListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceConnectStatusChanged(status: ConnectState) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt deleted file mode 100644 index 22f0a4e..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketChannelHandler.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -import android.os.Looper -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.lifecycleScope -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class SocketChannelHandler(private val listener: OnSocketConnectListener) : - SimpleChannelInboundHandler(), LifecycleOwner { - - private fun isOnMainThread(): Boolean { - return Looper.getMainLooper().thread == Thread.currentThread() - } - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.SUCCESS) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.SUCCESS) - } - } - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.CLOSED) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.CLOSED) - } - } - } - - override fun channelRead0(channelHandlerContext: ChannelHandlerContext, bytes: ByteArray?) { - if (bytes == null) { - return - } - if (isOnMainThread()) { - listener.onMessageResponse(bytes) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onMessageResponse(bytes) - } - } - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - ctx.close() - if (isOnMainThread()) { - listener.onServiceConnectStatusChanged(ConnectState.ERROR) - } else { - lifecycleScope.launch(Dispatchers.Main) { - listener.onServiceConnectStatusChanged(ConnectState.ERROR) - } - } - } - - private val registry = LifecycleRegistry(this) - - override fun getLifecycle(): Lifecycle { - return registry - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketClient.kt b/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketClient.kt deleted file mode 100644 index 4675048..0000000 --- a/app/src/main/java/com/casic/common/detector/gd/utils/tcp/SocketClient.kt +++ /dev/null @@ -1,128 +0,0 @@ -package com.casic.common.detector.gd.utils.tcp - -import android.util.Log -import io.netty.bootstrap.Bootstrap -import io.netty.buffer.ByteBuf -import io.netty.buffer.Unpooled -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 -import java.util.concurrent.TimeUnit - -class SocketClient(builder: Builder) { - - private val kTag = "SocketClient" - private val hostname = builder.hostname - private val port = builder.port - private val timeout = builder.timeout - private val listener = builder.listener - - private var bootstrap: Bootstrap - private var channel: Channel? = null - - class Builder { - lateinit var hostname: String - var port = 0 - var timeout = 0L - lateinit var listener: OnSocketConnectListener - - fun setHostname(hostname: String): Builder { - this.hostname = hostname - return this - } - - fun setPort(port: Int): Builder { - this.port = port - return this - } - - fun setTimeout(timeout: Long): Builder { - this.timeout = timeout - return this - } - - fun setOnSocketListener(listener: OnSocketConnectListener): Builder { - this.listener = listener - return this - } - - fun build(): SocketClient { - return SocketClient(this) - } - } - - init { - val eventLoopGroup = NioEventLoopGroup() - bootstrap = Bootstrap() - bootstrap.group(eventLoopGroup) - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10 * 1000) //连接超时时间 - .option( - ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator(64, 2048, 65536) - ) - .handler(object : ChannelInitializer() { - override fun initChannel(socketChannel: SocketChannel) { - val pipeline = socketChannel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0, TimeUnit.SECONDS)) - .addLast(ByteArrayDecoder()) - .addLast(ByteArrayEncoder()) - .addLast(SocketChannelHandler(listener)) - } - }) - } - - fun connect() { - synchronized(this) { - try { - Log.d(kTag, "connect: 连接TCP服务器") - //连接监听 - val channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - channel = channelFuture.channel() - } - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - retryConnect() - } - } - } - - fun disconnect() { - channel?.close()?.addListener(ChannelFutureListener.CLOSE) - Log.d(kTag, "disconnect: 断开TCP服务器") - } - - private fun retryConnect() { - try { - Thread.sleep(timeout) - connect() - } catch (ex: InterruptedException) { - Log.d(kTag, "retryConnect: ${ex.localizedMessage}") - } - } - - fun sendData(message: String) { - val byteBuf = Unpooled.wrappedBuffer(message.toByteArray()) - sendData(byteBuf) - } - - fun sendData(buffer: ByteBuf) { - channel?.writeAndFlush(buffer) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/view/MainActivity.kt b/app/src/main/java/com/casic/common/detector/gd/view/MainActivity.kt index d91361f..211cb37 100644 --- a/app/src/main/java/com/casic/common/detector/gd/view/MainActivity.kt +++ b/app/src/main/java/com/casic/common/detector/gd/view/MainActivity.kt @@ -150,6 +150,9 @@ Intent(this, SerialPortService::class.java).also { bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } + Intent(this, NtripConnectService::class.java).also { + startService(it) + } soundResourceId = soundPool.load(this, R.raw.ring3, 1) //地图初始化 initMapConfig(savedInstanceState)