package com.fuban.driver.base
|
|
import android.app.Activity
|
import android.app.Application
|
import android.content.Intent
|
import android.os.*
|
import android.util.Log
|
import androidx.annotation.RequiresApi
|
import cn.jpush.android.api.JPushInterface
|
import cn.jpush.android.api.TagAliasCallback
|
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.fuban.driver.base.gaode.gpsnav.util.TTSController
|
import com.fuban.driver.base.local.OnTripTrackLifecycleListener
|
import com.fuban.driver.base.local.OnTripTrackListener
|
import com.fuban.driver.bean.CarLocationBean
|
import com.fuban.driver.bean.OrderResData
|
import com.fuban.driver.bean.OrderSimpleData
|
import com.fuban.driver.bean.websocket.HeartBean
|
import com.fuban.driver.netUtls.Api
|
import com.fuban.driver.netUtls.getUserId
|
import com.fuban.driver.ui.pub.LoginActivity
|
import com.fuban.driver.ui.to_city.TripCityActivity
|
import com.fuban.driver.utils.Cache.CacheKey
|
import com.fuban.driver.utils.Cache.CacheUtil
|
import com.fuban.driver.utils.LogUtils
|
import com.google.gson.Gson
|
import com.tencent.bugly.crashreport.CrashReport
|
import com.umeng.commonsdk.UMConfigure
|
import com.umeng.socialize.PlatformConfig
|
import com.xuexiang.xui.XUI
|
import org.greenrobot.eventbus.EventBus
|
import org.jetbrains.anko.toast
|
import org.json.JSONObject
|
import java.security.SecureRandom
|
import java.security.cert.X509Certificate
|
import java.util.*
|
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 {
|
//设置debug模式
|
var isDebug = false
|
var heartHandler: Handler? = null
|
var currentTime = System.currentTimeMillis()
|
|
override fun setSharedPreferencesName(): String {
|
return "MyApplication"
|
}
|
|
@RequiresApi(api = Build.VERSION_CODES.DONUT)
|
override fun onCreate() {
|
super.onCreate()
|
appContext = this
|
handleSSLHandshake()
|
//如果是主进程
|
XUI.init(this)
|
registerActivityLifecycleCallbacks(this)
|
// CrashReport.initCrashReport(getApplicationContext(), "444bb776ed", false);
|
LogUtils.OpenLog(true)
|
initUpPoint()
|
initSocket()
|
}
|
|
/**
|
* 延迟初始化,在用户同意隐私协议后进行
|
*/
|
fun initSdk(){
|
UMConfigure.init(
|
this,
|
"640ae80cba6a5259c41ab641",
|
"gaode",
|
UMConfigure.DEVICE_TYPE_PHONE,
|
""
|
)
|
PlatformConfig.setWeixin("wx19a713b4943f9568", "5d4ca951a855b1e2c86a844cd42fd133")
|
PlatformConfig.setQQZone("1112151767", "5viZ7mQkNkYtUr7b") //qq互联
|
JPushInterface.setDebugMode(true)
|
JPushInterface.init(this)
|
setAlisa()
|
}
|
|
public fun setAlisa() {
|
if (CacheKey.getUserId().isNotEmpty()) {
|
var alisa = "DRIVER" + CacheKey.getUserId()
|
sysErr(alisa)
|
mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, alisa))
|
}
|
}
|
|
private val MSG_SET_ALIAS = 1001
|
private val mHandler: Handler = object : Handler() {
|
override fun handleMessage(msg: Message) {
|
super.handleMessage(msg)
|
when (msg.what) {
|
MSG_SET_ALIAS -> {
|
Log.d(TAG, "Set alias in handler.")
|
// 调用 JPush 接口来设置别名。
|
JPushInterface.setAliasAndTags(
|
applicationContext,
|
msg.obj as String,
|
null,
|
mAliasCallback
|
)
|
}
|
else -> Log.i(TAG, "Unhandled msg - " + msg.what)
|
}
|
}
|
}
|
|
private val mAliasCallback =
|
TagAliasCallback { code, alias, tags ->
|
val logs: String
|
when (code) {
|
0 -> {
|
logs = "Set tag and alias success"
|
Log.i("TAG", logs)
|
}
|
6002 -> {
|
logs = "Failed to set alias and tags due to timeout. Try again after 60s."
|
Log.i("TAG", logs)
|
// 延迟 60 秒来调用 Handler 设置别名
|
var alisa = "DRIVER" + CacheKey.getUserId()
|
Handler().postDelayed({
|
JPushInterface.setAliasAndTags(this, alisa, null, null)
|
}, 60 * 1000)
|
}
|
else -> {
|
logs = "Failed with errorCode = $code"
|
Log.e("TAG", logs)
|
}
|
}
|
}
|
|
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消息")
|
if (!isLogin) {
|
return@addOnMessageListener
|
}
|
currentTime = System.currentTimeMillis()
|
val json = JSONObject(message)
|
val method = json.optString("method")
|
Handler(Looper.getMainLooper()).post {
|
// ToastUtils.showShortToast(this, "收到websocket=$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()
|
isLogin = false
|
var intent = Intent()
|
intent.setClass(this, LoginActivity::class.java)
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
startActivity(intent)
|
toast("您的账号已在其他平台登录")
|
}
|
Const.SOCKET_METHOD.ORDER_STATUS -> {
|
val orderSimpleData =
|
Gson().fromJson(
|
data,
|
OrderSimpleData::class.java
|
)
|
for (view in orderStatueViews.asReversed().indices) {
|
orderStatueViews[view].orderInfo(orderSimpleData)
|
}
|
if (orderSimpleData.status == 1) {
|
val act = activities[activities.size - 1]
|
// MyApplication.getTTsManager().setVideoText("收到新的订单")
|
when (orderSimpleData.orderType) {
|
1,2 -> {
|
(act as MyBaseActivity).showOrder(
|
orderSimpleData.orderId.toString(),
|
orderSimpleData.orderType.toString(),
|
orderSimpleData.time,
|
1
|
)
|
}
|
4,5 -> {
|
(act as MyBaseActivity).showOrder(
|
orderSimpleData.orderId.toString(),
|
orderSimpleData.orderType.toString(),
|
orderSimpleData.time,
|
1
|
)
|
}
|
}
|
}
|
if (orderSimpleData.status == 2) {
|
val act = activities[activities.size - 1]
|
when (orderSimpleData.orderType) {
|
1, 2 -> {
|
(act as MyBaseActivity).toDorderAct(
|
orderSimpleData.orderId.toString(),
|
orderSimpleData.orderType.toString()
|
)
|
}
|
3 -> {
|
if (act is TripCityActivity) {
|
act.callOrder()
|
} else {
|
(act as MyBaseActivity).toDorderActCity(
|
orderSimpleData.orderId.toString(),
|
orderSimpleData.orderType.toString()
|
)
|
}
|
|
}
|
|
}
|
|
}
|
|
|
}
|
Const.SOCKET_METHOD.REASSIGN -> {
|
EventBus.getDefault().post(BaseEvent(BaseEvent.REFREASH_MAIN))
|
val orderSimpleData =
|
Gson().fromJson(
|
data,
|
OrderResData::class.java
|
)
|
val act = activities[activities.size - 1]
|
when (orderSimpleData.orderType) {
|
1, 2 -> {
|
(act as MyBaseActivity).showOrder(
|
orderSimpleData.orderId.toString(),
|
orderSimpleData.orderType.toString(),
|
30,
|
2
|
)
|
}
|
3 -> {
|
if (act is TripCityActivity) {
|
act.callOrder()
|
}
|
(act as MyBaseActivity).toDorderActCity(
|
orderSimpleData.orderId.toString(),
|
orderSimpleData.orderType.toString()
|
)
|
}
|
}
|
|
}
|
}
|
} else {
|
sysErr("socket return code ===$code")
|
}
|
} catch (e: Exception) {
|
e.printStackTrace()
|
}
|
}
|
NettyClient.getInstance()
|
.setOnConnectListener {
|
sendHeart()
|
}
|
}
|
|
|
fun initUpPoint() {
|
//猎鹰sdk上报
|
var serviceIdS = CacheKey.getServerId()
|
if (serviceIdS == "")
|
return
|
var serviceId = serviceIdS.toLong()
|
var terminalName = CacheKey.getTerminalName() // 唯一标识某个用户或某台设备的名称
|
aMapTrackClient = AMapTrackClient(applicationContext);
|
aMapTrackClient.setInterval(5, 30)
|
aMapTrackClient.queryTerminal(QueryTerminalRequest(serviceId, terminalName),
|
object : OnTripTrackListener() {
|
override fun onQueryTerminalCallback(p0: QueryTerminalResponse?) {
|
if (p0!!.isSuccess) {
|
if (p0.tid <= 0) {
|
aMapTrackClient.addTerminal(
|
AddTerminalRequest(terminalName, serviceId),
|
object :
|
OnTripTrackListener() {
|
override fun onQueryTerminalCallback(queryTerminalResponse: QueryTerminalResponse?) {
|
super.onQueryTerminalCallback(queryTerminalResponse)
|
if (p0.isSuccess) {
|
// 创建完成,开启猎鹰服务
|
sysErr("创建完成,开启猎鹰服务" + p0.errorMsg)
|
var terminalId = queryTerminalResponse!!.tid;
|
aMapTrackClient.startTrack(
|
TrackParam(
|
serviceId,
|
terminalId
|
), onTrackLifecycleListener
|
);
|
} else {
|
// 请求失败
|
sysErr("请求失败" + p0.getErrorMsg())
|
}
|
}
|
});
|
} else {
|
// terminal已经存在,直接开启猎鹰服务
|
var terminalId = p0.tid
|
sysErr("创建完成,开启猎鹰服务" + p0.errorMsg)
|
aMapTrackClient.startTrack(
|
TrackParam(serviceId, terminalId),
|
onTrackLifecycleListener
|
)
|
}
|
} else {
|
sysErr("请求失败" + p0.errorMsg)
|
}
|
}
|
})
|
}
|
|
lateinit var aMapTrackClient: AMapTrackClient
|
var onTrackLifecycleListener = object : OnTripTrackLifecycleListener() {
|
override fun onStartGatherCallback(p0: Int, p1: String?) {
|
if (p0 == ErrorCode.TrackListen.START_GATHER_SUCEE ||
|
p0 == ErrorCode.TrackListen.START_GATHER_ALREADY_STARTED
|
) {
|
sysErr("定位采集开启成功")
|
} 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 {
|
sysErr("轨迹上报服务服务启动异常")
|
}
|
}
|
}
|
|
private fun sendLocation() {
|
if (getUserId() != -1 && aMapLocation != null) {
|
val bean = CarLocationBean()
|
val dataBean = CarLocationBean.DataBean(
|
getUserId(),
|
currentOrderId,
|
currentOrderType,
|
aMapLocation!!.longitude,
|
aMapLocation!!.latitude,
|
aMapLocation!!.bearing.toDouble(),
|
aMapLocation!!.altitude
|
)
|
bean.data = dataBean
|
NettyClient.getInstance()
|
.sendMessage(Gson().toJson(bean))
|
sysErr(dataBean.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()
|
if (heartHandler == null) {
|
heartHandler = Handler(mainLooper)
|
}
|
heartHandler!!.removeCallbacksAndMessages(null)
|
testHeartNunm++
|
if ((System.currentTimeMillis() - currentTime) / 1000 > 30) {
|
sysErr("sendHeart_websocket 重新连接")
|
currentTime = System.currentTimeMillis()
|
NettyClient.getInstance().checkNettyState()
|
} else {
|
sysErr("sendHeart_websocket 发送心跳")
|
}
|
}
|
heartHandler!!.postDelayed({ sendHeart() }, 5000)
|
}
|
|
interface OrderStatueView {
|
fun orderInfo(data: OrderSimpleData?)
|
}
|
|
|
companion object {
|
private const val TAG = "MyApplication"
|
var canPlayVoice = false //进入主页才可以播放语言通知
|
protected var mTtsManager: TTSController? = null
|
public var isLogin: Boolean = true
|
|
public var appContext: MyApplication? = 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!!
|
}
|
|
fun getLocation(): AMapLocation {
|
if (aMapLocation == null) {
|
var map = AMapLocation("")
|
map.latitude = -1.0
|
map.longitude = -1.0
|
return map
|
} else {
|
return aMapLocation!!
|
}
|
}
|
|
var aMapLocation: AMapLocation? = null
|
var currentOrderId: String = ""
|
var currentOrderType: String = ""
|
var orderStatueViews: MutableList<OrderStatueView> =
|
mutableListOf()
|
var testHeartNunm = 0
|
var testReceiveNum = 0
|
fun handleSSLHandshake() {
|
try {
|
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
|
override fun getAcceptedIssuers(): Array<X509Certificate?> {
|
return arrayOfNulls(0)
|
}
|
|
override fun checkClientTrusted(
|
certs: Array<X509Certificate>,
|
authType: String
|
) {
|
}
|
|
override fun checkServerTrusted(
|
certs: Array<X509Certificate>,
|
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) {
|
}
|
}
|
|
fun addOrderView(view: OrderStatueView) {
|
if (!orderStatueViews.contains(view)) {
|
orderStatueViews.add(view)
|
}
|
}
|
|
fun removeOrderView(view: OrderStatueView?) {
|
orderStatueViews.remove(view)
|
}
|
}
|
|
private val activities = ArrayList<Activity?>()
|
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) {
|
if (canPlayVoice)
|
getTTsManager().setVideoText("福伴司机已置于后台,可能会导致听单异常,里程计费差异,请勿切换。")
|
}
|
}, 600)
|
|
}
|
|
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
|
activities.add(activity)
|
}
|
|
|
}
|