Commit 86ea637f authored by p x's avatar p x
Browse files

对通2个51 的socket

parent d261bf13
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
......@@ -42,14 +41,14 @@ android {
dataBinding = true
}
lint {
abortOnError=false
checkReleaseBuilds=false
abortOnError = false
checkReleaseBuilds = false
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs","include" to listOf("*.jar", "*.aar"))))
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
......@@ -59,7 +58,7 @@ dependencies {
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation("com.google.protobuf:protobuf-java:4.31.1")
implementation("com.google.protobuf:protobuf-java:4.31.1")
// implementation("com.google.protobuf:protobuf-javalite:4.31.1")
// implementation("com.google.protobuf:protoc:3.0.0")
// implementation("com.google.protobuf:protobuf-kotlin-lite:4.31.1")
......@@ -78,16 +77,20 @@ implementation("com.google.protobuf:protobuf-java:4.31.1")
// 权限请求框架
implementation("com.guolindev.permissionx:permissionx:1.8.1")
//加密库
implementation("androidx.security:security-crypto:1.0.0")
// implementation("androidx.security:security-crypto:1.0.0")
// implementation("com.gyf.immersionbar:immersionbar:2.3.3-beta15")
//四维依赖
// implementation("com.jakewharton.timber:timber:4.5.1")
// implementation("com.mapzen.android:lost:2.1.2")
//网络
implementation("io.reactivex.rxjava3:rxjava:3.0.8")
implementation("io.reactivex.rxjava3:rxandroid:3.0.0")
// implementation("io.reactivex.rxjava3:rxjava:3.0.8")
// implementation("io.reactivex.rxjava3:rxandroid:3.0.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0")
// implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0")
implementation("com.squareup.retrofit2:converter-scalars:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
}
\ No newline at end of file
......@@ -78,6 +78,8 @@
android:screenOrientation="landscape">
</activity>
</application>
</manifest>
\ No newline at end of file
{
"sources": {
"3DTiles": {
"url": "http://support.minedata.cn:81/testdata/Qingdao3DTile/tileset.json",
"type": "3d-tiles",
"maximumScreenSpaceError":12
},
"MERGE_2":{"tiles":["cloudservice://mvt-layer/merge/{z}/{r}/{c}/{z}_{x}_{y}.pbf"],
"type":"vector"
},
"satellite":{"tiles":["http://smap.minedata.com.cn/service/map/satellite?z={z}&x={x}&y={y}"],
"tileSize":256,
"type":"raster"
}
},
"layers": [{
"layout": {
"visibility": "visible"
},
"maxzoom": 20.0,
"paint": {
"background-color": "#f5f5f5"
},
"source": "",
"source-layer": "",
"id": "9d86a24a66294b15be50e254e3d4f8ad",
"type": "background",
"minzoom": 0.0
},
{
"layout": {
"visibility": "visible"
},
"maxzoom": 3.0,
"source": "",
"source-layer": "",
"id": "9d86a24a66294b15be50e254e3d4f8adsphere",
"type": "sphere",
"minzoom": 0.0
},
{"layout":{"visibility":"none"},
"maxzoom":17.5,
"paint":{},
"source":"satellite",
"source-layer":"satellite",
"id":"b541e3a11b2449959669855aa5e84acb",
"type":"raster",
"minzoom":3
},
{
"layout": {
"visibility": "visible"
},
"maxzoom": 20.0,
"source": "3DTiles",
"source-layer": "",
"id": "9d86a24a66294b15be50e254e3d4f8ae",
"type": "3d-tiles",
"minzoom": 0.0
},{
"layout": {
"visibility": "none",
"border-visibility": "visible",
"line-cap": "butt",
"line-join": "round"
},
"maxzoom": 20,
"paint": {
"line-translate-anchor": "viewport",
"line-width": 5.2,
"line-border-width": 1,
"line-border-color": "#dcc21a",
"line-color": "#fee566"
},
"source": "MERGE_2",
"source-layer": "natProHighway",
"id": "1022902036979085408",
"type": "line",
"minzoom": 7
},
{
"layout": {
"visibility": "none"
},
"maxzoom": 20,
"paint": {
"extrusion-height": {
"property": "levels",
"type": "identity"
},
"extrusion-color": "#fdf7f9",
"extrusion-base": 0,
"extrusion-opacity": 0.3,
"extrusion-translate-anchor": "viewport",
"extrusion-translate": [0, 0]
},
"source": "MERGE_2",
"source-layer": "building",
"id": "1022902036979085390",
"type": "extrusion",
"minzoom": 13
}
],
"version": 8
}
\ No newline at end of file
package com.sd.cavphmi;
public class Config {
public static String HOST = "minedata.cn";//证书校验,跟地图数据无关
public static String SCHEME = "https";//证书校验,跟地图数据无关
public static String MAP_TOK = "882391b74f344ec8b116305f2dd7340c";
public static String MAP_ID = "1022902036664512512";//白天
public static String MAP_NIGHT_TOK = "882391b74f344ec8b116305f2dd7340c";
public static String MAP_NIGHT_ID = "1022905981000577024";//黑夜
public static String MAP_BLUE_ID = "1022905736803942400";//极夜蓝
public static String BASE_URL = "https://service.minedata.cn/map/solu/style/";
public static String SATELLITE_URL = "http://218.2.231.245/mapjs2/rest/services/MapJS/js_yxdt_2016/MapServer/tile/{z}/{y}/{x}";//暂定
public static String OFFLINE_URL = "https://minedata.cn/lbsservice/mapdownload/datastore.json";//暂定
public static String OFFLINE_TOK = "882391b74f344ec8b116305f2dd7340c";//暂定
public static String API_BASE_URL = "https://sd-data.minedata.cn";
public static String API_DYNAMIC_DATA_URL = "https://service.minedata.cn";
public static String API_URL = "https://minemap.minedata.cn";
public static String API_VERSION = "v2.1.1";
//地图中心点
public static double mapCentrelat = 41.810246132876834;//41.80196;
public static double mapCentrelon = 123.4418114224643;//123.43326;
}
package com.sd.cavphmi.bean
import androidx.annotation.IntDef
import androidx.databinding.ObservableField
// 使用@IntDef注解这些常量
@IntDef(GearStatus.P, GearStatus.R, GearStatus.N, GearStatus.D)
@Retention(AnnotationRetention.SOURCE)
annotation class GearStatus {
companion object {
// 定义状态常量
const val P = 33
const val R = 32
const val N = 34
const val D = 31
}
}
/**
* 车辆仪表
* */
class CarPanelBean {
companion object {
val instance: CarPanelBean by lazy { CarPanelBean() }
}
/***CAN 总线数据中的行驶速度,单位:0.01m/s,0xFFFF 表 示缺省***/
var speed = ObservableField(0)
/***档位**/
var tapPos = ObservableField<Int>(GearStatus.P)
//剩余油量或电量
var remainSoc = ObservableField<Int>(0)
//转向灯 1=left 2=right
var lights = ObservableField<Int>(-1)
/*** 枚举类型:[0..9],1:人工接管(人工驾驶);2:单车自控(自动驾
* 驶);3:云端支持下的人工驾驶;4:云端支持下的自动驾驶;5:非
* 主驾位置人工驾驶(不启用);6:脱离(非自动驾驶行程自动结束下
* 的接管);7:远程驾驶(非现场人工驾驶);8:未处于任何驾驶模式;
* 9:其他未定义状态;0xFF 表示缺省*/
var driveMode = ObservableField("")
//航向角0.。360
var heading = ObservableField<Int>(0)
}
\ No newline at end of file
package com.sd.cavphmi.bean
/***车辆位资数据
*{"vehicleData":[{"altitude":0.00,"brake":30,"gasPedal":20,"gear":2,"heading":208.61645962016533,"latitude":43.83869937,"longitude":125.14344480,"obuCode":"O-HK-2687","reportTime":1750300843548,"speed":0.00,"vehicleId":"1694264612474306561","vehiclePlate":"吉AC242","vehiclePurpose":"avp","vehiclePurposeName":"AVP车辆","wheelAngle":-375}],"wsTime":1750300843548}
/***网联车辆位姿
*{"version":"2.0.0","data_id":"default","data_type":"OBU","data_list":[{"vid":"245","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5013455,39.8110367","direction":330.2354,"speed":0.0,"timestamp":1754464768658,"vinfo":{"door":1,"light":1,"wiper":0}},{"vid":"261","vmodel":"01010102001","vtype":"双层客车1","coord_type":"Geo","coord":"117.345278,39.0059533","direction":346.8844,"speed":47.0,"timestamp":1754464768625,"vinfo":{"door":0,"light":0,"wiper":1,"poleId":"1200003938"}},{"vid":"263","vmodel":"01010400006","vtype":"中型客车","coord_type":"Geo","coord":"117.3505606,39.0030274","direction":356.9585,"speed":58.0,"timestamp":1754464768626,"vinfo":{"door":0,"light":0,"wiper":1}},{"vid":"265","vmodel":"01010400001","vtype":"清扫","coord_type":"Geo","coord":"117.346545,39.001303","direction":0.27499999999997726,"speed":0.0,"timestamp":1754464768627,"vinfo":{"door":0,"light":0,"wiper":1,"poleId":"1200001928"}},{"vid":"267","vmodel":"01010400003","vtype":"售卖","coord_type":"Geo","coord":"117.3463217,38.9951148","direction":94.40610000000004,"speed":0.0,"timestamp":1754464768628,"vinfo":{"door":0,"light":36864,"wiper":1,"poleId":"1200003838"}},{"vid":"269","vmodel":"01010400004","vtype":"出租","coord_type":"Geo","coord":"117.3465439,38.9954946","direction":274.5396,"speed":53.0,"timestamp":1754464768627,"vinfo":{"door":0,"light":0,"wiper":1,"poleId":"1200003838"}},{"vid":"335","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5014316,39.8110748","direction":330.2354,"speed":0.0,"timestamp":1754464768655,"vinfo":{"door":1,"light":1,"wiper":0}},{"vid":"363","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5030884,39.8089693","direction":238.19000000000005,"speed":0.0,"timestamp":1754464768657,"vinfo":{"door":1,"light":1,"wiper":0}},{"vid":"355","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5024007,39.8101233","direction":329.1582,"speed":0.0,"timestamp":1754464768656,"vinfo":{"door":1,"light":1,"wiper":0}},{"vid":"271","vmodel":"01010400008","vtype":"巡逻车","coord_type":"Geo","coord":"117.3471332,39.0015908","direction":271.231,"speed":60.0,"timestamp":1754464768627,"vinfo":{"door":0,"light":0,"wiper":1,"poleId":"1200001928"}},{"vid":"369","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5012194,39.8088289","direction":256.06500000000005,"speed":0.0,"timestamp":1754464768656,"vinfo":{"door":1,"light":1,"wiper":0}},{"vid":"367","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5027912,39.8087311","direction":58.24649999999997,"speed":0.0,"timestamp":1754464768657,"vinfo":{"door":1,"light":1,"wiper":0}},{"vid":"359","vmodel":"01010108001","vtype":"Ambulance","coord_type":"Geo","coord":"116.5012066,39.8088949","direction":263.1252999999999,"speed":0.0,"timestamp":1754464768658,"vinfo":{"door":1,"light":1,"wiper":0}}]}
* **/
data class CarVehicle(
val vehicleData: List<CarVehicleData>,
val wsTime: Long
val data_id: String,
val data_list: List<VData>,
val data_type: String,
val version: String
)
data class CarVehicleData(
val altitude: Double,
val brake: Int,
val gasPedal: Int,
val gear: Int,
val heading: Float,
val latitude: Double,
val longitude: Double,
val obuCode: String,
val reportTime: Long,
val speed: Float,//m/s
val vehicleId: String,
val vehiclePlate: String,
val vehiclePurpose: String,
val vehiclePurposeName: String,
val wheelAngle: Int
data class VData(
val coord: String,
val coord_type: String,//"117.345278,39.0059533",
val direction: Double,//航向角
val speed: Double,
val timestamp: Long,
val vid: String,
val vinfo: Vinfo,
val vmodel: String,
val vtype: String
)
data class Vinfo(
val door: Int,
val light: Int,
val poleId: String,
val wiper: Int
)
\ No newline at end of file
package com.sd.cavphmi.bean
/**感知目标物
* {"objectData":[{"altitude":0.0,"deviceCode":"ALL","id":"rsm","latitude":0.0,"longitude":0.0,"participant":[{"gear":0,"heading":59.51892445105614,"latitude":43.836595395579934,"longitude":125.13730164662486,"ptcId":"0","ptcType":"non-motor","size":{"length":1.7816076278686523,"width":0.95207178592681885,"height":1.080740213394165},"speed":0.0030517578125}],"reportTime":1750148176068}],"wsTime":1750148130604}{"objectData":[{"altitude":0.0,"deviceCode":"ALL","id":"rsm","latitude":0.0,"longitude":0.0,"participant":[{"gear":0,"heading":59.51892445105614,"latitude":43.836595395579934,"longitude":125.13730164662486,"ptcId":"0","ptcType":"non-motor","size":{"length":1.7816076278686523,"width":0.95207178592681885,"height":1.080740213394165},"speed":0.0030517578125}],"reportTime":1750148176068}],"wsTime":1750148130604}
*
* {"version":"2.0.0","data_id":"f33f1961-af28-4e87-9b66-084e99720e56","data_type":"路侧感知数据","data_list":[{"vid":"200690","vmodel":"01010104000","vtype":"CAR","coord_type":"Geo","coord":"117.3255554,38.9960103","direction":289.3393,"speed":0.0,"timestamp":1754466394391,"vinfo":null},{"vid":"200696","vmodel":"01010104000","vtype":"CAR","coord_type":"Geo","coord":"117.3255172,38.9960139","direction":289.3537,"speed":0.0,"timestamp":1754466394391,"vinfo":null},{"vid":"400357","vmodel":"01020101014","vtype":"MID_COACH","coord_type":"Geo","coord":"117.325676,38.9966065","direction":109.39340000000004,"speed":0.0,"timestamp":1754466394391,"vinfo":null},{"vid":"400358","vmodel":"01020101013","vtype":"SUV","coord_type":"Geo","coord":"117.3256466,38.9965419","direction":109.59839999999997,"speed":0.0,"timestamp":1754466394391,"vinfo":null},{"vid":"200699","vmodel":"01020101013","vtype":"SUV","coord_type":"Geo","coord":"117.3254728,38.9959157","direction":289.3537,"speed":6.8759999999999994,"timestamp":1754466394391,"vinfo":null},{"vid":"200700","vmodel":"01010104000","vtype":"CAR","coord_type":"Geo","coord":"117.3255258,38.9959447","direction":289.3393,"speed":0.684,"timestamp":1754466394391,"vinfo":null},{"vid":"400363","vmodel":"01010102000","vtype":"ARGE_COACH","coord_type":"Geo","coord":"117.3257287,38.9967229","direction":109.39340000000004,"speed":0.0,"timestamp":1754466394391,"vinfo":null},{"vid":"300370","vmodel":"01010102000","vtype":"ARGE_COACH","coord_type":"Geo","coord":"117.3258973,38.9968533","direction":289.3811,"speed":60.01200000000001,"timestamp":1754466394391,"vinfo":null},{"vid":"300371","vmodel":"01010104000","vtype":"CAR","coord_type":"Geo","coord":"117.3257478,38.9965232","direction":289.29,"speed":58.104000000000006,"timestamp":1754466394391,"vinfo":null},{"vid":"300372","vmodel":"01020101013","vtype":"SUV","coord_type":"Geo","coord":"117.325127,38.9963078","direction":356.99649999999997,"speed":59.11200000000001,"timestamp":1754466394391,"vinfo":null}]}
*
* ***/
data class PerTarget(
val objectData: List<ObjectData>,
val wsTime: Long
)
data class ObjectData(
val altitude: Double,
val deviceCode: String,
val id: String,
val latitude: Double,
val longitude: Double,
val participant: List<Participant>,
val reportTime: Long
)
data class Participant(
val gear: Int,
val heading: Double,
val latitude: Double,
val longitude: Double,
val ptcId: String,
val ptcType: String,
val size: Size,
val speed: Double
data class PerTarget(
val data_id: String,
val data_list: List<PData>,
val data_type: String,
val version: String
)
data class Size(
val height: Double,
val length: Double,
val width: Double
data class PData(
val coord: String,
val coord_type: String,
val direction: Double,
val speed: Double,
val timestamp: Long,
val vid: String,
val vinfo: Any,
val vmodel: String,
val vtype: String
)
\ No newline at end of file
package com.sd.cavphmi.bindadapters
import android.graphics.Color
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.graphics.toColorInt
import androidx.databinding.BindingAdapter
import com.sd.cavphmi.R
import com.sd.cavphmi.bean.GearStatus
import com.sd.cavphmi.ui.view.HeadAngelView
object ShowCarPanelObject {
@JvmStatic
@BindingAdapter(value = ["showSpeed", "spdExp"], requireAll = false)
fun showSpeed(tv: TextView, speed: Int, spdExp: Int) {
tv.setText(speed.toString())
}
/***档位*
* **/
@JvmStatic
@BindingAdapter("showTapPos")
fun showTapPos(tv: TextView, @GearStatus gear: Int) {
var tag = tv.tag.toString().toInt()
// println("--------tag = ${tag} gear = ${gear}")
if (tag == gear) {
tv.setTextColor(Color.BLACK)
} else {
// tv.setTextColor(Color.GRAY)
tv.setTextColor("#66000000".toColorInt())
}
}
/***剩余油或者电***/
@JvmStatic
@BindingAdapter("showProTv")
fun showProTv(tv: TextView, pro: Int) {
tv.text = "${pro}%"
}
/***剩余油或者电***/
@JvmStatic
@BindingAdapter("showProgress")
fun showProgress(bar: ProgressBar, pro: Int) {
bar.setProgress(pro)
}
/***汽车转向灯 32769 0x8009=右转 ***/
@JvmStatic
@BindingAdapter("showTurnLight")
fun showTurnLight(ll: LinearLayout, lights: Int) {
if (lights == -1)
return
var temp = lights
//0:有效;1:车灯状态字段全部无效(或未获取数据)
var valid = temp.shr(15)
//取第3-4位 bit3=左转灯 bit4=右转灯 2个都开deng=12
val turn = lights.and(0xC)
var count = ll.childCount
for (i in 0..count - 1) {
var iv = ll.getChildAt(i) as ImageView
var tag = iv.tag
if (tag.equals("left")) {
if (turn == 4) {
iv.setImageResource(R.drawable.trun_left_blue)
} else {
iv.setImageResource(R.drawable.trun_left_grey)
}
} else if (tag.equals("right")) {
if (turn == 8) {
iv.setImageResource(R.drawable.trun_right_blue)
} else {
iv.setImageResource(R.drawable.trun_right_grey)
}
}
// if (turn == 4) {
// if (tag.equals("left")) {
// iv.setImageResource(R.drawable.trun_left_blue)
// } else {
// iv.setImageResource(R.drawable.trun_right_grey)
// }
// } else if (turn == 8) {
// if (tag.equals("right")) {
// iv.setImageResource(R.drawable.trun_right_blue)
// } else {
// iv.setImageResource(R.drawable.trun_left_grey)
// }
// }
}
}
/***是否自动驾驶***/
@JvmStatic
@BindingAdapter("showAutoDri")
fun showAutoDri(tv: TextView, auto: Int) {
when (auto) {
2, 6 -> {
tv.text = "自动驾驶"
}
1, 3 -> {
tv.text = "人工驾驶"
}
}
}
/***航向角***/
@JvmStatic
@BindingAdapter("showHeading")
fun showHeading(iv: HeadAngelView, heading: Float) {
// println("---------showHeading = ${heading}")
iv.setHeadAngel(heading)
}
/***高精地图里的车辆仪表界面***/
@JvmStatic
@BindingAdapter(value = ["showMapCarPan", "isStartNai"], requireAll = false)
fun showMapCarPan(fl: FrameLayout, isHighMap: Boolean,isStartNai: Boolean) {
// println("---------showHeading = ${heading}")
if (isHighMap){
// if (isStartNai){
fl.visibility= View.VISIBLE
// var params=fl.layoutParams as RelativeLayout.LayoutParams
// params.height= DisplayUtil.dp2px(106f)
// fl.layoutParams=params
// }
} else {
fl.visibility= View.GONE
}
}
}
\ No newline at end of file
package com.sd.cavphmi.bindadapters
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.RelativeSizeSpan
import android.text.style.StyleSpan
import android.widget.ImageView
import android.widget.TextView
import androidx.databinding.BindingAdapter
import com.sd.cavphmi.R
import java.text.DecimalFormat
import kotlin.math.absoluteValue
object ShowCarStatuObject {
/**信号***/
@JvmStatic
@BindingAdapter("showXinhao")
fun showXinhao(iv: ImageView, timeDiff: Int) {
when (timeDiff) {
in 1..100 -> iv.setImageResource(R.drawable.xinhao5)
in 101..200 -> iv.setImageResource(R.drawable.xinhao4)
in 201..300 -> iv.setImageResource(R.drawable.xinhao3)
in 301..400 -> iv.setImageResource(R.drawable.xinhao2)
else -> {
iv.setImageResource(R.drawable.xinhao1)
}
}
}
/**泊车状态***/
@JvmStatic
@BindingAdapter("showAvpStatus")
fun showAvpStatus(tv: TextView, avpStatus: Int?) {
when (avpStatus) {
1 -> tv.setText("场外行驶")
2, 6 -> tv.setText("场内行驶")
3 -> tv.setText("自动泊车中")
4 -> tv.setText("车辆停靠")
5 -> tv.setText("自动召车中")
else -> {
tv.setText("")
}
}
}
@JvmStatic
@BindingAdapter("showSpeed")
fun showSpeed(tv: TextView, speed: Float) {
var sb = SpannableStringBuilder()
var mixSpan = RelativeSizeSpan(1f)
var maxSpan = RelativeSizeSpan(2f)
var bold = StyleSpan(Typeface.BOLD)
if (speed > 0f) {
val df: DecimalFormat = DecimalFormat("#.0")
val s: String = df.format(speed.times(3.6f))
sb.append("${s}km/h")
sb.setSpan(maxSpan, 0, s.count(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
sb.setSpan(bold, 0, s.count(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
sb.setSpan(mixSpan, s.count(), sb.count(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
tv.setText(sb)
} else {
sb = SpannableStringBuilder("0km/h")
sb.setSpan(maxSpan, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
sb.setSpan(bold, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
sb.setSpan(mixSpan, 1, sb.count(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
tv.setText(sb)
}
}
@JvmStatic
@BindingAdapter("showHeading")
fun showHeading(tv: TextView, head: Int) {
var heading = head.absoluteValue
when (heading) {
0 -> {
tv.setText("正北")
}
90 -> {
tv.setText("正东")
}
180 -> {
tv.setText("正南")
}
270 -> {
tv.setText("正北")
}
in 1..45 -> {
tv.setText("北偏东${heading}°")
}
in 46..89 -> {
tv.setText("东偏北${90-heading}°")
}
in 91..135 -> {
tv.setText("东偏南${heading-90}°")
}
in 136..179 -> {
tv.setText("南偏东${180 - heading}°")
}
in 181..225 -> {
tv.setText("南偏西${heading - 180}°")
}
in 226..269 -> {
tv.setText("西偏南${270 - heading}°")
}
in 271..315 -> {
tv.setText("西偏北${heading - 270}°")
}
in 316..359 -> {
tv.setText("北偏西${360 - heading}°")
}
else -> {
tv.setText(" - -")
}
}
}
}
\ No newline at end of file
......@@ -6,7 +6,6 @@ import com.sd.cavphmi.MyAppcation
import com.sd.cavphmi.utils.MyContants
import okhttp3.Cache
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.File
......@@ -37,7 +36,7 @@ object RetrofitApi {
.baseUrl(MyContants.HOST)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(mGson))
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
// .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
}
......
......@@ -11,6 +11,7 @@ import com.sd.cavphmi.bean.ParkBean
import com.sd.cavphmi.bean.VehicleStats
import com.sd.cavphmi.databinding.ActivityMainBinding
import com.sd.cavphmi.intfaces.OnConCan
import com.sd.cavphmi.ui.fragment.CarPanelFragment
import com.sd.cavphmi.viewmodels.AvpMapVM
import com.sd.cavphmi.viewmodels.MainVm
import com.sd.cavphmi.viewmodels.MockVM
......@@ -40,21 +41,22 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
private val avpMapVM: AvpMapVM by viewModels()
private lateinit var dialogFragment: ExitAppDialog
//汽车仪表
private val carPanelFragment by lazy { CarPanelFragment.newInstance() }
override fun initView() {
viewModel.mockVM = mockVM
var ft = supportFragmentManager.beginTransaction()
ft.add(R.id.map_car_pan, carPanelFragment, "1")
ft.commit()
}
override fun getToData() {
viewModel.startWS()
viewModel.getCurrentTime()
viewModel.getMobileNetworkSignal()
viewModel.getOrderData()
viewModel.getSpaceDataLoc()
// viewModel.getSpaceData()
//test
// viewModel.findPathPlanning()
// viewModel.getOrderData()
// viewModel.getSpaceDataLoc()
}
override fun initListener() {
......@@ -73,7 +75,7 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
private fun mockBt() {
binding.btVehicle.setOnClickListener {
viewModel.subVehicle().observe(this) {
topicVehicle(it)
// topicVehicle(it)
}
}
binding.btStatus.setOnClickListener {
......@@ -82,6 +84,7 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
topicVehicleStatus(it)
}
}
//感知目标物
binding.btTarget.setOnClickListener {
viewModel.subTarget()
}
......
package com.sd.cavphmi.ui.fragment
import androidx.lifecycle.ViewModelProvider
import com.sd.cavphmi.BR
import com.sd.cavphmi.R
import com.sd.cavphmi.base.BaseFragment
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.databinding.FragmentCarPanelBinding
import dagger.hilt.android.AndroidEntryPoint
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
//private const val ARG_PARAM1 = "param1"
//private const val ARG_PARAM2 = "param2"
/**
* 车仪表
*/
@AndroidEntryPoint
class CarPanelFragment : BaseFragment<FragmentCarPanelBinding, MyBaseViewModel>() {
//
// private var param1: String? = null
// private var param2: String? = null
//
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// arguments?.let {
// param1 = it.getString(ARG_PARAM1)
// param2 = it.getString(ARG_PARAM2)
// }
// }
override fun getStatuBarColor(): Int {
return -1
}
override fun isAutoStatusBarDarkModeEnable(): Boolean {
return false
}
override fun initContentView(): Int {
return R.layout.fragment_car_panel
}
override fun initViewModel(): MyBaseViewModel {
return ViewModelProvider(this).get(MyBaseViewModel::class.java)
}
override fun initVariableId(): Int {
return BR.vm
}
override fun initView() {
}
override fun initListener() {
}
override fun getToData() {
}
companion object {
// lateinit var cp: CarPanelFragment
// @JvmStatic
// fun newInstance(param1: String, param2: String) =
// CarPanel().apply {
// arguments = Bundle().apply {
// putString(ARG_PARAM1, param1)
// putString(ARG_PARAM2, param2)
// }
// }
@JvmStatic
fun newInstance() = CarPanelFragment()
}
}
\ No newline at end of file
package com.sd.cavphmi.ui.view
import android.animation.Animator
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
/**
* 航向角
* */
class HeadAngelView : AppCompatImageView {
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init()
}
private lateinit var rotationAnimator: ObjectAnimator
var start = 0f
var end = 0f
var cur = 0f
// private var emitter: ObservableEmitter<Float>? = null
fun init() {
rotationAnimator = ObjectAnimator.ofFloat(this, "rotation", start)
rotationAnimator.setDuration(300) // 设置动画持续时间,单位为毫秒
rotationAnimator.addUpdateListener(animatorUpdateListener)
// Observable.create<Float> { emitter ->
// this.emitter = emitter
// }.throttleLast(1, TimeUnit.SECONDS)
// .subscribeOn(AndroidSchedulers.mainThread())
// .subscribe({ next ->
// println("----------next = ${next}")
// rotationAnimator.cancel()
// rotationAnimator.setFloatValues(cur, end)
// rotationAnimator.start()
// }, {}, {})
}
fun setFirst() {
rotationAnimator.cancel()
rotationAnimator.setFloatValues(cur, start)
rotationAnimator.start()
}
fun setHeadAngel(newHead: Float) {
if (newHead < 0f)
return
end = newHead
// emitter?.onNext(end)
rotationAnimator.cancel()
rotationAnimator.setFloatValues(cur, end)
rotationAnimator.start()
}
private var animatorListener = object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
}
override fun onAnimationEnd(animation: Animator) {
}
override fun onAnimationCancel(animation: Animator) {
}
override fun onAnimationRepeat(animation: Animator) {
}
}
private var animatorUpdateListener = object : ValueAnimator.AnimatorUpdateListener {
override fun onAnimationUpdate(animation: ValueAnimator) {
// println("------------animation = ${animation.animatedValue}")
cur = animation.animatedValue as Float
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
// rotationAnimator.removeAllListeners()
rotationAnimator.removeUpdateListener(animatorUpdateListener)
}
}
\ No newline at end of file
......@@ -6,10 +6,11 @@ object MyContants {
var HOST = if (IS_DEBUG) "https://faw.cuscavp.cn:8443" else ""
// var PORT = if (IS_DEBUG) "123" else "34534"
//wss://faw.cuscavp.cn:8443/socket/ws?clientSource=100 长春
var WS_HOST =
if (IS_DEBUG) "wss://faw.cuscavp.cn:8443/socket/ws?clientSource=100" else ""
/***网联车辆位姿***/
var WS_VEH_LOC = "wss://itg-dev.cu-sc.com:19443/WSPLUSV5/socket?token=111&msgType=2&reType=51world"
/***感知目标物***/
var WS_FEEL_TARGET = "wss://itg-dev.cu-sc.com:19443/WSPLUSV5/socket?token=111&msgType=1&reType=51world"
/***已经**/
const val ALREADT_ONCE = -1
......
package com.sd.cavphmi.utils
import androidx.security.crypto.EncryptedSharedPreferences
import com.sd.cavphmi.MyAppcation
object MyPres {
private const val PREFS_NAME = "adas"
private const val MASTER_KEY_ALIAS = "masterkeyalias"
private val sharedPreferences by lazy {
EncryptedSharedPreferences.create(
PREFS_NAME,
MASTER_KEY_ALIAS,
MyAppcation.instance().applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}
var token: String
set(value) {
with(sharedPreferences.edit()) {
putString("token", value)
commit()
}
}
get() {
return sharedPreferences.getString("token", "") ?: ""
}
var hisSearch: String
set(value) {
with(sharedPreferences.edit()) {
putString("hisSearch", value)
commit()
}
}
get() {
return sharedPreferences.getString("hisSearch", "") ?: ""
}
/**
* 全类型历史搜素
*/
var curLat: String
set(value) {
with(sharedPreferences.edit()) {
putString("curLat", value)
commit()
}
}
get() {
return sharedPreferences.getString("curLat", "") ?: ""
}
/**
* 专题资料历史搜素
*/
var curLng: String
set(value) {
with(sharedPreferences.edit()) {
putString("curLng", value)
commit()
}
}
get() {
return sharedPreferences.getString("curLng", "") ?: ""
}
/**
* 资料历史搜素
*/
var dataSearch: String
set(value) {
with(sharedPreferences.edit()) {
putString("dataSearch", value)
commit()
}
}
get() {
return sharedPreferences.getString("dataSearch", "") ?: ""
}
/**
* 问答历史搜素
*/
var qaSearch: String
set(value) {
with(sharedPreferences.edit()) {
putString("qaSearch", value)
commit()
}
}
get() {
return sharedPreferences.getString("qaSearch", "") ?: ""
}
/**
* 首次授权
*/
var isFrist: Boolean
set(value) {
with(sharedPreferences.edit()) {
putBoolean("isFrist", value)
commit()
}
}
get() {
return sharedPreferences.getBoolean("isFrist", true)
}
/**
* 邀请码
*/
var invCode: String
set(value) {
with(sharedPreferences.edit()) {
putString("invcode", value)
commit()
}
}
get() {
return sharedPreferences.getString("invcode", "") ?: ""
}
/**
* 个人电话
*/
var mobile: String
set(value) {
with(sharedPreferences.edit()) {
putString("mobile", value)
commit()
}
}
get() {
return sharedPreferences.getString("mobile", "") ?: ""
}
/**
* 删除领域
*/
var goodField: String
set(value) {
with(sharedPreferences.edit()) {
putString("goodField", value)
commit()
}
}
get() {
return sharedPreferences.getString("goodField", "") ?: ""
}
var userId: String
set(value) {
with(sharedPreferences.edit()) {
putString("userId", value)
commit()
}
}
get() {
return sharedPreferences.getString("userId", "") ?: ""
}
/**
* 极光推送ID
*/
var registrationId: String
set(value) {
with(sharedPreferences.edit()) {
putString("registrationId", value)
commit()
}
}
get() {
return sharedPreferences.getString("registrationId", "") ?: ""
}
}
\ No newline at end of file
......@@ -8,8 +8,9 @@ import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.bean.CarVehicle
import com.sd.cavphmi.bean.AllLinePlaningBean
import com.sd.cavphmi.bean.CarPanelBean
import com.sd.cavphmi.bean.CarVehicle
import com.sd.cavphmi.bean.OrderBean
import com.sd.cavphmi.bean.ParkBean
import com.sd.cavphmi.bean.ParkLinePlan
......@@ -24,11 +25,12 @@ import com.sd.cavphmi.bean.VehicleStats
import com.sd.cavphmi.bean.WebSetBean
import com.sd.cavphmi.net.MyResult
import com.sd.cavphmi.repositorys.ParseSocketRepo
import com.sd.cavphmi.utils.DateUtils
import com.sd.cavphmi.utils.FileIoUtils
import com.sd.cavphmi.utils.MyContants
import com.sd.cavphmi.utils.ToastHelper
import com.sd.cavphmi.websockets.FeelTargetWSClient
import com.sd.cavphmi.websockets.MyWebSocketClient
import com.sd.cavphmi.websockets.VecLocWSClient
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
......@@ -51,6 +53,12 @@ class MainVm @Inject constructor(
private var client: MyWebSocketClient? = null
//w网联车辆socket
private var vecLocWSClient: VecLocWSClient? = null
//感知物socket
private var feelTargetWSClient: FeelTargetWSClient? = null
private var gson = Gson()
//模拟操作
......@@ -89,26 +97,14 @@ class MainVm @Inject constructor(
// 是否处理路径规划显示的路径
private var needDealPath = false
//驾驶模式
var driveMode = ObservableField("")
//航向角
var heading = ObservableField(550)
//速度
var speed = ObservableField(0f)
//当前时间
var curTime = ObservableField("")
/***车辆仪表***/
var carPanelBean = CarPanelBean.instance
//网络延时时间差
var timeOutDiff = ObservableField(-1)
// 当前时间
private var curTimer = Timer()
// var timeOutDiff = ObservableField(-1)
// 信号强度
private var netSingTimer = Timer()
// private var netSingTimer = Timer()
// 订单详情
private var orderTimer = Timer()
......@@ -117,36 +113,26 @@ class MainVm @Inject constructor(
private var carSpaNoTimer = Timer()
/***获取当前时间**/
fun getCurrentTime() {
curTimer.schedule(object : TimerTask() {
override fun run() {
var time = DateUtils.getCurrentTime12HourFormat()
curTime.set(time)
}
}, 2000, 1000 * 60)
}
/***获取信号强度**/
fun getMobileNetworkSignal() {
netSingTimer.schedule(object : TimerTask() {
override fun run() {
viewModelScope.launch {
var result = parseSocketRepo.getTimeOut()
when (result) {
is MyResult.Success<Int> -> {
timeOutDiff.set(result.data)
// println("-------时间差---- = ${result.data}")
}
else -> {
// println("-------Error---- = ${result.msg}")
}
}
}
}
}, 5000, 1000 * 60)
}
// fun getMobileNetworkSignal() {
// netSingTimer.schedule(object : TimerTask() {
// override fun run() {
// viewModelScope.launch {
// var result = parseSocketRepo.getTimeOut()
// when (result) {
// is MyResult.Success<Int> -> {
// timeOutDiff.set(result.data)
//// println("-------时间差---- = ${result.data}")
// }
//
// else -> {
//// println("-------Error---- = ${result.msg}")
// }
// }
// }
// }
// }, 5000, 1000 * 60)
// }
/***获取订单信息
* @param vehiclePlate 车牌号
......@@ -281,7 +267,7 @@ class MainVm @Inject constructor(
// this.$refs.basisCesium.findPathPlanning(res);
// // 泊车需要高亮车位,召车不高亮
if (ifParking) {
spaceCode = result.data?.spaceCode?:""
spaceCode = result.data?.spaceCode ?: ""
} else {
// spaceCode = ''
}
......@@ -298,26 +284,26 @@ class MainVm @Inject constructor(
/**查询车位信息 判断车位上是否有车**/
fun getSpaceData() {
carSpaNoTimer.schedule(object : TimerTask() {
override fun run() {
viewModelScope.launch {
var result = parseSocketRepo.getSpaceData()
when (result) {
is MyResult.Success<SpaceNoBean> -> {
println("-------------查询车位信息= ${result}")
FileIoUtils.writeToFile(gson.toJson(result.data), "spaceno.txt")
}
is MyResult.Error -> {
println("-------------查询车位信息 Error= ${result}")
// carSpaNoTimer.cancel()
}
}
}
}
}, 4000, 1000 * 20)
}
// fun getSpaceData() {
// carSpaNoTimer.schedule(object : TimerTask() {
// override fun run() {
// viewModelScope.launch {
// var result = parseSocketRepo.getSpaceData()
// when (result) {
// is MyResult.Success<SpaceNoBean> -> {
// println("-------------查询车位信息= ${result}")
// FileIoUtils.writeToFile(gson.toJson(result.data), "spaceno.txt")
// }
//
// is MyResult.Error -> {
// println("-------------查询车位信息 Error= ${result}")
//// carSpaNoTimer.cancel()
// }
// }
// }
// }
// }, 4000, 1000 * 20)
// }
/**获取本地车位**/
fun getSpaceDataLoc() {
......@@ -350,20 +336,20 @@ class MainVm @Inject constructor(
fun startWS() {
// val httpHeaders = mutableMapOf<String, String>()
// httpHeaders.put("Cookie", "username=nemo")
try {
client = MyWebSocketClient(URI(MyContants.WS_HOST))
client?.onSocketCb = onSocketCb
client?.onDataCb = onDataCb
client?.connect()
} catch (e: Exception) {
}
// try {
// client = MyWebSocketClient(URI(MyContants.WS_HOST))
// client?.onSocketCb = onSocketCb
// client?.onDataCb = onDataCb
// client?.connect()
// } catch (e: Exception) {
//
// }
}
/***清理资源***/
fun cleanRes() {
curTimer.cancel()
netSingTimer.cancel()
// curTimer.cancel()
// netSingTimer.cancel()
orderTimer.cancel()
carSpaNoTimer.cancel()
closeWS()
......@@ -391,16 +377,19 @@ class MainVm @Inject constructor(
private var onDataCb = object : MyWebSocketClient.OnDataCb {
override fun onVehicle(res: Response.SocketResponse) {
viewModelScope.launch {
/* viewModelScope.launch {
FileIoUtils.writeToFile(res.data, "CarVehicle.txt")
val bean =
parseSocketRepo.parseDataBean(res.data, CarVehicle::class.java)
println("------车辆位姿数据 = ${res.data}")
if ((bean.vehicleData.count()) > 0) {
heading.set(bean.vehicleData.get(0).heading.toInt())
speed.set(bean.vehicleData.get(0).speed)
}
carPanelBean.heading.set(bean.vehicleData.get(0).heading.toInt())
carPanelBean.speed.set(bean.vehicleData.get(0).speed.toInt())
// heading.set(bean.vehicleData.get(0).heading.toInt())
// speed.set(bean.vehicleData.get(0).speed)
}
}*/
}
override fun onVehicleStats(res: Response.SocketResponse) {
......@@ -416,7 +405,8 @@ class MainVm @Inject constructor(
2 -> "远程驾驶"
else -> "—— ——"
}
driveMode.set(str)
carPanelBean.driveMode.set(str)
// driveMode.set(str)
}
vehicleStat.value = bean
}
......@@ -487,9 +477,24 @@ class MainVm @Inject constructor(
/*** 联网车辆位姿数据**/
fun subVehicle(): LiveData<CarVehicle> {
if (isMock) {
mockVM.onVehicleMock(carVehicle, heading, speed)
// mockVM.onVehicleMock(carVehicle, carPanelBean.heading, carPanelBean.speed)
} else {
client?.send(getSendData("/topic/vehicle"))
try {
if (vecLocWSClient == null) {
vecLocWSClient = VecLocWSClient(URI(MyContants.WS_VEH_LOC))
vecLocWSClient?.connect()
vecLocWSClient?.onDataCb = object : VecLocWSClient.OnDataCb {
override fun onMsg(str: String) {
// FileIoUtils.writeToFile(str, "CarVehicle.txt")
var bean = gson.fromJson(str, CarVehicle::class.java)
carVehicle.postValue(bean)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
return carVehicle
}
......@@ -508,9 +513,24 @@ class MainVm @Inject constructor(
* **/
fun subTarget(): LiveData<PerTarget> {
if (isMock) {
mockVM.onSubTargetMock(targetPre)
// mockVM.onSubTargetMock(targetPre)
} else {
client?.send(getSendData("/topic/dataMerge"))
try {
if (feelTargetWSClient == null) {
feelTargetWSClient = FeelTargetWSClient(URI(MyContants.WS_FEEL_TARGET))
feelTargetWSClient?.connect()
feelTargetWSClient?.onDataCb = object : FeelTargetWSClient.OnDataCb {
override fun onMsg(str: String) {
// FileIoUtils.writeToFile(str, "PerTarget.txt")
var bean = gson.fromJson(str, PerTarget::class.java)
targetPre.postValue(bean)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
return targetPre
}
......
......@@ -41,7 +41,7 @@ class MockVM @Inject constructor(
speed: ObservableField<Float>
) {
viewModelScope.launch {
val dst = mutableListOf<String>()
/* val dst = mutableListOf<String>()
FileIoUtils.getAssetMock(context, "mock/CarVehicle.txt", dst)
dst.forEach { str ->
delay(1000)
......@@ -51,7 +51,7 @@ class MockVM @Inject constructor(
heading.set(bean.vehicleData.get(0).heading.toInt())
speed.set(bean.vehicleData.get(0).speed)
carVehicle.value = bean
}
}*/
}
}
......
package com.sd.cavphmi.websockets
import org.java_websocket.client.WebSocketClient
import org.java_websocket.drafts.Draft
import org.java_websocket.handshake.ServerHandshake
import java.net.URI
import java.nio.ByteBuffer
/*****感知目标物**/
class FeelTargetWSClient : WebSocketClient {
private val TAG = "-----FeelTargetWSClient"
constructor(serverUri: URI) : super(serverUri)
constructor(serverUri: URI?, protocolDraft: Draft?) : super(serverUri, protocolDraft)
constructor(serverUri: URI?, httpHeaders: MutableMap<String, String>?) : super(
serverUri,
httpHeaders
)
override fun onOpen(handshakedata: ServerHandshake?) {
// send("Hello, it is me. Mario :)")
// System.out.println(TAG + "new connection opened")
}
override fun onMessage(message: String?) {
// System.out.println(TAG + "received message: " + message);
if (message.isNullOrEmpty())
return
onDataCb?.onMsg(message)
// onSocketCb?.onMessage(message)
}
override fun onMessage(bytes: ByteBuffer?) {
// System.out.println(TAG + " received ByteBuffer")
}
override fun onClose(code: Int, reason: String?, remote: Boolean) {
// System.out.println(TAG + " closed with exit code " + code + " additional info: " + reason);
}
override fun onError(ex: Exception?) {
// System.err.println(TAG + "an error occurred:" + ex)
}
var onDataCb: OnDataCb? = null
interface OnDataCb {
fun onMsg(str: String)
}
}
\ No newline at end of file
package com.sd.cavphmi.websockets
import com.sd.cavphmi.viewmodels.MainVm
import org.java_websocket.client.WebSocketClient
import org.java_websocket.drafts.Draft
import org.java_websocket.handshake.ServerHandshake
import protocol.Response
import java.net.URI
import java.nio.ByteBuffer
/*****往来你车辆位姿**/
class VecLocWSClient : WebSocketClient {
private val TAG = "-----VecLocWSClient"
constructor(serverUri: URI) : super(serverUri)
constructor(serverUri: URI?, protocolDraft: Draft?) : super(serverUri, protocolDraft)
constructor(serverUri: URI?, httpHeaders: MutableMap<String, String>?) : super(
serverUri,
httpHeaders
)
override fun onOpen(handshakedata: ServerHandshake?) {
// send("Hello, it is me. Mario :)")
// System.out.println(TAG + "new connection opened")
}
override fun onMessage(message: String?) {
System.out.println(TAG + "received message: " + message);
if (message.isNullOrEmpty())
return
onDataCb?.onMsg(message)
// onSocketCb?.onMessage(message)
}
override fun onMessage(bytes: ByteBuffer?) {
// System.out.println(TAG + " received ByteBuffer")
}
override fun onClose(code: Int, reason: String?, remote: Boolean) {
// System.out.println(TAG + " closed with exit code " + code + " additional info: " + reason);
}
override fun onError(ex: Exception?) {
// System.err.println(TAG + "an error occurred:" + ex)
}
var onDataCb: OnDataCb? = null
interface OnDataCb {
fun onMsg(str: String)
}
}
\ No newline at end of file
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