package com.fuban.user.ui.trip
|
|
import android.app.Activity
|
import android.content.Intent
|
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 androidx.core.os.bundleOf
|
import cn.sinata.amaplib.overlay.DrivingRouteOverlay
|
import cn.sinata.rxnetty.NettyClient
|
import cn.sinata.xldutils.callPhone
|
import cn.sinata.xldutils.gone
|
import cn.sinata.xldutils.utils.SpanBuilder
|
import cn.sinata.xldutils.utils.myToast
|
import cn.sinata.xldutils.utils.parserTime
|
import cn.sinata.xldutils.visible
|
import com.amap.api.maps.CameraUpdateFactory
|
import com.amap.api.maps.model.*
|
import com.amap.api.services.core.LatLonPoint
|
import com.amap.api.services.route.*
|
import com.fuban.user.FBApplication
|
import com.fuban.user.R
|
import com.fuban.user.interfaces.OrderStateChangeListener
|
import com.fuban.user.network.Apis
|
import com.fuban.user.network.HttpManager
|
import com.fuban.user.network.entity.Order
|
import com.fuban.user.network.entity.TrippingInfo
|
import com.fuban.user.network.request
|
import com.fuban.user.ui.TransparentStatusBarActivity
|
import com.fuban.user.dialog.ShareDialog
|
import com.fuban.user.dialog.TipDialog
|
import com.fuban.user.utils.Const
|
import com.share.utils.ShareUtils
|
import com.umeng.socialize.UMShareListener
|
import com.umeng.socialize.bean.SHARE_MEDIA
|
import kotlinx.android.synthetic.main.activity_trip.*
|
import kotlinx.android.synthetic.main.marker_with_text.view.*
|
import org.jetbrains.anko.imageResource
|
import org.jetbrains.anko.sdk27.coroutines.onClick
|
import org.jetbrains.anko.startActivity
|
import org.jetbrains.anko.startActivityForResult
|
|
class TripActivity:TransparentStatusBarActivity(), Handler.Callback, OrderStateChangeListener,
|
RouteSearch.OnRouteSearchListener,UMShareListener {
|
override fun setContentView() = R.layout.activity_trip
|
private val aMap by lazy {
|
mMapView.map
|
}
|
private val app by lazy {
|
application as FBApplication
|
}
|
private val handler by lazy {
|
Handler(this)
|
}
|
private val noResponseDialog by lazy { //无应答弹窗,不重复覆盖弹窗
|
val tipDialog = TipDialog()
|
tipDialog.arguments =
|
bundleOf("msg" to "附近暂无司机接单,您是否继续等待?", "ok" to "继续等待", "cancel" to "取消订单")
|
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 = "" //客服电话
|
|
override fun initClick() {
|
tv_complain.onClick {
|
startActivity<ComplainActivity>("id" to order!!.driverId)
|
}
|
|
tv_action.setOnClickListener {
|
if (order?.state == 1){
|
val tipDialog = TipDialog()
|
tipDialog.arguments = bundleOf("msg" to "您确定要取消该订单吗?","ok" to "确定取消","cancel" to "不取消")
|
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)
|
}
|
|
tv_share.onClick {
|
val shareDialog = ShareDialog()
|
shareDialog.arguments = bundleOf("isTrip" to true)
|
shareDialog.setCallback(object :ShareDialog.Callback{
|
override fun onOk(way: Int) {
|
ShareUtils.share(this@TripActivity,if (way == 0) SHARE_MEDIA.WEIXIN else if (way == 1) SHARE_MEDIA.QQ else
|
SHARE_MEDIA.MORE, String.format(Const.Share.TRIP_CONTENT,FBApplication.phone,if (type == 1) "专车" else "出租车",order!!.licensePlate),
|
Const.Share.TITLE,String.format(Apis.TRIP_URL,id,type),this@TripActivity,FBApplication.emergency)
|
shareDialog.dismiss()
|
}
|
})
|
shareDialog.show(supportFragmentManager,"share")
|
}
|
|
iv_header_home.setOnClickListener {
|
startActivity<DriverDetailActivity>("id" to order!!.driverId)
|
}
|
|
iv_location.setOnClickListener {
|
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(FBApplication.lat,FBApplication.lon),15f))
|
}
|
}
|
|
private fun cancelOrder() {
|
HttpManager.cancelOrder(id,type).request(this){ _, _->
|
myToast("取消成功")
|
setResult(Activity.RESULT_OK)
|
finish()
|
}
|
}
|
|
override fun initView() {
|
id = intent.getIntExtra("id",0)
|
type = intent.getIntExtra("type",Const.OrderType.TYPE_TAXI)
|
titleBar.addRightButton("取消订单",onClickListener = View.OnClickListener {
|
// if (order?.state in (5..6))
|
// startActivity<ComplainActivity>("id" to order!!.driverId)
|
// else
|
startActivityForResult<CancelOrderActivity>(1,"id" to id,"type" to type)
|
})
|
titleBar.getRightButton(0)?.gone()
|
initMap()
|
app.addTripStateListener(this)
|
getPhone()
|
}
|
|
private fun initMap() {
|
val myLocationStyle = MyLocationStyle()
|
myLocationStyle.strokeColor(resources.getColor(R.color.colorBrown))
|
myLocationStyle.radiusFillColor(resources.getColor(R.color.colorTransBrown))
|
myLocationStyle.interval(2000)
|
myLocationStyle.anchor(0.5f, 0.5f)
|
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//
|
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.my_blue_loc))
|
aMap.myLocationStyle = myLocationStyle//设置定位蓝点的Style
|
aMap.uiSettings.isMyLocationButtonEnabled = false//设置默认定位按钮是否显示,非必需设置。
|
aMap.uiSettings.setZoomInByScreenCenter(true)
|
aMap.uiSettings.isZoomControlsEnabled = false
|
aMap.uiSettings.isRotateGesturesEnabled = false
|
aMap.uiSettings.isTiltGesturesEnabled = false
|
aMap.isMyLocationEnabled = true
|
aMap.moveCamera(CameraUpdateFactory.newLatLng(LatLng(FBApplication.lat,FBApplication.lon)))
|
}
|
|
|
private fun getPhone(){
|
HttpManager.getPhone(FBApplication.chooseCityCode).request(this){ _, data->
|
data?.let {
|
it.forEach {
|
if (it.type == 1)
|
phoneEmergency = it.phone
|
else
|
phoneService = it.phone
|
}
|
}
|
}
|
}
|
|
/**
|
* 获取订单基础数据:起终点,订单状态等
|
*/
|
private fun getData(){
|
HttpManager.queryOrderInfo(id,type).request(this){_,data->
|
order = data
|
data?.let {
|
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 (it.state !=1){ //有司机
|
handler.removeMessages(0)
|
handler.removeMessages(1)
|
handler.removeMessages(2)
|
titleBar.getRightButton(0)?.visible()
|
tv_action.gone()
|
tv_state.visible()
|
cl_driver.visible()
|
order?.run {
|
iv_header_home.setImageURI(driverAvatar)
|
tv_name.text = "$driverName $licensePlate"
|
tv_car_info.text = "$brand·$carColor"
|
tv_score.text = String.format("%.1f",score)
|
tv_count.text = String.format("%d单",orderNum)
|
}
|
}
|
setStateUI()
|
}
|
}
|
}
|
|
/**
|
* 订单状态变化后的UI渲染,主要是起终点,标题等数据
|
*/
|
private fun setStateUI(){
|
order?.let {
|
when(it.state){
|
1->{
|
title = "等待应答"
|
if (!handler.hasMessages(0))
|
handler.sendEmptyMessage(0)
|
tv_action.visible()
|
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.startLat,it.startLon),15f))
|
queryEndPush()
|
}
|
2->{
|
title = "等待接驾"
|
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->{
|
title = "等待接驾"
|
if (!handler.hasMessages(2))
|
handler.sendEmptyMessage(2)
|
setMarker(LatLng(it.startLat,it.startLon),it.startAddress)
|
getTrippingData()
|
}
|
4->{
|
title = "司机已到达"
|
setMarker(LatLng(it.startLat,it.startLon),it.startAddress)
|
if (!handler.hasMessages(1))
|
handler.sendEmptyMessage(1)
|
getTrippingData()
|
}
|
5,6->{
|
title = "服务中"
|
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()
|
tv_share.visible()
|
// if (type == Const.OrderType.TYPE_CROSS_CITY) //跨城行程中无法取消
|
titleBar.getRightButton(0)?.gone()
|
}else->{
|
startActivity<OrderDetailActivity>("id" to id,"type" to type)
|
finish()
|
}
|
}
|
}
|
}
|
|
|
/**
|
* 获取行程中的数据:主要是司机位置,订单状态变化,距离、时间等预算信息
|
*/
|
private fun getTrippingData(){
|
FBApplication.intervalCount = 0
|
HttpManager.trippingInfo(id,type).request(this){_,data->
|
data?.let {
|
if (it.lat.isNotEmpty())
|
setDriverMarker(LatLng(it.lat.toDouble(),it.lon.toDouble()))
|
if (it.state!=order?.state) //订单状态发生变化,重新拉取数据
|
getData()
|
else{
|
setTrippingUI(it)
|
}
|
}
|
}
|
}
|
|
/**
|
* 获取是否有司机接单
|
*/
|
private fun queryEndPush(){
|
FBApplication.intervalCount = 0
|
HttpManager.queryEndPush(id,type).request(this){_,data->
|
data?.let {
|
if (it.state == 2){ //无人接单
|
noResponse(id)
|
}
|
}
|
}
|
}
|
|
/**
|
* 超时无应答
|
*/
|
fun noResponse(id: Int){
|
if (id == this@TripActivity.id&&!noResponseDialog.isAdded) {
|
noResponseDialog.show(supportFragmentManager, "noResponse")
|
}
|
}
|
|
/**
|
* 行程中的UI,展示不同状态下的动态数据
|
* */
|
private fun setTrippingUI(it:TrippingInfo){
|
when(order?.state){
|
2,3->{
|
val s = String.format("司机接单,距预约地点大约%s公里,大约%s分钟到达",it.reservationMileage,it.reservationTime)
|
tv_state.text = SpanBuilder(s).color(this,12,s.indexOf("公"),R.color.color_text_price)
|
.color(this,s.indexOf("公")+5,s.indexOf("分"),R.color.color_text_price).build()
|
if (it.lat.isNotEmpty()){
|
//todo 移动视角吗?不需要,因为查询路径后做了移动
|
// val builder = LatLngBounds.builder()
|
// builder.include(LatLng(order!!.startLat,order!!.startLon)).include(
|
// LatLng(it.lat.toDouble(),it.lon.toDouble()))
|
if (order?.state == 3)
|
setRoute(LatLonPoint(it.lat.toDouble(),it.lon.toDouble()),
|
LatLonPoint(order!!.startLat,order!!.startLon)
|
)
|
}
|
}
|
4->{
|
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.lat.toDouble(),it.lon.toDouble()), 15f))
|
oldDrivingRouteOverlay?.removeFromMap()
|
newDrivingRouteOverlay?.removeFromMap()
|
}
|
5,6->{
|
val s = String.format("已为您服务%s分钟,累计行驶%s公里\n距离目的地还有大约%s公里,预计行驶大约%s分钟",
|
it.servedTime,it.servedMileage,it.laveMileage,it.laveTime)
|
tv_state.text = SpanBuilder(s).color(this,5,s.indexOf("分"),R.color.color_text_price)
|
.color(this,s.indexOf("驶")+1,s.indexOf("公"),R.color.color_text_price)
|
.color(this,s.indexOf("约")+1,s.indexOf("约")+it.laveMileage.length+1,R.color.color_text_price)
|
.color(this,s.length-2-it.laveTime.length,s.length-2,R.color.color_text_price)
|
.build()
|
if (it.lat.isNotEmpty())
|
setRoute(LatLonPoint(it.lat.toDouble(),it.lon.toDouble()),
|
LatLonPoint(order!!.endLat,order!!.endLon)
|
)
|
}
|
}
|
}
|
|
private var startMarker: Marker? = null
|
private var endMarker: Marker? = null
|
|
/**
|
* @param isStart true:起点标记 false:终点标记
|
*/
|
private fun setMarker(latLon: LatLng, content: CharSequence = "",isStart:Boolean = true) {
|
if (isStart){
|
val icon = if (content.isEmpty()) BitmapDescriptorFactory.fromResource(R.mipmap.starting_point)
|
else{
|
val view = layoutInflater.inflate(R.layout.marker_with_text_2, null, false)
|
view.tv_content.text = content
|
view.iv.imageResource = if (order?.state == 1) R.mipmap.icon_location else R.mipmap.starting_point
|
BitmapDescriptorFactory.fromView(view)
|
}
|
if (startMarker!=null){
|
startMarker!!.position =latLon
|
startMarker!!.setIcon(icon)
|
}else{
|
val options = MarkerOptions()
|
options.position(latLon).icon(icon)
|
startMarker = aMap.addMarker(options)
|
}
|
}else{
|
if (endMarker!=null){
|
endMarker!!.options.position(latLon)
|
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.end_point))
|
}else{
|
val options = MarkerOptions()
|
options.position(latLon).icon(BitmapDescriptorFactory.fromResource(R.mipmap.end_point))
|
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 setRoute(start: LatLonPoint, end: LatLonPoint) {
|
|
val fromAndTo = RouteSearch.FromAndTo(start, end)
|
val driveRouteQuery =
|
RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_SAVE_MONEY, null, null, "")
|
val routeSearch = RouteSearch(this)
|
routeSearch.calculateDriveRouteAsyn(driveRouteQuery)
|
routeSearch.setRouteSearchListener(this)
|
}
|
|
/**
|
* 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 = String.format("正为您寻找车辆 等待%02d:%02d", i / 1000 / 60, i / 1000 % 60)
|
setMarker(latLon, SpanBuilder(c)
|
.color(this,10,c.length,R.color.colorRed).build())
|
FBApplication.intervalCount ++
|
if (FBApplication.intervalCount>7){
|
queryEndPush()
|
getTrippingData()
|
}
|
Log.e("timer","事件0:"+FBApplication.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 = String.format("司机到达预约地点,已等您%02d:%02d", i / 1000 / 60, i / 1000 % 60)
|
tv_state.text = SpanBuilder(c).color(this,12,c.length,R.color.colorRed).build()
|
FBApplication.intervalCount ++
|
if (FBApplication.intervalCount>7){
|
getTrippingData()
|
}
|
Log.e("timer","事件1:"+FBApplication.intervalCount)
|
handler.sendEmptyMessageDelayed(1, 1000)
|
}
|
}
|
2->{
|
FBApplication.intervalCount ++
|
if (FBApplication.intervalCount>7){
|
getTrippingData()
|
}
|
Log.e("timer","事件2:"+FBApplication.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)
|
}
|
}
|
return true
|
}
|
|
override fun onStateChanged(id: Int, state: Int) { //state
|
if (id == order?.orderId){
|
setResult(Activity.RESULT_OK)
|
if (order?.driverId==0||order?.arriveTime.isNullOrEmpty()||state == 15){ //司机接单和到达预约点需要掉接口去获取司机信息以及等待开始时间
|
getData()
|
}else{
|
order?.state = state
|
setStateUI()
|
}
|
}
|
}
|
|
override fun onTrippingChanged(info: TrippingInfo) {
|
if (info.orderId == order?.orderId){
|
setTrippingUI(info)
|
}
|
}
|
|
override fun onShuttleConfirm(id: Int, type: Int) {
|
if (this.type == Const.OrderType.TYPE_SPECIAL&&order?.state == 1){
|
this.type = type
|
this.id = id
|
getData()
|
}
|
}
|
|
private var oldDrivingRouteOverlay: DrivingRouteOverlay? = null
|
private var newDrivingRouteOverlay: DrivingRouteOverlay? = null
|
override fun onDriveRouteSearched(result: DriveRouteResult?, errorCode: Int) {
|
if (errorCode == 1000) {
|
if (result?.paths != null) {
|
oldDrivingRouteOverlay = newDrivingRouteOverlay
|
if (result.paths.size > 0) {
|
val drivePath = result.paths[0]
|
newDrivingRouteOverlay = DrivingRouteOverlay(
|
this, aMap, drivePath,
|
result.startPos,
|
result.targetPos
|
)
|
newDrivingRouteOverlay!!.setNodeIconVisibility(false)
|
newDrivingRouteOverlay!!.addToMap(Color.parseColor("#00C47A"))
|
newDrivingRouteOverlay!!.zoomToSpan(50, 620, 50, 300)
|
oldDrivingRouteOverlay?.removeFromMap()
|
}
|
}
|
}
|
}
|
|
override fun onBusRouteSearched(p0: BusRouteResult?, p1: Int) {
|
}
|
|
override fun onRideRouteSearched(p0: RideRouteResult?, p1: Int) {
|
}
|
|
override fun onWalkRouteSearched(p0: WalkRouteResult?, p1: Int) {
|
}
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
super.onActivityResult(requestCode, resultCode, data)
|
if (requestCode == 1&&resultCode == Activity.RESULT_OK&&data!=null){
|
setResult(Activity.RESULT_OK)
|
finish()
|
val money = data.getDoubleExtra("money", 0.0)
|
if (money!=0.0)
|
startActivity<OrderDetailActivity>("id" to id,"type" to type)
|
}
|
}
|
|
override fun onResume() {
|
super.onResume()
|
mMapView.onResume()
|
getData()
|
NettyClient.getInstance().checkNettyState()
|
}
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
super.onCreate(savedInstanceState)
|
mMapView.onCreate(savedInstanceState)
|
}
|
|
override fun onSaveInstanceState(outState: Bundle) {
|
super.onSaveInstanceState(outState)
|
mMapView.onSaveInstanceState(outState)
|
}
|
|
override fun onLowMemory() {
|
super.onLowMemory()
|
mMapView.onLowMemory()
|
}
|
|
override fun onPause() {
|
super.onPause()
|
mMapView.onPause()
|
}
|
|
override fun onDestroy() {
|
mMapView.onDestroy()
|
handler.removeMessages(0)
|
handler.removeMessages(1)
|
handler.removeMessages(2)
|
app.removeTripStateListener(this)
|
super.onDestroy()
|
}
|
|
override fun onResult(p0: SHARE_MEDIA?) {
|
}
|
|
override fun onCancel(p0: SHARE_MEDIA?) {
|
}
|
|
override fun onError(p0: SHARE_MEDIA?, p1: Throwable?) {
|
}
|
|
override fun onStart(p0: SHARE_MEDIA?) {
|
}
|
|
}
|