Commit f848c1da authored by 马乐's avatar 马乐

1.注册初步验证OK

2.鉴权初步验证OK 3.心跳OK
parent 02a36148
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:name=".MyApp"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
...@@ -11,6 +13,7 @@ ...@@ -11,6 +13,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/Theme.HTAnticollision" android:theme="@style/Theme.HTAnticollision"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
......
...@@ -8,7 +8,11 @@ import androidx.navigation.ui.setupWithNavController ...@@ -8,7 +8,11 @@ import androidx.navigation.ui.setupWithNavController
import com.blankj.utilcode.util.Utils import com.blankj.utilcode.util.Utils
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.gyf.immersionbar.ImmersionBar import com.gyf.immersionbar.ImmersionBar
import com.waytous.anticollision.config.DeviceConfig
import com.waytous.anticollision.databinding.ActivityMainBinding import com.waytous.anticollision.databinding.ActivityMainBinding
import com.waytous.anticollision.tcp.Session
import io.github.toggery.jt808.messagebody.B8001
import kotlin.concurrent.thread
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
...@@ -25,6 +29,15 @@ class MainActivity : AppCompatActivity() { ...@@ -25,6 +29,15 @@ class MainActivity : AppCompatActivity() {
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
initNavView() initNavView()
DeviceConfig.province = 11
DeviceConfig.city = 0
DeviceConfig.phoneNumber = "18801011111"
DeviceConfig.HostConfig.host = "192.168.9.48"
DeviceConfig.HostConfig.port = 6608
val session = Session()
thread { session.login() }
} }
private fun initNavView(){ private fun initNavView(){
......
...@@ -5,10 +5,9 @@ import com.blankj.utilcode.util.LogUtils ...@@ -5,10 +5,9 @@ import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.SPStaticUtils import com.blankj.utilcode.util.SPStaticUtils
import com.blankj.utilcode.util.SPUtils import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.Utils import com.blankj.utilcode.util.Utils
import kotlin.properties.Delegates
object MyApp: Application() { class MyApp: Application() {
lateinit var instance:MyApp
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
...@@ -17,4 +16,10 @@ object MyApp: Application() { ...@@ -17,4 +16,10 @@ object MyApp: Application() {
LogUtils.getConfig().globalTag = "Waytous" LogUtils.getConfig().globalTag = "Waytous"
SPStaticUtils.setDefaultSPUtils(SPUtils.getInstance("settings")) SPStaticUtils.setDefaultSPUtils(SPUtils.getInstance("settings"))
} }
companion object {
//情况一:声明可空的属性
private var instance: MyApp by Delegates.notNull()
fun instance() = instance
}
} }
\ No newline at end of file
...@@ -4,15 +4,9 @@ import com.blankj.utilcode.util.DeviceUtils ...@@ -4,15 +4,9 @@ import com.blankj.utilcode.util.DeviceUtils
import com.waytous.anticollision.config.DeviceConfig import com.waytous.anticollision.config.DeviceConfig
import com.waytous.anticollision.config.Settings import com.waytous.anticollision.config.Settings
import com.waytous.anticollision.listener.SessionListener import com.waytous.anticollision.listener.SessionListener
import com.waytous.anticollision.utils.NamedThreadFactory import com.waytous.anticollision.utils.*
import com.waytous.anticollision.utils.SignInStatus
import com.waytous.anticollision.utils.logd
import com.waytous.anticollision.utils.loge
import io.github.toggery.jt808.codec.* import io.github.toggery.jt808.codec.*
import io.github.toggery.jt808.messagebody.B0100 import io.github.toggery.jt808.messagebody.*
import io.github.toggery.jt808.messagebody.B0102
import io.github.toggery.jt808.messagebody.B8001
import io.github.toggery.jt808.messagebody.HexUtil
import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBuf
import io.netty.buffer.UnpooledByteBufAllocator import io.netty.buffer.UnpooledByteBufAllocator
import io.netty.util.DefaultAttributeMap import io.netty.util.DefaultAttributeMap
...@@ -36,14 +30,17 @@ internal enum class DeviceStatus { ...@@ -36,14 +30,17 @@ internal enum class DeviceStatus {
* 未注册 * 未注册
* */ * */
Unregistered, Unregistered,
/** /**
* 注册中 * 注册中
* */ * */
Registering, Registering,
/** /**
* 已册中 * 已册中
* */ * */
Registered, Registered,
/** /**
* 未鉴权 * 未鉴权
* */ * */
...@@ -60,13 +57,13 @@ internal enum class DeviceStatus { ...@@ -60,13 +57,13 @@ internal enum class DeviceStatus {
Authenticated Authenticated
} }
internal class Schedule{ internal class Schedule {
companion object{ companion object {
const val tcpReadIntervalSecs:Long = 2 // 2 seconds const val tcpReadIntervalSecs: Long = 2 // 2 seconds
const val tcpConnectTimeoutSecs = 40 // 40 seconds const val tcpConnectTimeoutSecs = 40 // 40 seconds
const val signInTimeoutSecs:Long = 60 // 60 seconds const val signInTimeoutSecs: Long = 60 // 60 seconds
const val heartbeatInterval = 120 // 120 seconds const val heartbeatInterval = 120 // 120 seconds
} }
} }
...@@ -74,7 +71,7 @@ internal class Schedule{ ...@@ -74,7 +71,7 @@ internal class Schedule{
* jt808网络会话管理 * jt808网络会话管理
* @author male * @author male
* */ * */
internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { internal class Session : ConnectListener, SyncMessageListener<AbstractToStringJoiner> {
/** /**
* 消息内容解析器 * 消息内容解析器
...@@ -117,10 +114,10 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -117,10 +114,10 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
} }
private val scheduler by lazy { private val scheduler by lazy {
Executors.newScheduledThreadPool(1,NamedThreadFactory("Heartbeat")) Executors.newScheduledThreadPool(1, NamedThreadFactory("Heartbeat"))
} }
private var scheduleFutureTask: ScheduledFuture<*>?=null private var scheduleFutureTask: ScheduledFuture<*>? = null
private val mOperateLock by lazy { private val mOperateLock by lazy {
ReentrantLock() ReentrantLock()
...@@ -145,13 +142,13 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -145,13 +142,13 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 设备尝试登录 * 设备尝试登录
* */ * */
private fun tryLogin(block:()->Boolean){ private fun tryLogin(block: () -> Boolean) {
var retryTimes = 0 var retryTimes = 0
var success:Boolean var success: Boolean
do { do {
success = block() success = block()
retryTimes++ retryTimes++
} while (retryTimes < CONNECT_MAX_RETRY && success) } while (retryTimes < CONNECT_MAX_RETRY && !success)
if (!success) { if (!success) {
handleDisconnect(Error.JT808EncodeError) handleDisconnect(Error.JT808EncodeError)
} }
...@@ -160,9 +157,9 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -160,9 +157,9 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 错误处理逻辑 * 错误处理逻辑
* */ * */
private fun handleDisconnect(error: Error){ private fun handleDisconnect(error: Error) {
when(error){ when (error) {
Error.IOError,Error.StreamClosed,Error.Timeout,Error.NotConnected ->{ Error.IOError, Error.StreamClosed, Error.Timeout, Error.NotConnected -> {
} }
else -> {} else -> {}
...@@ -172,11 +169,11 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -172,11 +169,11 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 设备登录 * 设备登录
* */ * */
fun login():SignInStatus{ fun login(): SignInStatus {
mOperateLock.lock() mOperateLock.lock()
try { try {
deviceStatus.set(DeviceStatus.Registering) deviceStatus.set(DeviceStatus.Registering)
tcpManager.connect(DeviceConfig.HostConfig.host,DeviceConfig.HostConfig.port,Schedule.tcpConnectTimeoutSecs) tcpManager.connect(DeviceConfig.HostConfig.host, DeviceConfig.HostConfig.port, Schedule.tcpConnectTimeoutSecs)
return if (mOperateCondition.await(Schedule.signInTimeoutSecs, TimeUnit.SECONDS)) { return if (mOperateCondition.await(Schedule.signInTimeoutSecs, TimeUnit.SECONDS)) {
when (deviceStatus.get()) { when (deviceStatus.get()) {
DeviceStatus.Authenticated -> { DeviceStatus.Authenticated -> {
...@@ -189,10 +186,10 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -189,10 +186,10 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
} else { } else {
SignInStatus.SignOut SignInStatus.SignOut
} }
} catch (e:InterruptedException) { } catch (e: InterruptedException) {
loge("登录线程被中断,被中断线程:${Thread.currentThread().name},中断线程:${e.printStackTrace()}") loge("登录线程被中断,被中断线程:${Thread.currentThread().name},中断线程:${e.printStackTrace()}")
return SignInStatus.SignOut return SignInStatus.SignOut
}finally { } finally {
mOperateLock.unlock() mOperateLock.unlock()
} }
} }
...@@ -200,8 +197,8 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -200,8 +197,8 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 添加监听器 * 添加监听器
* */ * */
fun addSessionListener(listener:SessionListener){ fun addSessionListener(listener: SessionListener) {
synchronized(listeners){ synchronized(listeners) {
listeners.add(listener) listeners.add(listener)
} }
} }
...@@ -209,26 +206,50 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -209,26 +206,50 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 删除监听器 * 删除监听器
* */ * */
fun removeSessionListener(listener:SessionListener){ fun removeSessionListener(listener: SessionListener) {
synchronized(listeners){ synchronized(listeners) {
listeners.remove(listener) listeners.remove(listener)
} }
} }
private fun notifyConnectStatus(status: ConnectStatus) {
if (deviceStatus.get() != DeviceStatus.Authenticated) {
return
}
synchronized(listeners) {
listeners.forEach {
it.onConnectStatusChanged(status)
}
}
}
private fun notifySignInStatus(status: SignInStatus, error: Error) {
synchronized(listeners) {
listeners.forEach {
if (status == SignInStatus.SignIn) {
it.onUserSignIn()
} else {
it.onUserSignOut(error)
}
}
}
}
/** /**
* 设备鉴权 * 设备鉴权
* */ * */
private fun doAuthenticate():Boolean{ private fun doAuthenticate(): Boolean {
val b0102 = B0102().apply { val b0102 = B0102().apply {
token = Settings.token token = Settings.token
} }
val request = Message.of(0x0100, b0102).apply { val request = Message.of(0x0102, b0102).apply {
simNo = DeviceConfig.phoneNumber simNo = DeviceConfig.phoneNumber
} }
Message.encode( Message.encode(
request, MessageMetadata.inbounds(), attributeMap, request, MessageMetadata.inbounds(), attributeMap,
UnpooledByteBufAllocator.DEFAULT::buffer, buffs::add UnpooledByteBufAllocator.DEFAULT::buffer, buffs::add
) )
deviceStatus.set(DeviceStatus.Authenticating)
return doSendMessage("设备鉴权") return doSendMessage("设备鉴权")
} }
...@@ -259,14 +280,19 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -259,14 +280,19 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 开始心跳 * 开始心跳
* */ * */
private fun startHeartbeat(){ private fun startHeartbeat() {
scheduleFutureTask = scheduler.scheduleAtFixedRate(::sendPing,0,Schedule.tcpReadIntervalSecs,TimeUnit.SECONDS) scheduleFutureTask = scheduler.scheduleAtFixedRate(
::sendPing,
0,
Schedule.tcpReadIntervalSecs,
TimeUnit.SECONDS
)
} }
/** /**
* 结束心跳 * 结束心跳
* */ * */
private fun stopHeartbeat(){ private fun stopHeartbeat() {
if (scheduleFutureTask?.isDone == false) { if (scheduleFutureTask?.isDone == false) {
scheduleFutureTask?.cancel(true) scheduleFutureTask?.cancel(true)
} }
...@@ -275,7 +301,7 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -275,7 +301,7 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 发送心跳 * 发送心跳
* */ * */
private fun sendPing(){ private fun sendPing() {
val request = Message.of(0x0002).apply { val request = Message.of(0x0002).apply {
simNo = DeviceConfig.phoneNumber simNo = DeviceConfig.phoneNumber
} }
...@@ -289,12 +315,12 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -289,12 +315,12 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
/** /**
* 发送心跳 * 发送心跳
* */ * */
private fun doSendMessage(name:String) = if (buffs.isNotEmpty()) { private fun doSendMessage(name: String) = if (buffs.isNotEmpty()) {
val byteArray = ByteArray(buffs[0].readableBytes()) val byteArray = ByteArray(buffs[0].readableBytes())
buffs[0].readBytes(byteArray) buffs[0].readBytes(byteArray)
logd("【$name】:${HexUtil.dump(byteArray)}") logd("【$name】:${HexUtil.dump(byteArray)}")
tcpManager.send(byteArray) tcpManager.send(byteArray)
synchronized(buffs){ synchronized(buffs) {
buffs.removeAt(0) buffs.removeAt(0)
} }
true true
...@@ -308,64 +334,64 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> { ...@@ -308,64 +334,64 @@ internal class Session : ConnectListener, SyncMessageListener<Codec<*>> {
logd(error.reason) logd(error.reason)
} }
override fun onSignUp(data: Codec<*>) { override fun onSignUp(payload: AbstractToStringJoiner) {
Settings.deviceId = DeviceUtils.getUniqueDeviceId() Settings.deviceId = DeviceUtils.getUniqueDeviceId()
Settings.isRegistered = true Settings.isRegistered = true
Settings.token = (data as B8100Codec).newInstance().token Settings.token = (payload as B8100).token
deviceStatus.set(DeviceStatus.Registered) deviceStatus.set(DeviceStatus.Registered)
tryLogin(::doAuthenticate) tryLogin(::doAuthenticate)
} }
override fun onCommonResponse(data: Codec<*>) { override fun onCommonResponse(payload: AbstractToStringJoiner) {
val codec = (data as B8001Codec).newInstance() val codec = (payload as B8001)
when (codec.replyId) { when (codec.replyId) {
0x0100 ->{ 0x0100 -> {
when(codec.result){ when (codec.result) {
B8001.RESULT_SUCCESSFUL->{ B8001.RESULT_SUCCESSFUL -> {
deviceStatus.set(DeviceStatus.Registered) deviceStatus.set(DeviceStatus.Registered)
loge("设备注册成功!") loge("设备注册成功!")
} }
B8001.RESULT_FAILED->{ B8001.RESULT_FAILED -> {
deviceStatus.set(DeviceStatus.Unregistered) deviceStatus.set(DeviceStatus.Unregistered)
loge("设备注册失败!") loge("设备注册失败!")
} }
B8001.RESULT_WRONG->{ B8001.RESULT_WRONG -> {
deviceStatus.set(DeviceStatus.Unregistered) deviceStatus.set(DeviceStatus.Unregistered)
loge("设备注册消息有误!") loge("设备注册消息有误!")
} }
} }
} }
0x0102 ->{ 0x0102 -> {
when(codec.result){ when (codec.result) {
B8001.RESULT_SUCCESSFUL->{ B8001.RESULT_SUCCESSFUL -> {
if (deviceStatus.get() == DeviceStatus.Authenticating) { if (deviceStatus.get() == DeviceStatus.Authenticating) {
deviceStatus.set(DeviceStatus.Authenticated) deviceStatus.set(DeviceStatus.Authenticated)
startHeartbeat() startHeartbeat()
loge("设备鉴权成功!") loge("设备鉴权成功!")
}else{ } else {
deviceStatus.set(DeviceStatus.UnAuthenticated) deviceStatus.set(DeviceStatus.UnAuthenticated)
loge("设备鉴权失败!") loge("设备鉴权失败!")
} }
} }
B8001.RESULT_FAILED->{ B8001.RESULT_FAILED -> {
deviceStatus.set(DeviceStatus.UnAuthenticated) deviceStatus.set(DeviceStatus.UnAuthenticated)
loge("设备鉴权失败!") loge("设备鉴权失败!")
} }
B8001.RESULT_WRONG->{ B8001.RESULT_WRONG -> {
deviceStatus.set(DeviceStatus.UnAuthenticated) deviceStatus.set(DeviceStatus.UnAuthenticated)
loge("设备鉴权消息有误!") loge("设备鉴权消息有误!")
} }
} }
} }
0x0002->{ 0x0002 -> {
when(codec.result){ when (codec.result) {
B8001.RESULT_SUCCESSFUL->{ B8001.RESULT_SUCCESSFUL -> {
logd("心跳响应成功") logd("心跳响应成功")
} }
B8001.RESULT_FAILED->{ B8001.RESULT_FAILED -> {
loge("心跳响应失败!") loge("心跳响应失败!")
} }
B8001.RESULT_WRONG->{ B8001.RESULT_WRONG -> {
loge("心跳消息有误!") loge("心跳消息有误!")
} }
} }
......
...@@ -3,17 +3,17 @@ package com.waytous.anticollision.tcp ...@@ -3,17 +3,17 @@ package com.waytous.anticollision.tcp
/** /**
* 消息同步监听器 * 消息同步监听器
* */ * */
interface SyncMessageListener<T> { interface SyncMessageListener<in T> {
/** /**
* 设备注册 * 设备注册
* @param data * @param data
* */ * */
fun onSignUp(data:T) fun onSignUp(payload:T)
/** /**
* 平台通用应答 * 平台通用应答
* @param data * @param data
* */ * */
fun onCommonResponse(data:T) fun onCommonResponse(payload:T)
} }
\ No newline at end of file
...@@ -3,7 +3,12 @@ package com.waytous.anticollision.tcp ...@@ -3,7 +3,12 @@ package com.waytous.anticollision.tcp
import com.blankj.utilcode.util.LogUtils import com.blankj.utilcode.util.LogUtils
import com.waytous.anticollision.BuildConfig import com.waytous.anticollision.BuildConfig
import com.waytous.anticollision.utils.logd import com.waytous.anticollision.utils.logd
import io.github.toggery.jt808.codec.* import io.github.toggery.jt808.codec.Codec
import io.github.toggery.jt808.codec.Message
import io.github.toggery.jt808.codec.MessageMetadata
import io.github.toggery.jt808.messagebody.AbstractToStringJoiner
import io.github.toggery.jt808.messagebody.B8001
import io.github.toggery.jt808.messagebody.B8100
import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBuf
import io.netty.util.DefaultAttributeMap import io.netty.util.DefaultAttributeMap
import io.netty.util.ReferenceCountUtil import io.netty.util.ReferenceCountUtil
...@@ -13,7 +18,7 @@ import io.netty.util.ReferenceCountUtil ...@@ -13,7 +18,7 @@ import io.netty.util.ReferenceCountUtil
* *
* @author male * @author male
* */ * */
class SyncParser(private val syncMessageListener: SyncMessageListener<Codec<*>>) { class SyncParser(private val syncMessageListener: SyncMessageListener<AbstractToStringJoiner>) {
/** /**
* 解析字节流 * 解析字节流
...@@ -21,13 +26,12 @@ class SyncParser(private val syncMessageListener: SyncMessageListener<Codec<*>>) ...@@ -21,13 +26,12 @@ class SyncParser(private val syncMessageListener: SyncMessageListener<Codec<*>>)
* */ * */
fun parse(buf: ByteBuf){ fun parse(buf: ByteBuf){
try { try {
val message: Message<Codec<*>> = Message.decode(buf, MessageMetadata.outbounds(), DefaultAttributeMap()) val message: Message<AbstractToStringJoiner> = Message.decode(buf, MessageMetadata.outbounds(), DefaultAttributeMap())
logd("【解析】:$message") logd("【解析】:$message")
when(val codec:Codec<*> = message.body){ when(val payload:Any = message.body){
is B8001Codec -> syncMessageListener.onCommonResponse(codec) is B8100 -> syncMessageListener.onSignUp(payload)
is B8100Codec -> syncMessageListener.onSignUp(codec) is B8001 -> syncMessageListener.onCommonResponse(payload)
} }
LogUtils.d(message.toString())
} catch (e: Exception) { } catch (e: Exception) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
LogUtils.e("parse received data error:${e.message}") LogUtils.e("parse received data error:${e.message}")
......
...@@ -142,10 +142,12 @@ internal class TcpManager( ...@@ -142,10 +142,12 @@ internal class TcpManager(
} }
val (errCode, length) = connection.receive() val (errCode, length) = connection.receive()
if (errCode == Error.NOError) { if (errCode == Error.NOError) {
val buf = UnpooledByteBufAllocator.DEFAULT.buffer(length) if (length > 0) {
buf.writeBytes(connection.buffer, 0, length) val buf = UnpooledByteBufAllocator.DEFAULT.buffer(length)
connectListener.onDataReceived(buf) buf.writeBytes(connection.buffer, 0, length)
connection.buffer.fill(0, 0, length - 1) connectListener.onDataReceived(buf)
connection.buffer.fill(0, 0, length - 1)
}
receiveExecutor.execute { receive(timeout) } receiveExecutor.execute { receive(timeout) }
} else { } else {
mCancel.set(true) mCancel.set(true)
...@@ -212,40 +214,39 @@ internal class TcpManager( ...@@ -212,40 +214,39 @@ internal class TcpManager(
* @param timeout * @param timeout
* @return Error * @return Error
* */ * */
fun connect(host: String, port: Int, timeout: Int, receiveInterval: Int = 2): Error = try { fun connect(host: String, port: Int, timeout: Int, receiveInterval: Int = 2): Error {
receiveLock.lock() try {
sendLock.lock() receiveLock.lock()
var errorCode: Error = Error.NOError sendLock.lock()
if (socket.isConnected && connectStatus.get() > State.Disconnected) { if (socket.isConnected && connectStatus.get() > State.Disconnected) {
errorCode = Error.NOError return Error.NOError
} else { }
closeSocket() connectStatus.set(State.Connecting)
socket.soTimeout = receiveInterval
socket.connect(
InetSocketAddress(host, port),
if (timeout > 0) timeout else DEFAULT_TIMEOUT
)
inputStream = socket.getInputStream()
outputStream = socket.getOutputStream()
connectStatus.set(State.Connected)
return Error.NOError
} catch (e: IOException) {
connectStatus.set(State.Disconnected)
return Error.IOError
} catch (e: SocketTimeoutException) {
connectStatus.set(State.Disconnected)
return Error.Timeout
} catch (e: IllegalArgumentException) {
connectStatus.set(State.Disconnected)
return Error.InvalidParam
} catch (e: Exception) {
connectStatus.set(State.Disconnected)
return Error.ServerUnknownError
} finally {
sendLock.unlock()
receiveLock.unlock()
} }
connectStatus.set(State.Connecting)
socket.soTimeout = receiveInterval
socket.connect(
InetSocketAddress(host, port),
if (timeout > 0) timeout else DEFAULT_TIMEOUT
)
inputStream = socket.getInputStream()
outputStream = socket.getOutputStream()
connectStatus.set(State.Connected)
errorCode
} catch (e: IOException) {
connectStatus.set(State.Disconnected)
Error.IOError
} catch (e: SocketTimeoutException) {
connectStatus.set(State.Disconnected)
Error.Timeout
} catch (e: IllegalArgumentException) {
connectStatus.set(State.Disconnected)
Error.InvalidParam
} catch (e: Exception) {
connectStatus.set(State.Disconnected)
Error.ServerUnknownError
} finally {
sendLock.unlock()
receiveLock.unlock()
} }
/** /**
...@@ -292,7 +293,7 @@ internal class TcpManager( ...@@ -292,7 +293,7 @@ internal class TcpManager(
Error.NotConnected, Error.NotConnected,
0 0
) )
if (inputStream.available() < 0) return ReceivedResult(Error.NOError, 0) if (inputStream.available() <= 0) return ReceivedResult(Error.NOError, 0)
val len = inputStream.read(buffer) val len = inputStream.read(buffer)
return if (len > 0) { return if (len > 0) {
ReceivedResult(Error.NOError, len) ReceivedResult(Error.NOError, len)
......
...@@ -37,31 +37,31 @@ class HomeFragment : Fragment() { ...@@ -37,31 +37,31 @@ class HomeFragment : Fragment() {
_binding = FragmentHomeBinding.inflate(inflater, container, false) _binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root val root: View = binding.root
// val mapView: MapView = binding.mapView val mapView: MapView = binding.mapView
val mapView = MapView(this.context!!) // val mapView = MapView(this.context!!)
mapView.getMapboxMap().setCamera( mapView.getMapboxMap().setCamera(
CameraOptions.Builder() CameraOptions.Builder()
.center( // .center(
Point.fromLngLat( // Point.fromLngLat(
LATITUDE, // LATITUDE,
LONGITUDE // LONGITUDE
)) // ))
.zoom(ZOOM).build() .zoom(ZOOM).build()
) )
mapView.getMapboxMap().loadStyle(style(Style.MAPBOX_STREETS){ mapView.getMapboxMap().loadStyle(style(Style.OUTDOORS){
+geoJsonSource(GEOJSON_SOURCE_ID) +geoJsonSource(GEOJSON_SOURCE_ID)
{ {
url("multiple_geometry_example.geojson") url("asset://multiple_geometry_example.geojson")
}
+lineLayer("linelayer", GEOJSON_SOURCE_ID) {
lineCap(LineCap.ROUND)
lineJoin(LineJoin.ROUND)
lineOpacity(0.7)
lineWidth(8.0)
lineColor("#888")
} }
// +lineLayer("linelayer", GEOJSON_SOURCE_ID) {
// lineCap(LineCap.ROUND)
// lineJoin(LineJoin.ROUND)
// lineOpacity(0.7)
// lineWidth(8.0)
// lineColor("#888")
// }
}) })
return mapView return root
} }
override fun onDestroyView() { override fun onDestroyView() {
...@@ -71,8 +71,8 @@ class HomeFragment : Fragment() { ...@@ -71,8 +71,8 @@ class HomeFragment : Fragment() {
companion object { companion object {
private const val GEOJSON_SOURCE_ID = "geo-json" private const val GEOJSON_SOURCE_ID = "geo-json"
private const val LATITUDE = -122.483696 private const val LATITUDE = -77.0911931991577
private const val LONGITUDE = 37.833818 private const val LONGITUDE = 38.95653886174238
private const val ZOOM = 14.0 private const val ZOOM = 14.0
} }
} }
\ No newline at end of file
...@@ -8,9 +8,9 @@ import kotlin.reflect.KProperty ...@@ -8,9 +8,9 @@ import kotlin.reflect.KProperty
class PreferenceDelegate<T>(private val name: String, private val default: T, private val prefName: String = "settings") class PreferenceDelegate<T>(private val name: String, private val default: T, private val prefName: String = "settings")
: ReadWriteProperty<Any?, T> { : ReadWriteProperty<Any?, T> {
private val prefs: SharedPreferences by lazy {
MyApp.instance.applicationContext.getSharedPreferences(prefName, Context.MODE_PRIVATE) private val prefs: SharedPreferences =
} MyApp.instance().applicationContext.getSharedPreferences(prefName, Context.MODE_PRIVATE)
@Synchronized @Synchronized
override fun getValue(thisRef: Any?, property: KProperty<*>): T { override fun getValue(thisRef: Any?, property: KProperty<*>): T {
......
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
android:id="@+id/mapView" android:id="@+id/mapView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
mapbox:mapbox_cameraTargetLat="40.7128"
mapbox:mapbox_cameraTargetLng="-74.0060"
mapbox:mapbox_cameraZoom="9.0"
mapbox:mapbox_resourcesAccessToken="@string/map_box_public_key" mapbox:mapbox_resourcesAccessToken="@string/map_box_public_key"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment