package com.liuzhou.callcar.driver.pad.base import android.app.Activity import android.app.Application import android.content.Context import android.content.IntentFilter import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import androidx.multidex.MultiDex import cn.sinata.rxnetty.NettyClient import cn.sinata.xldutils.BaseApplication import cn.sinata.xldutils.utils.sysErr import com.amap.api.location.AMapLocation import com.amap.api.track.AMapTrackClient import com.amap.api.track.ErrorCode import com.amap.api.track.TrackParam import com.amap.api.track.query.model.AddTerminalRequest import com.amap.api.track.query.model.QueryTerminalRequest import com.amap.api.track.query.model.QueryTerminalResponse import com.google.gson.Gson import com.liuzhou.callcar.driver.pad.base.gpsnav.util.TTSController import com.liuzhou.callcar.driver.pad.bean.CarLocationBean import com.liuzhou.callcar.driver.pad.bean.OrderResData import com.liuzhou.callcar.driver.pad.bean.OrderSimpleData import com.liuzhou.callcar.driver.pad.bean.websocket.HeartBean import com.liuzhou.callcar.driver.pad.netUtls.Api import com.liuzhou.callcar.driver.pad.netUtls.getUserId import com.liuzhou.callcar.driver.pad.slab.MySlabBaseActivity import com.liuzhou.callcar.driver.pad.utils.Cache.CacheKey import com.liuzhou.callcar.driver.pad.utils.LogUtils import com.tencent.bugly.crashreport.CrashReport import org.json.JSONObject import java.security.SecureRandom import java.security.cert.X509Certificate import javax.net.ssl.HttpsURLConnection import javax.net.ssl.SSLContext import javax.net.ssl.TrustManager import javax.net.ssl.X509TrustManager /** * Created by Administrator on 2018/1/17. */ class MyApplication : BaseApplication(), Application.ActivityLifecycleCallbacks { var heartHandler: Handler = Handler(Looper.getMainLooper()) var currentTime = System.currentTimeMillis() var aMapTrackClient: AMapTrackClient? = null var trackParam: TrackParam? = null val bean = CarLocationBean().apply { data = CarLocationBean.DataBean( 0, "", "", 0.0, 0.0, 0.0, 0.0 ) } override fun setSharedPreferencesName(): String { return "MyApplication" } override fun onCreate() { super.onCreate() appContext = this handleSSLHandshake() //如果是主进程 // XUI.init(this) // UMConfigure.init( // this, // "5ee48ce8978eea081640df6a", // "gaode", // UMConfigure.DEVICE_TYPE_PHONE, // "" // ) registerActivityLifecycleCallbacks(this) // PlatformConfig.setWeixin("wx65d2c03f04352f90", "7a3a57f9ba78c1f400b75298eec4c7c0") // PlatformConfig.setQQZone("101877032", "eab94b262bf9789eec770cde42a6e71e") //qq互联 LogUtils.OpenLog(true) CrashReport.initCrashReport(applicationContext, "666d35fada", false) initSocket() registerBusinessBroadcastReceiver() } private fun initSocket() { NettyClient.getInstance().init(this, Api.SOCKET_SERVER, Api.SOCKET_PORT, true) NettyClient.getInstance() .addOnMessageListener { message: String? -> try { Log.e("socket_message_by", message) // sysErr("收到websocket消息") currentTime = System.currentTimeMillis() val json = JSONObject(message) val method = json.optString("method") if (method != "OK" && method != "PONG") upLog("收到服务端推送,method:${method}") val data = json.optString("data") val code = json.optInt("code", -1) if (code == 200) { when (method) { Const.SOCKET_METHOD.OK -> { testReceiveNum++ } Const.SOCKET_METHOD.OFFLINE -> { // CacheUtil.get().clear() // NettyClient.getInstance().stopService() // var intent = Intent() // intent.setClass(this, SlabLoginActivity::class.java) // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // startActivity(intent) // Handler(Looper.getMainLooper()).post { // toast("您的账号已在其他平台登录") // } } Const.SOCKET_METHOD.ORDER_STATUS -> { val orderSimpleData = Gson().fromJson(data, OrderSimpleData::class.java) for (view in orderStatueViews) { view.orderInfo(orderSimpleData) } if (orderSimpleData.status == 1) { if (orderSimpleData.orderId.toString() == currentReceiveOrderId && orderSimpleData.orderType.toString() == currentReceiveOrderType) { upLog("had ReceiveOrderId:${orderSimpleData.orderId} ReceiveOrderType:${orderSimpleData.orderType}") return@addOnMessageListener } currentReceiveOrderId = orderSimpleData.orderId.toString() currentReceiveOrderType = orderSimpleData.orderType.toString() val act = activities[activities.size - 1] (act as MySlabBaseActivity).showOrder( orderSimpleData.orderId.toString(), orderSimpleData.orderType.toString(), orderSimpleData.time, 1 ) } if (orderSimpleData.status == 2) { val act = activities[activities.size - 1] (act as MySlabBaseActivity).toDorderAct( orderSimpleData.orderId.toString(), orderSimpleData.orderType.toString() ) } } Const.SOCKET_METHOD.REASSIGN -> { val orderSimpleData = Gson().fromJson( data, OrderResData::class.java ) val act = activities[activities.size - 1] (act as MySlabBaseActivity).showOrder( orderSimpleData.orderId.toString(), orderSimpleData.orderType.toString(), 30, 2 ) } } } else { sysErr("socket return code ===$code") } } catch (e: Exception) { e.printStackTrace() } } NettyClient.getInstance() .setOnConnectListener { sendHeart() } sendHeart() } override fun attachBaseContext(base: Context?) { super.attachBaseContext(base) MultiDex.install(this); } //猎鹰sdk上报 fun initUpPoint() { val serviceIdS = CacheKey.getServerId() if (serviceIdS.isEmpty()) { stopUpPoint() return } if (aMapTrackClient == null) { aMapTrackClient = AMapTrackClient(applicationContext).apply { setInterval(5, 30) } } if (trackParam == null) { val serviceId = serviceIdS.toLong() val terminalName = CacheKey.getTerminalName() // 唯一标识某个用户或某台设备的名称 aMapTrackClient?.queryTerminal(QueryTerminalRequest(serviceId, terminalName), object : OnTripTrackListener() { override fun onQueryTerminalCallback(p0: QueryTerminalResponse?) { if (p0?.isSuccess == true) { if (p0.tid <= 0) { aMapTrackClient?.addTerminal( AddTerminalRequest(terminalName, serviceId), object : OnTripTrackListener() { override fun onQueryTerminalCallback(queryTerminalResponse: QueryTerminalResponse?) { super.onQueryTerminalCallback(queryTerminalResponse) if (queryTerminalResponse?.isSuccess == true) { // 创建完成,开启猎鹰服务 val terminalId = queryTerminalResponse.tid startTrack(serviceId, terminalId) } else { // 请求失败 sysErr("请求失败${queryTerminalResponse?.errorMsg}") } } }) } else { // terminal已经存在,直接开启猎鹰服务 val terminalId = p0.tid startTrack(serviceId, terminalId) } } else { sysErr("请求失败${p0?.errorMsg}") } } }) } } //开始猎鹰服务 private fun startTrack(serviceId: Long, terminalId: Long) { aMapTrackClient?.startTrack( TrackParam(serviceId, terminalId), object : OnTripTrackLifecycleListener() { override fun onStartGatherCallback(p0: Int, p1: String?) { if (p0 == ErrorCode.TrackListen.START_GATHER_SUCEE || p0 == ErrorCode.TrackListen.START_GATHER_ALREADY_STARTED ) { sysErr("定位采集开启成功") trackParam = TrackParam(serviceId, terminalId) } else { sysErr("定位采集启动异常=$p1") } } override fun onStartTrackCallback(p0: Int, p1: String?) { if (p0 == ErrorCode.TrackListen.START_TRACK_SUCEE || p0 == ErrorCode.TrackListen.START_TRACK_SUCEE_NO_NETWORK || p0 == ErrorCode.TrackListen.START_TRACK_ALREADY_STARTED ) { aMapTrackClient?.startGather(this) } else { trackParam = null sysErr("轨迹上报服务服务启动异常$p1") } } }) sysErr("创建完成,开启猎鹰服务") } //停止猎鹰服务 fun stopUpPoint() { aMapTrackClient?.stopGather(object : OnTripTrackLifecycleListener() {}) trackParam?.also { aMapTrackClient?.stopTrack(it, object : OnTripTrackLifecycleListener() {}) } trackParam = null aMapTrackClient = null } private fun sendLocation() { if (getUserId() != -1 && aMapLocation != null) { bean.data.apply { driverId = getUserId() orderId = currentOrderId orderType = currentOrderType lon = aMapLocation!!.longitude lat = aMapLocation!!.latitude computeAzimuth = aMapLocation!!.bearing.toDouble() altitude = aMapLocation!!.altitude } NettyClient.getInstance() .sendMessage(Gson().toJson(bean)) Handler(Looper.getMainLooper()).post { // toast("发送location --> $dataBean") } sysErr(bean.data.toString()) } } private fun sendHeart() { if (getUserId() != -1) { Log.i(TAG, "sendHeart: userId === " + getUserId()) val bean = HeartBean() bean.data = HeartBean.DataBean() NettyClient.getInstance() .sendMessage(Gson().toJson(bean)) sendLocation() heartHandler.removeCallbacksAndMessages(null) testHeartNunm++ if ((System.currentTimeMillis() - currentTime) / 1000 > 30) { sysErr("sendHeart_websocket 重新连接") currentTime = System.currentTimeMillis() // var s = CacheUtil.get().getAsString("reConnect") // s = "$s###初始化重连" // CacheUtil.get().put("reConnect", s) // NettyClient.getInstance().checkNettyState() NettyClient.getInstance().checkNettyStateNull() //reconnect // initSocket() heartHandler.postDelayed({ sendHeart() }, 5000) } else { sysErr("sendHeart_websocket 发送心跳") heartHandler.postDelayed({ sendHeart() }, 5000) } } } interface OrderStatueView { fun orderInfo(data: OrderSimpleData?) } companion object { private const val TAG = "MyApplication" public var appContext: MyApplication? = null private var mTtsManager: TTSController? = null fun getInstance(): MyApplication? { if (appContext == null) { appContext = MyApplication() } return appContext } fun getTTsManager(): TTSController { if (mTtsManager == null) { mTtsManager = TTSController.getInstance(getInstance()) mTtsManager?.init() } return mTtsManager!! } var aMapLocation: AMapLocation? = null get() { return if (field == null) { val locationStr = CacheKey.getKeyStr("location") if (locationStr.isNotEmpty()) { Gson().fromJson(locationStr, AMapLocation::class.java) } else { field } } else { field } } set(value) { // value?.apply { // latitude = 30.59 // longitude = 104.06 // } field = value CacheKey.putKeyStr("location", if (value == null) "" else Gson().toJson(value)) } var currentOrderId: String = "" var currentOrderType: String = "" var currentReceiveOrderId: String = "" var currentReceiveOrderType: String = "" var orderStatueViews: MutableList = ArrayList() var testHeartNunm = 0 var testReceiveNum = 0 fun handleSSLHandshake() { try { val trustAllCerts = arrayOf(object : X509TrustManager { override fun getAcceptedIssuers(): Array { return arrayOfNulls(0) } override fun checkClientTrusted( certs: Array, authType: String ) { } override fun checkServerTrusted( certs: Array, authType: String ) { } }) val sc = SSLContext.getInstance("TLS") // trustAllCerts信任所有的证书 sc.init(null, trustAllCerts, SecureRandom()) HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory) HttpsURLConnection.setDefaultHostnameVerifier { hostname, session -> true } } catch (ignored: Exception) { ignored.printStackTrace() } } fun addOrderView(view: OrderStatueView) { if (!orderStatueViews.contains(view)) { orderStatueViews.add(view) } } fun removeOrderView(view: OrderStatueView?) { orderStatueViews.remove(view) } fun upLog(msg: String) { // val map = getMapByAny() // map["content"] = "${TimeUtils.getCurrentTime()}:=====》$msg" // if (appContext!=null) // callNet(appContext!!,Api.saveVehicleTerminalLog,map,{}){ // toast("丢失一条日志") // } } } private val activities = ArrayList() private var showNum = 0 override fun onActivityPaused(activity: Activity?) { } override fun onActivityResumed(activity: Activity?) { } override fun onActivityStarted(activity: Activity?) { showNum++ } override fun onActivityDestroyed(activity: Activity?) { activities.remove(activity) } override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) { } override fun onActivityStopped(activity: Activity?) { showNum-- Handler(Looper.getMainLooper()).postDelayed({ if (showNum == 0) { getTTsManager().setVideoText("柳州便民叫车司机已置于后台,可能会导致听单异常,里程计费差异,请勿切换。") } }, 600) } override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) { activities.add(activity) } //注册业务广播 private fun registerBusinessBroadcastReceiver() { registerReceiver(MainBroadCastReceiver(), IntentFilter().apply { addAction("wisdom.intent.action.driverInfo")//司机信息 addAction("wisdom.intent.action.topLight")//顶灯 }) registerReceiver(MoneyBroadCastReceiver(), IntentFilter().apply { addAction("wisdom.intent.action.ledLight")//空重车状态 addAction("wisdom.intent.action.priceDevice")//计价器 addAction("android.net.conn.CONNECTIVITY_CHANGE") addAction("android.net.conn.CONNECTIVITY_SUCCESS") addAction("android.net.conn.CONNECTIVITY_FAILURE") }) } }