package com.igo.user.ui.trip
|
|
import android.Manifest
|
import android.content.Intent
|
import android.content.pm.PackageManager
|
import android.graphics.Bitmap
|
import android.graphics.Color
|
import android.os.Bundle
|
import android.os.Handler
|
import android.os.Message
|
import android.util.Log
|
import android.view.View
|
import android.widget.ImageView
|
import android.widget.TextView
|
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.core.app.ActivityCompat
|
import androidx.core.os.bundleOf
|
import androidx.core.view.isVisible
|
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.RecyclerView
|
import cn.sinata.rxnetty.LogHelper.logRecord
|
import cn.sinata.rxnetty.NettyClient
|
import cn.sinata.xldutils.activity.BaseActivity
|
import cn.sinata.xldutils.callPhone
|
import cn.sinata.xldutils.gone
|
import cn.sinata.xldutils.utils.LanguageUtil
|
import cn.sinata.xldutils.utils.SpanBuilder
|
import cn.sinata.xldutils.utils.myToast
|
import cn.sinata.xldutils.utils.parserTime
|
import cn.sinata.xldutils.view.TitleBar
|
import cn.sinata.xldutils.visible
|
import com.facebook.drawee.view.SimpleDraweeView
|
import com.github.zackratos.ultimatebar.UltimateBar
|
import com.google.android.gms.maps.CameraUpdateFactory
|
import com.google.android.gms.maps.GoogleMap
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
import com.google.android.gms.maps.model.LatLng
|
import com.google.android.gms.maps.model.Marker
|
import com.google.android.gms.maps.model.MarkerOptions
|
import com.google.android.gms.maps.model.Polyline
|
import com.google.android.gms.maps.model.PolylineOptions
|
import com.google.android.libraries.mapsplatform.transportation.consumer.ConsumerApi
|
import com.google.android.libraries.mapsplatform.transportation.consumer.managers.TripModelCallback
|
import com.google.android.libraries.mapsplatform.transportation.consumer.model.MarkerType
|
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TripInfo
|
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TripInfo.TripStatus
|
import com.google.android.libraries.mapsplatform.transportation.consumer.model.TripModelOptions
|
import com.google.android.libraries.mapsplatform.transportation.consumer.model.VehicleLocation
|
import com.google.android.libraries.mapsplatform.transportation.consumer.sessions.JourneySharingSession
|
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerController
|
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerGoogleMap
|
import com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapFragment
|
import com.google.gson.Gson
|
import com.google.gson.reflect.TypeToken
|
import com.igo.user.IGoApplication
|
import com.igo.user.R
|
import com.igo.user.dialog.TipDialog
|
import com.igo.user.interfaces.OrderStateChangeListener
|
import com.igo.user.network.HttpManager
|
import com.igo.user.network.entity.Order
|
import com.igo.user.network.entity.Point
|
import com.igo.user.network.entity.TrippingInfo
|
import com.igo.user.network.request
|
import com.igo.user.ui.mine.TripOrderFragment
|
import com.igo.user.ui.trip.adapter.ProgressAdapter
|
import com.igo.user.utils.Const
|
import com.igo.user.utils.Const.OrderType.TYPE_SPECIAL
|
import com.igo.user.utils.google.AMapKit
|
import com.igo.user.utils.google.JsonAuthTokenFactory
|
import com.tbruyelle.rxpermissions2.RxPermissions
|
import kotlinx.coroutines.launch
|
import org.jetbrains.anko.dip
|
import org.jetbrains.anko.find
|
import org.jetbrains.anko.imageResource
|
import org.jetbrains.anko.sdk27.coroutines.onClick
|
import org.jetbrains.anko.startActivity
|
import org.jetbrains.anko.startActivityForResult
|
|
class TripActivity : BaseActivity(), Handler.Callback,
|
OrderStateChangeListener {
|
var aMap: ConsumerGoogleMap? = null
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
super.onCreate(savedInstanceState)
|
setContentView(R.layout.activity_trip)
|
initView()
|
initClick()
|
}
|
|
private val app by lazy {
|
application as IGoApplication
|
}
|
private val handler by lazy {
|
Handler(this)
|
}
|
private val gson by lazy { Gson() }
|
|
//已行驶的路径,灰色
|
private var newDrivedRouteOverlay: Polyline? = null
|
private var oldDrivedRouteOverlay: Polyline? = null
|
|
private var consumerController: ConsumerController? = null
|
private var vehicleLocation: VehicleLocation? = null //车辆位置
|
|
private val noResponseDialog by lazy { //无应答弹窗,不重复覆盖弹窗
|
val tipDialog = TipDialog()
|
tipDialog.arguments =
|
bundleOf(
|
"msg" to getString(R.string.附近暂无司机接单),
|
"ok" to getString(R.string.继续等待),
|
"cancel" to getString(R.string.取消订单)
|
)
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
}
|
|
override fun onCancel() {
|
cancelOrder()
|
}
|
})
|
tipDialog.setDismissCallback(object : TipDialog.OnDismiss {
|
override fun onDismiss() {
|
HttpManager.pushOrderTaxi(id, type).request(this@TripActivity) { _, _ ->
|
}
|
}
|
})
|
tipDialog
|
}
|
private var id = 0
|
private var type: Int = 0
|
private var order: Order? = null
|
|
var phoneEmergency = "" //报警电话
|
var phoneService = "" //客服电话
|
|
|
private val iv_shuaxing by lazy { find<View>(R.id.iv_shuaxing) }
|
private val titleBar by lazy { find<TitleBar>(R.id.titleBar) }
|
private val tv_action by lazy { find<View>(R.id.tv_action) }
|
private val tv_complain by lazy { find<View>(R.id.tv_complain) }
|
private val iv_call by lazy { find<View>(R.id.iv_call) }
|
private val tv_110 by lazy { find<View>(R.id.tv_110) }
|
private val tv_service by lazy { find<View>(R.id.tv_service) }
|
private val iv_location by lazy { find<View>(R.id.iv_location) }
|
private val tv_cancel by lazy { find<View>(R.id.tv_cancel) }
|
private val tv_change_destination by lazy { find<View>(R.id.tv_change_destination) }
|
private val fl_one_click by lazy { find<View>(R.id.fl_one_click) }
|
private val iv_header_home by lazy { find<SimpleDraweeView>(R.id.iv_header_home) }
|
private val tv_end by lazy { find<TextView>(R.id.tv_end) }
|
private val tv_start by lazy { find<TextView>(R.id.tv_start) }
|
private val tv_time by lazy { find<TextView>(R.id.tv_time) }
|
private val tv_passenger_num by lazy { find<TextView>(R.id.tv_passenger_num) }
|
private val tv_remark by lazy { find<TextView>(R.id.tv_remark) }
|
private val ll_receiver_goods_code by lazy { find<View>(R.id.ll_receiver_goods_code) }
|
private val tv_receiver_goods_code by lazy { find<TextView>(R.id.tv_receiver_goods_code) }
|
private val tv_state by lazy { find<TextView>(R.id.tv_state) }
|
private val cl_driver by lazy { find<View>(R.id.cl_driver) }
|
private val tv_name by lazy { find<TextView>(R.id.tv_name) }
|
private val tv_car by lazy { find<TextView>(R.id.tv_car) }
|
private val tv_car_info by lazy { find<AppCompatTextView>(R.id.tv_car_info) }
|
private val tv_score by lazy { find<TextView>(R.id.tv_score) }
|
private val fl_reserve by lazy { find<View>(R.id.fl_reserve) }
|
private val tv_count by lazy { find<TextView>(R.id.tv_count) }
|
private val tv_progress by lazy { find<TextView>(R.id.tv_progress) }
|
private val line by lazy { find<View>(R.id.line) }
|
private val ll_progress by lazy { find<View>(R.id.ll_progress) }
|
private val rv_progress by lazy { find<RecyclerView>(R.id.rv_progress) }
|
private val view_bg by lazy { find<View>(R.id.view_bg) }
|
|
|
private var consumerApi: ConsumerApi? = null //谷歌消费者sdk
|
private var session: JourneySharingSession? = null
|
|
private val progressList = arrayListOf<String>()
|
private val progressAdapter = ProgressAdapter(progressList)
|
|
|
fun initClick() {
|
iv_shuaxing.onClick {
|
Log.e("订单信息: ", id.toString())
|
Log.e("订单信息: ", type.toString())
|
HttpManager.getOrderDrivingData(id, type)
|
.request(this@TripActivity, false, { _, _ ->
|
}) { _, msg ->
|
|
val data = gson.fromJson(msg, TrippingInfo::class.java)
|
Log.e("订单信息: ", data.toString())
|
setTrippingUI(data)
|
}
|
|
}
|
tv_complain.onClick {
|
startActivity<ComplainActivity>("id" to order!!.driverId)
|
}
|
|
tv_action.setOnClickListener {
|
if (order?.state == 1) {
|
val tipDialog = TipDialog()
|
tipDialog.arguments = bundleOf(
|
"msg" to getString(R.string.取消订单吗), "ok" to getString(
|
R.string.确定取消
|
), "cancel" to getString(R.string.不取消)
|
)
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
showDialog()
|
cancelOrder()
|
}
|
|
override fun onCancel() {
|
}
|
})
|
tipDialog.show(supportFragmentManager, "cancel")
|
}
|
}
|
|
iv_call.setOnClickListener {
|
callPhone(order?.driverPhone)
|
}
|
|
tv_110.setOnClickListener {
|
callPhone(phoneEmergency)
|
}
|
tv_service.setOnClickListener {
|
callPhone(phoneService)
|
}
|
iv_header_home.setOnClickListener {
|
startActivity<DriverDetailActivity>("id" to order!!.driverId)
|
}
|
|
iv_location.setOnClickListener {
|
if (order?.state == 5 && vehicleLocation != null) {
|
aMap?.animateCamera(
|
CameraUpdateFactory.newLatLngZoom(
|
LatLng(
|
vehicleLocation!!.latLng.latitude,
|
vehicleLocation!!.latLng.longitude
|
), 18f
|
)
|
)
|
} else
|
aMap?.animateCamera(
|
CameraUpdateFactory.newLatLngZoom(IGoApplication.getCurrentLocation(), 18f)
|
)
|
handler.removeMessages(4)
|
consumerController?.isAutoCameraEnabled = false
|
}
|
tv_change_destination.setOnClickListener {
|
startActivityForResult<ChoosePositionActivity>(2, "isModify" to true)
|
}
|
|
tv_cancel.setOnClickListener {
|
val tipDialog = TipDialog()
|
tipDialog.arguments = bundleOf(
|
"msg" to getString(R.string.未达取消),
|
"ok" to getString(R.string.确认), "cancel" to getString(R.string.拒绝)
|
)
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
startActivityForResult<CancelOrderActivity>(
|
1, "id" to id, "type" to type, "timeOut" to order?.timeOutCancel,
|
"driverTimeOut" to order?.driverTimeOut, "state" to order?.state
|
)
|
}
|
|
override fun onCancel() {
|
}
|
})
|
tipDialog.show(supportFragmentManager, "cancel")
|
}
|
|
tv_progress.setOnClickListener {
|
showDialog()
|
HttpManager.queryTimeInfo(id).request(this) { _, data ->
|
data?.apply {
|
progressList.clear()
|
progressList.add(getString(R.string.接单时间) + snatchOrderTime)
|
progressList.add(getString(R.string.取件时间) + startServiceTime)
|
progressList.add(getString(R.string.目前用时) + usedTime)
|
progressList.add(getString(R.string.剩余时间) + remainingTime)
|
progressList.add(getString(R.string.送达时间) + endServiceTime)
|
progressList.add(getString(R.string.整体里程公里).format(allMileage))
|
progressList.add(getString(R.string.当前里程公里).format(mileage))
|
ll_progress.visible()
|
}
|
}
|
}
|
view_bg.setOnClickListener {
|
ll_progress.gone()
|
}
|
}
|
|
private fun cancelOrder() {
|
var lat: Double
|
var lon: Double
|
if (vehicleLocation == null) {
|
val currentLocation = IGoApplication.getCurrentLocation()
|
lat = currentLocation.latitude
|
lon = currentLocation.longitude
|
} else {
|
lat = vehicleLocation!!.latLng.latitude
|
lon = vehicleLocation!!.latLng.longitude
|
}
|
HttpManager.cancelOrder(lat, lon, id, type).request(this) { _, _ ->
|
myToast(getString(R.string.取消成功))
|
logRecord("取消订单成功orderId:${id} type:${type}")
|
setResult(RESULT_OK)
|
finish()
|
}
|
}
|
|
fun initView() {
|
UltimateBar.with(this)
|
.statusDark(true)
|
.create().immersionBar() //沉浸状态栏
|
id = intent.getIntExtra("id", 0)
|
type = intent.getIntExtra("type", Const.OrderType.TYPE_TAXI)
|
titleBar.addRightButton(
|
getString(R.string.取消订单),
|
onClickListener = View.OnClickListener {
|
if (titleBar.getRightButton(0)?.text == getString(R.string.取消订单))
|
startActivityForResult<CancelOrderActivity>(
|
1, "id" to id, "type" to type, "timeOut" to order?.timeOutCancel,
|
"driverTimeOut" to order?.driverTimeOut, "state" to order?.state
|
)
|
else if (titleBar.getRightButton(0)?.text == getString(R.string.投诉司机))
|
tv_complain.callOnClick()
|
else
|
startActivityForResult<ChoosePositionActivity>(2, "isModify" to true)
|
})
|
titleBar.getRightButton(0)?.gone()
|
initConsumerSdk()
|
enableMyLocation()
|
app.addTripStateListener(this)
|
getPhone()
|
rv_progress.layoutManager = LinearLayoutManager(this)
|
rv_progress.adapter = progressAdapter
|
}
|
|
private fun initConsumerSdk() {
|
//谷歌乘客端api初始化
|
val consumerApiTask =
|
ConsumerApi.initialize(this, Const.google_provider_id, JsonAuthTokenFactory())
|
consumerApiTask?.addOnSuccessListener { consumerApi: ConsumerApi ->
|
Log.e(Const.GoogleTag, "ConsumerApi初始化成功")
|
this.consumerApi = consumerApi
|
}
|
}
|
|
private fun initMap() {
|
val fragment = supportFragmentManager.findFragmentById(R.id.mMapView) as ConsumerMapFragment
|
fragment.getConsumerGoogleMapAsync(object : ConsumerGoogleMap.ConsumerMapReadyCallback() {
|
override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
|
if (ActivityCompat.checkSelfPermission(
|
this@TripActivity,
|
Manifest.permission.ACCESS_FINE_LOCATION
|
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
|
this@TripActivity,
|
Manifest.permission.ACCESS_COARSE_LOCATION
|
) != PackageManager.PERMISSION_GRANTED
|
) {
|
return
|
}
|
consumerController = consumerGoogleMap.consumerController!!
|
val markerOptions = MarkerOptions()
|
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_car))
|
consumerController?.consumerMapStyle?.setMarkerStyleOptions(
|
MarkerType.TRIP_VEHICLE,
|
markerOptions
|
)
|
// consumerController?.isAutoCameraEnabled = false
|
aMap = consumerGoogleMap.apply {
|
isMyLocationEnabled = true
|
setPadding(0, dip(120), 0, dip(70))
|
uiSettings.isMyLocationButtonEnabled = false
|
moveCamera(CameraUpdateFactory.newLatLng(IGoApplication.getCurrentLocation()))
|
setOnCameraMoveStartedListener {
|
if (it == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE) {
|
handler.removeMessages(4)
|
consumerController?.isAutoCameraEnabled = false
|
}
|
}
|
//地图相机(视角)停止移动并变为空闲状态时触发回调
|
setOnCameraIdleListener {
|
handler.sendEmptyMessageDelayed(4, 10000)
|
}
|
}
|
getData()
|
}
|
})
|
}
|
|
/**
|
* Enables the My Location layer if the fine location permission has been granted.
|
*/
|
private fun enableMyLocation() {
|
// 1. Check if permissions are granted, if so, enable the my location layer
|
val subscribe = RxPermissions(this).request(
|
Manifest.permission.ACCESS_FINE_LOCATION,
|
Manifest.permission.ACCESS_COARSE_LOCATION
|
).subscribe {
|
if (it)
|
initMap()
|
else {
|
myToast(getString(R.string.没有权限))
|
}
|
}
|
}
|
|
|
private fun getPhone() {
|
val currentLocation = IGoApplication.getCurrentLocation()
|
HttpManager.getPhone(currentLocation.latitude, currentLocation.longitude)
|
.request(this, false) { _, data ->
|
data?.forEach {
|
if (it.type == 1)
|
phoneEmergency = it.phone
|
else if (it.type == 2)
|
phoneService = it.phone
|
}
|
}
|
}
|
|
/**
|
* 获取订单基础数据:起终点,订单状态等
|
*/
|
private fun getData() {
|
HttpManager.queryOrderInfo(id, type).request(this) { _, data ->
|
order = data
|
data?.let {
|
|
if (session == null) {
|
try {
|
IGoApplication.tripId = it.tripId
|
val tripName = "providers/i-go-odrd-testing/trips/${it.tripId}"
|
val tripModelManager = consumerApi?.tripModelManager
|
val tripModel = tripModelManager?.getTripModel(tripName)
|
// Create a JourneySharingSession instance based on the TripModel.
|
session = JourneySharingSession.createInstance(tripModel!!)
|
// Add the JourneySharingSession instance on the map for updating the UI.
|
consumerController?.showSession(session!!)
|
tripModel.registerTripCallback(object : TripModelCallback() {
|
override fun onTripStatusUpdate(p0: TripInfo, p1: Int) {
|
super.onTripStatusUpdate(p0, p1)
|
Log.e(Const.GoogleTag, "onTripStatusUpdate:${p1}")
|
if (p1 == TripStatus.CANCELED || p1 == TripStatus.COMPLETE) {
|
Log.e(Const.GoogleTag, "重置tripId")
|
IGoApplication.tripId = ""
|
}
|
}
|
|
override fun onTripUpdated(p0: TripInfo) {
|
super.onTripUpdated(p0)
|
Log.e(
|
Const.GoogleTag,
|
"onTripUpdated:${p0.vehicleLocation?.latLng}"
|
)
|
vehicleLocation = p0.vehicleLocation
|
}
|
})
|
// Set refresh interval to 2 seconds.
|
val tripOptions =
|
TripModelOptions.builder().setRefreshIntervalMillis(2000).build()
|
tripModel.tripModelOptions = tripOptions
|
} catch (e: Exception) {
|
e.printStackTrace()
|
Log.e(Const.GoogleTag, e.message ?: "用户sdk初始化异常")
|
}
|
}
|
if (type == Const.OrderType.TYPE_TAXI && it.endLat == 0.0) {
|
tv_end.text = "——"
|
fl_one_click.visible()
|
} else
|
tv_end.text = it.endAddress
|
tv_start.text = it.startAddress
|
tv_time.text = it.travelTime
|
if (type == Const.OrderType.TYPE_CROSS_CITY) {
|
tv_passenger_num.visible()
|
tv_passenger_num.text =
|
String.format("%d人 座位:%s号", it.peopleNumber, it.seatNumber)
|
.replace(",", "号,")
|
tv_remark.visibility = if (it.remark.isNotEmpty()) View.VISIBLE else View.GONE
|
tv_remark.text = it.remark
|
}
|
if (type == Const.OrderType.TYPE_SAME_CITY) {
|
tv_passenger_num.visible()
|
tv_passenger_num.text = it.remark.ifEmpty { "——" }
|
}
|
if (it.state != 1) { //有司机
|
handler.removeMessages(0)
|
handler.removeMessages(1)
|
handler.removeMessages(2)
|
titleBar.getRightButton(0)?.visible()
|
tv_action.gone()
|
if (type == TYPE_SPECIAL)
|
tv_state.visible()
|
else
|
tv_state.gone()
|
cl_driver.visible()
|
order?.run {
|
iv_header_home.setImageURI(driverAvatar)
|
tv_name.text = driverName
|
tv_car.text = licensePlate
|
tv_car_info.text = "$brand·$carColor"
|
tv_score.text = String.format("%.1f", score)
|
tv_count.text = getString(R.string.单数, orderNum)
|
}
|
}
|
setStateUI()
|
}
|
}
|
}
|
|
/**
|
* 订单状态变化后的UI渲染,主要是起终点,标题等数据
|
*/
|
private fun setStateUI() {
|
logRecord("订单状态变化后的UI渲染${order}")
|
iv_shuaxing.gone()
|
ll_receiver_goods_code.isVisible = false
|
order?.let {
|
when (it.state) {
|
1 -> {
|
titleBar.getRightButton(0)?.visible()
|
titleBar.setTitle(getString(R.string.等待应答))
|
if (!handler.hasMessages(0))
|
handler.sendEmptyMessage(0)
|
tv_action.visible()
|
aMap?.animateCamera(
|
CameraUpdateFactory.newLatLngZoom(
|
LatLng(it.startLat, it.startLon), 18f
|
)
|
)
|
queryEndPush()
|
}
|
|
2 -> {
|
if (type == TripOrderFragment.TYPE_LOGISTICS)
|
titleBar.getRightButton(0)?.gone()
|
titleBar.setTitle(
|
getString(
|
if (type == TripOrderFragment.TYPE_LOGISTICS) {
|
ll_progress.gone()
|
R.string.等待取件
|
} else R.string.等待接驾
|
)
|
)
|
fl_reserve.visibility =
|
if (it.travelTime1.isNotEmpty() && it.travelTime1.parserTime() - System.currentTimeMillis() > (30L * 60 * 1000)) View.VISIBLE else View.GONE
|
if (!handler.hasMessages(2))
|
handler.sendEmptyMessage(2)
|
setMarker(LatLng(it.startLat, it.startLon), it.startAddress)
|
getTrippingData()
|
}
|
|
3 -> {
|
titleBar.getRightButton(0)?.gone()
|
titleBar.setTitle(
|
getString(
|
if (type == TripOrderFragment.TYPE_LOGISTICS) {
|
ll_progress.gone()
|
R.string.等待取件
|
} else R.string.等待接驾
|
)
|
)
|
if (!handler.hasMessages(2))
|
handler.sendEmptyMessage(2)
|
setMarker(LatLng(it.startLat, it.startLon), it.startAddress)
|
getTrippingData()
|
}
|
|
4 -> {
|
titleBar.getRightButton(0)?.gone()
|
println("隐藏取消订单")
|
titleBar.setTitle(getString(R.string.司机已到达))
|
setMarker(LatLng(it.startLat, it.startLon), it.startAddress)
|
if (!handler.hasMessages(1))
|
handler.sendEmptyMessage(1)
|
getTrippingData()
|
}
|
|
5 -> {
|
if (type == TYPE_SPECIAL)
|
iv_shuaxing.visible() else iv_shuaxing.gone()
|
titleBar.setTitle(getString(R.string.serving))
|
if (!handler.hasMessages(2))
|
handler.sendEmptyMessage(2)
|
setMarker(LatLng(it.startLat, it.startLon))
|
setMarker(LatLng(it.endLat, it.endLon), isStart = false)
|
getTrippingData()
|
// tv_complain.visible()
|
titleBar.getRightButton(0)?.visible()
|
titleBar.getRightButton(0)?.text = getString(R.string.投诉司机)
|
// if (type == Const.OrderType.TYPE_CROSS_CITY) //跨城行程中无法取消 //todo 原型没有修改终点
|
// titleBar.getRightButton(0)?.gone()
|
// if (type == Const.OrderType.TYPE_CROSS_CITY||type == Const.OrderType.TYPE_SPECIAL) //专车行程中增加修改目的地
|
// titleBar.getRightButton(0)?.text = getString(R.string.修改终点)
|
if (type == TYPE_SPECIAL) tv_change_destination.visible() else tv_change_destination.gone()
|
if (type != Const.OrderType.TYPE_SAME_CITY) {
|
tv_cancel.gone()
|
} //客户反馈:快件单一旦司机开始行程后(取到快件送货途中)就不能再取消订单
|
titleBar.getRightButton(0)?.gone()
|
aMap?.isMyLocationEnabled = false //行程中取消乘客定位
|
drawLine()
|
ll_receiver_goods_code.isVisible =
|
it.orderType == Const.OrderType.TYPE_SAME_CITY
|
tv_receiver_goods_code.text = getString(R.string.取件码) + (it.code ?: "")
|
}
|
|
10 -> {
|
if (it.cancelUserType != 1) {
|
startActivity<OrderCancelDetailActivity>("id" to id, "type" to type)
|
logRecord("进入订单详情页state:${it.state} orderId:${id} type:${type}")
|
finish()
|
}
|
}
|
|
else -> {
|
startActivity<OrderDetailActivity>("id" to id, "type" to type)
|
logRecord("进入订单详情页state:${it.state} orderId:${id} type:${type}")
|
finish()
|
}
|
}
|
}
|
}
|
|
private fun drawLine() {
|
if (order?.orderType == 4) return // 快件订单不绘制
|
if (startMarker != null && endMarker != null) {
|
AMapKit.initRouteLine(
|
startMarker!!.position,
|
endMarker!!.position,
|
object : (MutableList<LatLng>, Float, Long) -> Unit {
|
override fun invoke(p1: MutableList<LatLng>, p2: Float, p3: Long) {
|
if (isFinishing || isDestroyed) {
|
return
|
}
|
aMap?.also {
|
markerLine?.remove()
|
markerLine = AMapKit.drawLine(this@TripActivity, it, p1)
|
AMapKit.moveCamera(it, startMarker!!.position, endMarker!!.position)
|
}
|
}
|
})
|
}
|
}
|
|
/**
|
* 获取行程中的数据:主要是司机位置,订单状态变化,距离、时间等预算信息
|
*/
|
private fun getTrippingData() {
|
logRecord("获取行程中的数据")
|
IGoApplication.intervalCount = 0
|
HttpManager.trippingInfo(id, type).request(this) { _, data ->
|
data?.let {
|
logRecord("获取行程中的数据: ${it}")
|
if (!it.lat.isNullOrEmpty())
|
setDriverMarker(LatLng(it.lat.toDouble(), it.lon?.toDoubleOrNull() ?: 0.0))
|
if (it.state != order?.state) //订单状态发生变化,重新拉取数据
|
getData()
|
else {
|
setTrippingUI(it)
|
}
|
}
|
}
|
}
|
|
/**
|
* 获取是否有司机接单
|
*/
|
private fun queryEndPush() {
|
IGoApplication.intervalCount = 0
|
HttpManager.queryEndPush(id, type).request(this) { _, data ->
|
data?.let {
|
if (it.state == 2) { //无人接单
|
noResponse(id)
|
}
|
}
|
}
|
}
|
|
/**
|
* 超时无应答
|
*/
|
fun noResponse(id: Int) {
|
lifecycleScope.launch {
|
// 等待生命周期至少达到 RESUMED(即 onResume 之后)
|
if (id == this@TripActivity.id && !noResponseDialog.isAdded) {
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
noResponseDialog.show(supportFragmentManager, "noResponse")
|
}
|
}
|
}
|
}
|
|
/**
|
* 行程中的UI,展示不同状态下的动态数据
|
* */
|
private fun setTrippingUI(it: TrippingInfo) {
|
logRecord("展示不同状态下的动态数据: ${it}")
|
tv_state.isVisible = false
|
//订单状态(1=待接单,2=待出发,3=待到达预约地点,4=待乘客上车,5=服务中,6=完成服务,
|
// 7=待支付,8=待评价,9=已完成,10=已取消,11=改派中,12=取消待支付)加个15作为改派成功
|
when (order?.state) {
|
2, 3 -> {
|
if (order?.orderType != 4) { // 非快件订单才显示订单状态
|
tv_state.isVisible = true
|
if ((it.reservationMileage.isNullOrEmpty() || it.reservationMileage.toDouble() == 0.0)
|
&& (it.reservationTime.isNullOrEmpty() || it.reservationTime.toInt() == 0)
|
) { //无数据
|
tv_state.text = getString(R.string.司机接驾途中)
|
} else {
|
val time = getString(R.string.多少分钟, it.reservationTime)
|
val distance = "%.2f".format(it.reservationMileage?.toDoubleOrNull() ?: 0.0)
|
val s = getString(R.string.接驾中, distance, time)
|
tv_state.text = SpanBuilder(s).color(
|
this, s.indexOf(distance), s.indexOf(distance) + distance.length,
|
R.color.colorPrimary
|
).color(
|
this,
|
s.indexOf(time),
|
s.indexOf(time) + (it.reservationTime ?: "").length,
|
R.color.colorPrimary
|
).build()
|
}
|
}
|
|
logRecord("setTrippingUI tips ${tv_state.text}")
|
}
|
|
4 -> {
|
tv_state.isVisible = true
|
}
|
|
5, 6 -> {
|
if (order?.orderType != 4) { // 非快件订单才显示订单状态
|
tv_state.isVisible = true
|
val mile2 = "%.2f".format(it.servedMileage?.toDoubleOrNull() ?: 0.0)
|
val timeS = getString(R.string.多少分钟, it.laveTime)
|
val s =
|
getString(R.string.已服务时间, it.servedTime, mile2, it.laveMileage, timeS)
|
tv_state.text = SpanBuilder(s).color(
|
this,
|
s.indexOf(it.servedTime ?: ""),
|
s.indexOf(it.servedTime ?: "") + (it.servedTime ?: "").length,
|
R.color.colorPrimary
|
)
|
.color(
|
this,
|
s.indexOf(mile2),
|
s.indexOf(mile2) + mile2.length,
|
R.color.colorPrimary
|
)
|
.color(
|
this,
|
s.indexOf(it.laveMileage ?: ""),
|
s.indexOf(it.laveMileage ?: "") + (it.laveMileage ?: "").length,
|
R.color.colorPrimary
|
)
|
.color(
|
this,
|
s.lastIndexOf(timeS),
|
s.lastIndexOf(timeS) + (it.laveTime ?: "").length,
|
R.color.colorPrimary
|
)
|
.build()
|
logRecord("setTrippingUI tips ${tv_state.text}")
|
}
|
if (!it.orderPositionList.isNullOrEmpty()) {
|
try {
|
val list = gson.fromJson<List<Point>>(
|
it.orderPositionList,
|
object : TypeToken<List<Point>>() {}.type
|
)
|
if (!list.isNullOrEmpty()) {
|
oldDrivedRouteOverlay = newDrivedRouteOverlay
|
newDrivedRouteOverlay = drawLine(list.map { LatLng(it.lat, it.lon) })
|
oldDrivedRouteOverlay?.remove()
|
}
|
} catch (e: Exception) {
|
e.printStackTrace()
|
}
|
}
|
}
|
}
|
}
|
|
private var startMarker: Marker? = null
|
private var endMarker: Marker? = null
|
var markerLine: Polyline? = null
|
|
/**
|
* @param isStart true:起点标记 false:终点标记
|
*/
|
private fun setMarker(latLon: LatLng, content: CharSequence = "", isStart: Boolean = true) {
|
val language = LanguageUtil.getLanguage()
|
if (isStart) {
|
val ic = when (language) {
|
Const.Language.ENGLISH -> R.mipmap.starting_point_e
|
Const.Language.CHINESE -> R.mipmap.starting_point
|
else -> R.mipmap.starting_point_f
|
}
|
val icon = if (content.isEmpty()) BitmapDescriptorFactory.fromResource(ic)
|
else {
|
val view = layoutInflater.inflate(R.layout.marker_with_text_2, null, false)
|
view.find<TextView>(R.id.tv_content).text = content
|
view.find<ImageView>(R.id.iv).imageResource =
|
if (order?.state == 1) R.mipmap.icon_location else ic
|
BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(view))
|
}
|
if (startMarker != null) {
|
startMarker!!.position = latLon
|
startMarker!!.setIcon(icon)
|
} else {
|
val options = MarkerOptions()
|
options.position(latLon).icon(icon)
|
startMarker = aMap?.addMarker(options)
|
}
|
} else {
|
val ic = when (language) {
|
Const.Language.ENGLISH -> R.mipmap.end_point_e
|
Const.Language.CHINESE -> R.mipmap.end_point
|
else -> R.mipmap.end_point_f
|
}
|
if (endMarker != null) {
|
endMarker!!.position = latLon
|
} else {
|
val options = MarkerOptions()
|
options.position(latLon).icon(BitmapDescriptorFactory.fromResource(ic))
|
endMarker = aMap?.addMarker(options)
|
}
|
}
|
}
|
|
private var driverMarker: Marker? = null //司机标记
|
private fun setDriverMarker(latLng: LatLng) { //现在使用谷歌套餐,不需要自己画司机位置
|
if (driverMarker == null) {
|
val b = BitmapDescriptorFactory.fromResource(R.mipmap.location_car)
|
val options = MarkerOptions()
|
options.position(latLng)
|
options.icon(b)
|
driverMarker = aMap?.addMarker(options)
|
} else {
|
driverMarker?.position = latLng
|
}
|
}
|
|
/**
|
* 绘制已行驶灰色路径
|
*/
|
private fun drawLine(latLngs: List<LatLng>): Polyline? {
|
val options = PolylineOptions().addAll(latLngs)
|
if (driverMarker != null) {
|
options.add(driverMarker!!.position)
|
}
|
options.width(20f).color(Color.parseColor("#999999"))
|
return aMap?.addPolyline(options)
|
}
|
|
/**
|
* handler定时器
|
* #what:0:等待应答 1:司机等待 2:其他状态时,判断socket是否在线,如果不在线就调仿socket接口
|
*/
|
override fun handleMessage(msg: Message): Boolean {
|
if (order == null)
|
return true
|
when (msg.what) {
|
0 -> {
|
if (order?.state == 1) {
|
val latLon = LatLng(order!!.startLat, order!!.startLon)
|
val waittime = order!!.insertTime.parserTime()
|
val s = System.currentTimeMillis()
|
val i = Math.max(s - waittime, 0L)
|
val c = getString(R.string.正在寻找车辆, i / 1000 / 60, i / 1000 % 60)
|
setMarker(
|
latLon, SpanBuilder(c)
|
.color(this, c.length - 6, c.length, R.color.colorRed).build()
|
)
|
IGoApplication.intervalCount++
|
if (IGoApplication.intervalCount > 7) {
|
queryEndPush()
|
getTrippingData()
|
}
|
logRecord("事件0:" + IGoApplication.intervalCount)
|
handler.sendEmptyMessageDelayed(0, 1000)
|
}
|
}
|
|
1 -> {
|
if (order?.state == 4) {
|
val waittime = order!!.arriveTime.parserTime()
|
val s = System.currentTimeMillis()
|
val i = Math.max(s - waittime, 0L)
|
val c = getString(R.string.司机到达预约地点等待, i / 1000 / 60, i / 1000 % 60)
|
tv_state.text =
|
SpanBuilder(c).color(this, c.length - 5, c.length, R.color.colorPrimary)
|
.build()
|
IGoApplication.intervalCount++
|
if (IGoApplication.intervalCount > 7) {
|
getTrippingData()
|
}
|
logRecord("事件1:" + IGoApplication.intervalCount)
|
handler.sendEmptyMessageDelayed(1, 1000)
|
}
|
}
|
|
2 -> {
|
IGoApplication.intervalCount++
|
if (IGoApplication.intervalCount > 7) {
|
getTrippingData()
|
}
|
logRecord("事件2:" + IGoApplication.intervalCount)
|
if (order?.state == 2)
|
fl_reserve.visibility =
|
if (order!!.travelTime1.isNotEmpty() && order!!.travelTime1.parserTime() - System.currentTimeMillis() > (30L * 60 * 1000)) View.VISIBLE else View.GONE
|
handler.sendEmptyMessageDelayed(2, 1000)
|
}
|
|
4 -> {
|
consumerController?.isAutoCameraEnabled = true
|
}
|
}
|
return true
|
}
|
|
override fun onStateChanged(id: Int, type: Int, state: Int) { //state
|
if (id == order?.orderId && type == order?.orderType) {
|
setResult(RESULT_OK)
|
if (order?.driverId == 0 || order?.arriveTime.isNullOrEmpty() || state == 15 || state == 10) { //司机接单和到达预约点需要掉接口去获取司机信息以及等待开始时间
|
getData()
|
} else {
|
order?.state = state
|
setStateUI()
|
}
|
}
|
}
|
|
override fun onTrippingChanged(info: TrippingInfo) {
|
if (info.orderId == order?.orderId && info.orderType == order?.orderType) {
|
setTrippingUI(info)
|
}
|
}
|
|
override fun onAddressChanged(info: TrippingInfo) {
|
Log.e("地址变更: ", (info.status == 2).toString())
|
if (info.orderId == order?.orderId) {
|
if (info.status == 2) { //司机同意修改目的地
|
getData()
|
}
|
if (info.status == 3) {//司机拒绝修改目的地
|
val tipDialog = TipDialog()
|
tipDialog.arguments = bundleOf(
|
"msg" to getString(R.string.拒绝变更),
|
"ok" to getString(R.string.确认), "isAlert" to true
|
)
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
}
|
|
override fun onCancel() {
|
}
|
})
|
tipDialog.show(supportFragmentManager, "refuse")
|
}
|
}
|
}
|
|
override fun onShuttleConfirm(id: Int, type: Int) {
|
if (this.type == TYPE_SPECIAL && order?.state == 1) {
|
this.type = type
|
this.id = id
|
getData()
|
}
|
}
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
super.onActivityResult(requestCode, resultCode, data)
|
if (resultCode == RESULT_OK && data != null) {
|
if (requestCode == 1) {
|
setResult(RESULT_OK)
|
logRecord("取消订单退出处理订单页orderId:${id} type:${type}")
|
finish()
|
val money = data.getDoubleExtra("money", 0.0)
|
if (money != 0.0)
|
startActivity<OrderDetailActivity>("id" to id, "type" to type)
|
} else if (requestCode == 2) { //修改终点
|
val lat = data.getDoubleExtra("lat", 0.0)
|
val lon = data.getDoubleExtra("lon", 0.0)
|
val address = data.getStringExtra("name") ?: ""
|
val tipDialog = TipDialog()
|
tipDialog.arguments = bundleOf(
|
"msg" to getString(R.string.变更目的地提示),
|
"ok" to getString(R.string.确认),
|
"cancel" to getString(R.string.拒绝)
|
)
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
showDialog()
|
HttpManager.updateEndAddress(address, lat, lon, id, type)
|
.request(this@TripActivity) { _, _ ->
|
}
|
}
|
|
override fun onCancel() {
|
}
|
})
|
tipDialog.show(supportFragmentManager, "modify")
|
}
|
}
|
}
|
|
/**
|
* 吧iew转化为bitmap
|
*
|
* @param view
|
* @return
|
*/
|
fun convertViewToBitmap(view: View): Bitmap {
|
view.isDrawingCacheEnabled = true
|
view.measure(
|
View.MeasureSpec.makeMeasureSpec(
|
0,
|
View.MeasureSpec.UNSPECIFIED
|
),
|
View.MeasureSpec.makeMeasureSpec(
|
0,
|
View.MeasureSpec.UNSPECIFIED
|
)
|
)
|
view.layout(0, 0, view.measuredWidth, view.measuredHeight)
|
view.buildDrawingCache()
|
val mCacheBitmap = view.drawingCache
|
return Bitmap.createBitmap(mCacheBitmap)
|
}
|
|
override fun onResume() {
|
super.onResume()
|
getData()
|
NettyClient.getInstance().checkNettyState()
|
}
|
|
|
override fun onDestroy() {
|
handler.removeMessages(0)
|
handler.removeMessages(1)
|
handler.removeMessages(2)
|
handler.removeMessages(3)
|
app.removeTripStateListener(this)
|
IGoApplication.tripId = ""
|
session?.stop()
|
super.onDestroy()
|
}
|
|
override fun onBackPressed() {
|
if (ll_progress.visibility == View.VISIBLE)
|
ll_progress.gone()
|
else
|
super.onBackPressed()
|
}
|
}
|