[3.0.0] merge dev_robobus_network_weak_230323

This commit is contained in:
wangmingjun
2023-03-31 18:46:21 +08:00
417 changed files with 11523 additions and 239 deletions

View File

@@ -48,17 +48,6 @@ android {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '0'
}
// 车型金旅m1 小巴业务
m1 {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '1'
}
// 车型金旅m1 小巴业务
m2 {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '1'
}
}
}

View File

@@ -4,8 +4,6 @@ import com.amap.api.maps.model.LatLng;
import java.util.List;
import mogo.telematics.pad.MessagePad;
/**
* Created on 2022/3/31
*/

View File

@@ -1,24 +0,0 @@
package com.mogo.och.bus.passenger.constant
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.common.module.biz.constant.OchCommonConst
/**
* Created on 2021/12/6
*/
class URLConst {
companion object {
@JvmStatic
fun getBaseUrl(): String {
return if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)){
OchCommonConst.getShuttleUrl()
}else{
OchCommonConst.getBaseUrl()
}
}
}
}

View File

@@ -540,11 +540,7 @@ public class BusPassengerModel {
}
public int getAverageSpeed(){
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)){
return BusPassengerConst.SHUTTLE_AVERAGE_SPEED;
}else {
return BusPassengerConst.BUS_AVERAGE_SPEED;
}
return BusPassengerConst.BUS_AVERAGE_SPEED;
}
public void startRemainRouteInfo() {

View File

@@ -4,13 +4,10 @@ import android.content.Context
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager.getServerToken
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.bus.passenger.constant.URLConst.Companion.getBaseUrl
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.biz.network.interceptor.transformTry
@@ -22,17 +19,15 @@ object BusPassengerServiceManager {
private var driverSnCache = ""
private var mShuttleBusPassengerServiceApi =
MoGoRetrofitFactory.getInstance(getBaseUrl()).create(ShettlePassengerServiceApi::class.java)
private var mBusPassengerServiceApi =
MoGoRetrofitFactory.getInstance(getBaseUrl()).create(PassengerServiceApi::class.java)
MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(PassengerServiceApi::class.java)
/**
* 获取Bus司机端的sn
* @return
*/
val driverAppSn: String
get(){
get() {
val serverToken = getServerToken()
if (serverToken != driverSnCache && serverToken.isNotEmpty()) {
driverSnCache = serverToken
@@ -49,25 +44,14 @@ object BusPassengerServiceManager {
fun queryDriverSiteByCoordinate(
context: Context, callback: OchCommonServiceCallback<BusPassengerRoutesResponse>?
) {
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
mShuttleBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
BusPassengerQueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate"))
} else {
mBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
BusPassengerQueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate"))
}
mBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
BusPassengerQueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate"))
}
/**
@@ -80,22 +64,12 @@ object BusPassengerServiceManager {
context: Context,
callback: OchCommonServiceCallback<BusPassengerOperationStatusResponse>?
) {
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
mShuttleBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus"))
} else {
mBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus"))
}
mBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus"))
}
}

View File

@@ -8,6 +8,7 @@ package com.mogo.och.bus.bean;
public class BusStationBean {
private int siteId;
private String name;
private String nameKr;
private int seq;
private double gcjLon; //高德
private double gcjLat; //高德
@@ -21,6 +22,10 @@ public class BusStationBean {
private int status;
private int ifStop = 1; // 是否需要停靠、1需要、0不需要 // TODO: 2021/10/19 原来站点里有设计是否需要停靠字段,现设计暂无,默认都需要停靠
public String getNameKr() {
return nameKr;
}
public double getGcjLon() {
return gcjLon;
}

View File

@@ -1,12 +0,0 @@
package com.mogo.och.bus.constant
import com.mogo.commons.debug.DebugConfig
/**
* Created on 2021/12/6
*/
class URLConst {
companion object {
}
}

View File

@@ -581,11 +581,12 @@ public class OrderModel {
* 服务端返回的OchBusRoutesResult逻辑 离开站为当前站, 到达下一站后才会将下一站置为当前站,
* 车机端展示是离开当前站,下一站设置为当前站, 所以服务端数据回来要做处理,不能直接渲染
*/
private void leaveStationSuccess(int leaveIndex, String leaveStation, String nextStation) {
private void leaveStationSuccess(int leaveIndex, String leaveStation,
String nextStation, String nextStationKr) {
onStartAutopilot(leaveIndex);
leaveTTSTips(nextStation);
leaveTTSTips(nextStation,nextStationKr);
if (busRoutesResult != null) {
boolean isLastStop = false;
@@ -657,6 +658,7 @@ public class OrderModel {
}
int arrivedStationIndex = backgroundCurrentStationIndex + 1;
String arriveStation = stationList.get(arrivedStationIndex).getName();
String arriveStationKr = stationList.get(arrivedStationIndex).getNameKr();
String departureStopName = stationList.get(backgroundCurrentStationIndex).getName();
CallerLogger.INSTANCE.d(M_BUS + TAG, "arriveSiteStation-currentStationIndex = " + arrivedStationIndex);
@@ -672,7 +674,8 @@ public class OrderModel {
queryBusRoutes();
isArrivedStation = true;
isGoingToNextStation = false;
arriveStationSuccess(arrivedStationIndex, departureStopName, arriveStation);
arriveStationSuccess(arrivedStationIndex, departureStopName,
arriveStation,arriveStationKr);
}
//5s轮询核销乘客
// startOrStopQueryPassengerWriteOff(true);
@@ -701,7 +704,8 @@ public class OrderModel {
});
}
private void arriveStationSuccess(int arrivedStationIndex, String departureStopName, String arriveStation) {
private void arriveStationSuccess(int arrivedStationIndex, String departureStopName,
String arriveStation, String arriveStationKr) {
if (busRoutesResult != null) {
boolean isLastStop = false;
if (arrivedStationIndex == busRoutesResult.getSites().size() - 1) {
@@ -714,7 +718,7 @@ public class OrderModel {
, arriveStation
, isLastStop);
}
VoiceManager.INSTANCE.arrivedStation(arriveStation);
VoiceManager.INSTANCE.arrivedStation(arriveStation,arriveStationKr);
}
/**
@@ -723,11 +727,14 @@ public class OrderModel {
public void leaveStation() {
CallerLogger.INSTANCE.d(M_BUS + TAG, "leaveStation-backgroundCurrentStationIndex = " + backgroundCurrentStationIndex);
String nextStationName = "";
String nextStationNameKr = "";
if (backgroundCurrentStationIndex < stationList.size() - 1) {
nextStationName = stationList.get(backgroundCurrentStationIndex + 1).getName();
nextStationNameKr = stationList.get(backgroundCurrentStationIndex + 1).getNameKr();
}
final String currentStationName = stationList.get(backgroundCurrentStationIndex).getName();
String finalNextStationName = nextStationName;
String finalNextStationNameKr = nextStationNameKr;
OrderServiceManager.leaveStation(mContext,
stationList.get(backgroundCurrentStationIndex).getSeq(),
stationList.get(backgroundCurrentStationIndex).getSiteId(),
@@ -740,7 +747,8 @@ public class OrderModel {
//需要更改当前站和下一站的状态 然后渲染
//startOrStopQueryPassengerWriteOff(false);
queryBusRoutes();
leaveStationSuccess(backgroundCurrentStationIndex, currentStationName, finalNextStationName);
leaveStationSuccess(backgroundCurrentStationIndex, currentStationName,
finalNextStationName,finalNextStationNameKr);
}
@@ -765,12 +773,12 @@ public class OrderModel {
}
//车站10s后播报
private void leaveTTSTips(String nextStation) {
private void leaveTTSTips(String nextStation,String nextStationKr) {
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
VoiceManager.INSTANCE.leaveStation(nextStation);
VoiceManager.INSTANCE.leaveStation(nextStation,nextStationKr);
}
},DELAY_10S);
}

View File

@@ -1,6 +1,9 @@
package com.mogo.och.bus.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* 查询核销乘客
@@ -21,4 +24,150 @@ public class BusWriteOffPassengersQueryRequest {
public String getSn() {
return sn;
}
/**
* @author: wangmingjun
* @date: 2021/10/19
*/
public static class BusOrdersResponse extends BaseData {
public com.mogo.och.bus.bean.BusOrdersResponse.Result data;
public static class Result{
public List<BusOrderBean> orders;
}
@Override
public String toString() {
return "BusOrdersResponse{" +
"data=" + data +
'}';
}
}
/**
* 网约车小巴路线接口请求响应结果
*
* @author tongchenfei
*/
public static class BusRoutesResponse extends BaseData {
private BusRoutesResult data;
public BusRoutesResult getResult() {
return data;
}
public void setResult(BusRoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "BusRoutesResponse{" +
"data=" + data +
'}';
}
}
/**
* 单个网约车小巴车站信息
*
* @author tongchenfei
*/
public static class BusStationBean {
private int siteId;
private String name;
private int seq;
private double gcjLon; //高德
private double gcjLat; //高德
private double lon; //高精坐标
private double lat; //高精坐标
private int drivingStatus;//行驶信息0初始值1已经过2当前站3未到站
private boolean leaving;
public int getSiteId() {
return siteId;
}
public String getName() {
return name;
}
public int getSeq() {
return seq;
}
public double getGcjLon() {
return gcjLon;
}
public double getGcjLat() {
return gcjLat;
}
public double getLon() {
return lon;
}
public double getLat() {
return lat;
}
public int getDrivingStatus() {
return drivingStatus;
}
public boolean isLeaving() {
return leaving;
}
public void setSiteId(int siteId) {
this.siteId = siteId;
}
public void setName(String name) {
this.name = name;
}
public void setSeq(int seq) {
this.seq = seq;
}
public void setGcjLon(double gcjLon) {
this.gcjLon = gcjLon;
}
public void setGcjLat(double gcjLat) {
this.gcjLat = gcjLat;
}
public void setLon(double lon) {
this.lon = lon;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setDrivingStatus(int drivingStatus) {
this.drivingStatus = drivingStatus;
}
public void setLeaving(boolean leaving) {
this.leaving = leaving;
}
@Override
public String toString() {
return "BusStationBean{" +
"siteId=" + siteId +
", name='" + name + '\'' +
", seq=" + seq +
", gcjLon=" + gcjLon +
", gcjLat=" + gcjLat +
", lon=" + lon +
", lat=" + lat +
", drivingStatus=" + drivingStatus +
", leaving=" + leaving +
'}';
}
}
}

View File

@@ -1,12 +0,0 @@
package com.mogo.och.bus.constant
import com.mogo.commons.debug.DebugConfig
/**
* Created on 2021/12/6
*/
class URLConst {
companion object {
}
}

View File

@@ -14,8 +14,10 @@ data class OrderInfoResponse(val data: OrderInfo?) : BaseData() {
val lineName: String?,//线路名称
var startSiteId: Int?,
var startSiteName: String?,
var startSiteNameKr: String?,
val siteId: Long?,//站点id
val siteName: String?,//站点名称
val siteNameKr: String?,//站点名称
val wgs84Lat: Double?,
val wgs84Lon: Double?,
var gcj02Lat: Double?,

View File

@@ -492,6 +492,7 @@ object CharterPassengerModel {
// 车辆空闲 订单结束已经还车
// 结束车态轮训
endCarStatusLoop()
this.carTypeChageListener?.setCarChangeListener(0)
setOrderStatus(OrderStatusEnum.NoOrderUnuse)
}
}
@@ -548,11 +549,7 @@ object CharterPassengerModel {
AbsMogoApplication.getApp()
.getString(R.string.m1_end_order_5min), 2
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VoiceManager.surplus5min(VoiceFocusManager.getVoiceCmdCallBack())
}else{
VoiceManager.surplus5min()
}
VoiceManager.surplus5min(VoiceFocusManager.getVoiceCmdCallBack())
CallerLogger.d(M_BUS_P+ TAG,"倒计时5分钟${it.orderNo}")
SharedPrefs.getInstance(mContext).putBoolean("${it.orderNo}$min5Speak",true)
}
@@ -858,12 +855,11 @@ object CharterPassengerModel {
mContext, lindId = it, object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
if (null != data && 0 == data.code) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VoiceManager.arrivedStation(orderInfo!!.siteName!!,
VoiceFocusManager.getVoiceCmdCallBack())
}else{
VoiceManager.arrivedStation(orderInfo!!.siteName!!,)
}
VoiceManager.arrivedStation(
orderInfo!!.siteName!!,
orderInfo!!.siteNameKr!!,
VoiceFocusManager.getVoiceCmdCallBack()
)
broadcastList["${it}$endKey"] = true
// 到站结束自驾
CallerAutoPilotControlManager.cancelAutoPilot()
@@ -883,13 +879,12 @@ object CharterPassengerModel {
}
}
fun leaveStation(){
orderInfo?.siteName?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VoiceManager.leaveStation(it,VoiceFocusManager.getVoiceCmdCallBack())
}else{
VoiceManager.leaveStation(it)
fun leaveStation() {
orderInfo?.siteName?.let {cn->
orderInfo?.siteNameKr?.let {kr->
VoiceManager.leaveStation(cn,kr, VoiceFocusManager.getVoiceCmdCallBack())
}
}
}

View File

@@ -53,7 +53,7 @@ class BusPassengerPresenter(view: MainFragment?) :
CharterPassengerModel.setStatusChangeListener(TAG,this)
CallerTelematicListenerManager.addListener(TAG, msgReceived)
OCHPlanningStopSideStatusManager.addListener(TAG,this)
setCarChangeListener(R.raw.aiqinghao)
setCarChangeListener(R.raw.m1)
//BusPassengerModel.setMoGoAutopilotPlanningListener(this)
}
@@ -215,7 +215,7 @@ class BusPassengerPresenter(view: MainFragment?) :
mView?.setCarModle(R.raw.pengyouhao)
}
else -> {
mView?.setCarModle(R.raw.aiqinghao)
mView?.setCarModle(R.raw.m1)
}
}
}

View File

@@ -52,7 +52,6 @@ class MainFragment :
}
override fun initViews() {
setCarModle(R.raw.m1)
cb_bp_video_player.onClick {
openSettingPage(M1ContainFragment.VIDEOTAB)
}

View File

@@ -7,7 +7,7 @@ import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.shuyu.gsyvideoplayer.GSYVideoManager
object VoiceFocusManager {
@RequiresApi(Build.VERSION_CODES.O)
fun getVoiceCmdCallBack():IMogoVoiceCmdCallBack{
UiThreadHandler.post {
GSYVideoManager.onPause()

View File

@@ -57,6 +57,8 @@ dependencies {
implementation rootProject.ext.dependencies.arouter
kapt rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.litezxing
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
api rootProject.ext.dependencies.mogoutils
api rootProject.ext.dependencies.mogocommons

View File

@@ -0,0 +1,117 @@
package com.mogo.och.common.module.utils
import android.graphics.Bitmap
import android.graphics.Canvas
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.common.BitMatrix
import com.google.zxing.qrcode.QRCodeWriter
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import java.util.*
/**
* isDeleteWhite 是否删除白边
*/
fun createQRCode(address: String, width: Int, height: Int,isDeleteWhite: Boolean): Bitmap? {
val hints = Hashtable<EncodeHintType, Any>()
hints[EncodeHintType.CHARACTER_SET] = "utf-8"
hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.H
hints[EncodeHintType.MARGIN] = if (isDeleteWhite) 1 else 0
var bitMatrix = QRCodeWriter().encode(
address,
BarcodeFormat.QR_CODE, width, height, hints
)
if (isDeleteWhite) {
//删除白边
bitMatrix = deleteWhite(bitMatrix)
}
val widthNew = bitMatrix.width
val heightNew = bitMatrix.height
val pixels = IntArray(widthNew * heightNew)
//下面这里按照二维码的算法,逐个生成二维码的图片,
//两个for循环是图片横列扫描的结果
for (y in 0 until heightNew) {
for (x in 0 until widthNew) {
if (bitMatrix.get(x, y)) {
pixels[y * widthNew + x] = -0x1000000
} else {
pixels[y * widthNew + x] = -0x1
}
}
}
//生成二维码图片的格式使用ARGB_8888
var bitmap = Bitmap.createBitmap(widthNew, heightNew, Bitmap.Config.ARGB_8888)
bitmap.setPixels(pixels, 0, widthNew, 0, 0, widthNew, heightNew)
return bitmap
}
/**
* 删除白色边框
*
* @param matrix matrix
* @return BitMatrix
*/
private fun deleteWhite(matrix: BitMatrix): BitMatrix? {
val rec = matrix.enclosingRectangle
val resWidth = rec[2] + 1
val resHeight = rec[3] + 1
val resMatrix = BitMatrix(resWidth, resHeight)
resMatrix.clear()
for (i in 0 until resWidth) {
for (j in 0 until resHeight) {
if (matrix[i + rec[0], j + rec[1]]) resMatrix[i] = j
}
}
return resMatrix
}
fun createQRCodeWithPicture(bmCenter: Bitmap,address: String, width: Int, height: Int,isDeleteWhite: Boolean): Bitmap?{
var qrCode = createQRCode(address,width,height,isDeleteWhite)
//8创建一个bitmap对象用于作为其图标
qrCode?.let {
val resultBitmap = addLogo(it,bmCenter)
if (resultBitmap != null){
return resultBitmap
}
}
return null
}
/**
* 用于向创建的二维码中添加一个logo
* @param bmQr
* @param bmCenter
* @return
*/
fun addLogo(bmQr: Bitmap, bmCenter:Bitmap) :Bitmap?{
if (bmQr == null) {
return null
}
if (bmCenter == null) {
return bmQr
}
//获取图片的宽高
val bmQrWidth = bmQr.width
val bmQrHeight = bmQr.height
val bmCenterWidth = bmCenter.width
val bmCenterHeight = bmCenter.height
var bitmap = Bitmap.createBitmap(bmQrWidth, bmQrHeight, Bitmap.Config.ARGB_8888)
try {
var canvas = Canvas(bitmap)
canvas.drawBitmap(bmQr, 0f, 0f, null)
canvas.drawBitmap(bmCenter, ((bmQrWidth-bmCenterWidth)/2-bmCenterWidth/2).toFloat(),
((bmQrHeight-bmCenterHeight)/2-bmCenterHeight/2).toFloat(), null)
canvas.save()
canvas.restore()
} catch (e: Exception) {
bitmap = null
e.stackTrace
}
return bitmap
}

View File

@@ -10,50 +10,66 @@ import java.util.ArrayList
object VoiceManager {
fun arrivedStation(siteName: String) {
arrivedStation(siteName,null)
fun arrivedStation(siteNameCN: String?) {
arrivedStation(siteNameCN,"")
}
fun arrivedStation(siteName: String,callBack: IMogoTTSCallback?=null) {
fun arrivedStation(siteNameCN: String?,siteNameKR: String?) {
arrivedStation(siteNameCN,siteNameKR,null)
}
fun arrivedStation(siteNameCN: String?, siteNameKR: String?,callBack: IMogoTTSCallback?=null) {
val contenxt = AbsMogoApplication.getApp()
val list: MutableList<LangTtsEntity> = ArrayList()
val chineseTTS = LangTtsEntity(
contenxt.getString(R.string.arrived_station_zh, siteName),
LanguageType.CHINESE
)
val engTTS = LangTtsEntity(
contenxt.getString(R.string.arrived_station_en, siteName),
LanguageType.CHINESE
)
val koreanTTS = LangTtsEntity(
contenxt.getString(R.string.arrived_station_ko, siteName),
LanguageType.KOREAN
)
list.add(chineseTTS)
list.add(engTTS)
list.add(koreanTTS)
siteNameCN?.let {
val chineseTTS = LangTtsEntity(
contenxt.getString(R.string.arrived_station_zh, it),
LanguageType.CHINESE
)
val engTTS = LangTtsEntity(
contenxt.getString(R.string.arrived_station_en, it),
LanguageType.CHINESE
)
val koreanTTS = LangTtsEntity(
contenxt.getString(R.string.arrived_station_ko, siteNameKR?:it),
LanguageType.KOREAN
)
list.add(chineseTTS)
list.add(engTTS)
list.add(koreanTTS)
}
VoiceNotice.showNotice(list, AIAssist.LEVEL1,callBack)
}
fun leaveStation(siteName: String){
leaveStation(siteName,null)
fun leaveStation(siteNameCN: String?){
leaveStation(siteNameCN,"")
}
fun leaveStation(siteName: String,callBack: IMogoTTSCallback?=null) {
val contenxt = AbsMogoApplication.getApp()
fun leaveStation(siteNameCN: String?,siteNameKR: String?){
leaveStation(siteNameCN,siteNameKR,null)
}
fun leaveStation(siteNameCN: String?, siteNameKR: String?,callBack: IMogoTTSCallback?=null) {
val list: MutableList<LangTtsEntity> = ArrayList()
val chineseTTS = LangTtsEntity(
contenxt.getString(R.string.leave_station_zh, siteName),
LanguageType.CHINESE
)
val engTTS = LangTtsEntity(
contenxt.getString(R.string.leave_station_en, siteName),
LanguageType.CHINESE
)
val koreanTTS = LangTtsEntity(
contenxt.getString(R.string.leave_station_ko, siteName),
LanguageType.KOREAN
)
list.add(chineseTTS)
list.add(engTTS)
list.add(koreanTTS)
val contenxt = AbsMogoApplication.getApp()
siteNameCN?.let {
val chineseTTS = LangTtsEntity(
contenxt.getString(R.string.leave_station_zh, it),
LanguageType.CHINESE
)
val engTTS = LangTtsEntity(
contenxt.getString(R.string.leave_station_en, it),
LanguageType.CHINESE
)
list.add(chineseTTS)
list.add(engTTS)
val koreanTTS = LangTtsEntity(
contenxt.getString(R.string.leave_station_ko, siteNameKR ?: it),
LanguageType.KOREAN
)
list.add(koreanTTS)
}
VoiceNotice.showNotice(list, AIAssist.LEVEL1,callBack)
}

View File

@@ -0,0 +1,76 @@
package com.mogo.och.common.module.wigets
import android.content.Context
import android.graphics.Bitmap
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.och.common.module.R
/**
* 带有title, tip,confirm,cancel的dialog
*/
class BindQRCodeDialog: BaseFloatDialog, LifecycleObserver {
private var qrBm : AppCompatImageView? = null
private var qrCancel: AppCompatTextView? = null
private var qrTitle: AppCompatTextView? = null
private var clickListener: ClickListener? = null
constructor(builder: Builder,context: Context) : super(context) {
qrTitle?.text = builder.titleStr
qrCancel?.text = builder.cancelStr
qrBm?.setImageBitmap(builder.qrBm)
}
init{
setContentView(R.layout.bind_driver_qr_view)
setCanceledOnTouchOutside(true)
qrTitle = findViewById(R.id.qr_title)
qrBm = findViewById(R.id.qr_bm)
qrCancel = findViewById(R.id.bind_qr_cancel)
qrCancel?.setOnClickListener {
clickListener?.cancel()
dismiss()
}
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
interface ClickListener{
fun cancel()
}
class Builder{
var titleStr:String = ""
var cancelStr:String = ""
var qrBm: Bitmap? = null
fun title(title: String) : Builder{
this.titleStr = title
return this
}
fun cancelStr(cancel: String) : Builder{
this.cancelStr = cancel
return this
}
fun qrBm(bm: Bitmap) : Builder{
this.qrBm = bm
return this
}
fun build(context: Context): BindQRCodeDialog? {
return BindQRCodeDialog(this,context)
}
}
}

View File

@@ -49,13 +49,6 @@ class OCHCommitDialog: BaseFloatDialog, LifecycleObserver {
this.clickListener = clickListener
}
fun showUpgradeDialog(){
if(isShowing){
return
}
show()
}
interface ClickListener{
fun confirm()
fun cancel()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_32"/>
<solid android:color="@color/qr_bg_color"/>
</shape>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/dp_890"
android:layout_height="@dimen/dp_780"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:ignore="MissingDefaultResource"
android:background="@drawable/bind_driver_qr_bg">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/qr_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bind_driver_qr_title"
android:gravity="center"
android:textSize="@dimen/dp_56"
android:layout_marginTop="@dimen/dp_48"
android:textColor="@android:color/white"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/qr_bm"
android:layout_width="@dimen/dp_357"
android:layout_height="@dimen/dp_357"
android:padding="8dp"
android:background="@android:color/white"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/qr_title"
app:layout_constraintBottom_toTopOf="@+id/line"/>
<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="@color/qr_line_bg_color"
app:layout_constraintBottom_toTopOf="@+id/bind_qr_cancel"
app:layout_constraintLeft_toLeftOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/bind_qr_cancel"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_162"
android:gravity="center"
android:text="@string/qr_cancel"
android:textSize="@dimen/dp_52"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textColor="@android:color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -11,4 +11,7 @@
<color name="taxi_4D000000">#4D000000</color>
<color name="och_dialog_bg_color">#3B4577</color>
<color name="qr_line_bg_color">#66B8BFE8</color>
<color name="qr_bg_color">#3B4577</color>
</resources>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="module_och_taxi_login_title">欢迎您登录</string>
<string name="module_och_taxi_login_btn">登录</string>
@@ -17,7 +17,7 @@
<string name="arrived_station_en">We are arriving at %1$s</string>
<string name="arrived_station_ko">%1$s 역에 도착했습니다</string>
<string name="arrived_station_zh">已到达%1$s</string>
<string name="arrived_station_zh">已到达%1$s</string>
<string name="leave_station_zh">车辆起步,请扶稳坐好,前方到站 %1$s</string>
<string name="leave_station_en">The next station is %1$s</string>
@@ -30,4 +30,7 @@
<string name="end_order_zh">感谢您体验\'蘑菇车联\'自动驾驶小巴车,本次旅程已结束,我们下次乘车再见</string>
<string name="end_order_en">Thank you for experiencing the self-driving minibus. See you next time</string>
<string name="end_order_ko">자율주행 버스를 체험해 주셔서 감사합니다. 다음에 또 뵙겠습니다</string>
<string name="qr_cancel">取消</string>
<string name="bind_driver_qr_title">扫描二维码完成车辆绑定</string>
</resources>

View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,15 @@
src
- androidTest Android 测试代码
- basecommon 金旅开沃、接驳车 公用代码部分
- jinlvvan 金旅开沃 独立代码部分
- m1 金旅m1 独立代码部分
- m2 金旅m2 独立代码部分
- main 所有车型公用代码部分
- shuttle 接驳车独立代码 因为接驳车和金旅开沃代码耦合厉害暂时放入到mogo-och-bus-passenger里面
后期会创建独立module和mogo-och-bus-passenger平级
- test 普通代码测试

View File

@@ -0,0 +1,83 @@
apply plugin: 'com.android.library'
apply plugin: 'com.alibaba.arouter'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
// buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode Integer.valueOf(VERSION_CODE)
versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
kapt {
useBuildCache = false
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "vehicle"
productFlavors {
// 车型:金旅星辰、开沃 小巴业务
jinlvvan {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '0'
}
// 车型金旅m1 小巴业务
m1 {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '1'
}
// 车型金旅m1 小巴业务
m2 {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '1'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.arouter
implementation rootProject.ext.dependencies.androidxrecyclerview
implementation rootProject.ext.dependencies.material
kapt rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.amapnavi3dmap
implementation project(":OCH:mogo-och-common-module")
compileOnly project(":libraries:mogo-map")
implementation project(':core:mogo-core-res')
testImplementation 'junit:junit:4.12'
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.och
POM_ARTIFACT_ID=och-bus-passenger
VERSION_CODE=1

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,26 @@
package com.mogo.och.bus.passenger;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.mogo.och.bus.passenger.test", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,96 @@
package com.mogo.och.bus.passenger;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI_P;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.MultiDisplayUtils;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import com.mogo.och.common.module.wigets.video.VideoPlayerActivity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* 网约车-Bus-乘客端
*
* Created on 2022/3/29
*/
@Route(path = BusPassengerConst.PATH)
public class MogoOCHBusPassenger implements IMogoOCH {
private static final String TAG = MogoOCHBusPassenger.class.getSimpleName();
private FragmentActivity mActivity;
private int mContainerId;
private BusPassengerRouteFragment mPassengerFragment;
@Override
public void createCoverage(FragmentActivity activity, int containerId) {
}
@Nullable
@Override
public Fragment createCoverage(@Nullable FragmentActivity activity, @Nullable Integer containerId) {
this.mActivity = activity;
this.mContainerId = containerId;
showFragment();
if (AppIdentityModeUtils.isJL(FunctionBuildConfig.appIdentityMode)) {
MultiDisplayUtils.INSTANCE.startActWithSecond(activity, VideoPlayerActivity.class);
}
return null;
}
@NotNull
@Override
public String getFunctionName() {
return null;
}
@Override
public void onDestroy() {
// 若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
if (mActivity == null) return;
mActivity.finish();
}
@Override
public void init(Context context) {
}
/**
* 进入鹰眼模式,设置手势缩放地图失效
*/
private void stepIntoVrMode() {
CallerLogger.INSTANCE.d( M_TAXI_P + TAG, "进入vr模式" );
CallerMoGoUiSettingManager.INSTANCE.stepInDayMode();//白天模式 状态栏字体颜色变黑
}
private void showFragment() {
if (mPassengerFragment == null) {
CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "准备add fragment======");
mPassengerFragment = new BusPassengerRouteFragment();
mActivity.getSupportFragmentManager().beginTransaction().add(mContainerId, mPassengerFragment).commitAllowingStateLoss();
return;
}
CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "准备show fragment");
mActivity.getSupportFragmentManager().beginTransaction().show(mPassengerFragment).commitAllowingStateLoss();
}
private void hideFragment(){
if (mPassengerFragment != null){
mActivity.getSupportFragmentManager().beginTransaction().hide(mPassengerFragment).commitAllowingStateLoss();
}
}
}

View File

@@ -0,0 +1,131 @@
package com.mogo.och.bus.passenger.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.Group;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.common.module.utils.BlinkAnimationUtil;
import com.mogo.och.common.module.wigets.MarqueeTextView;
import java.util.List;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_ARRIVING;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_LEAVING;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_STOPPED;
/**
* @author: wangmingjun
* @date: 2022/4/6
*/
public class BusPassengerLineStationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<BusPassengerStation> mStations;
public BusPassengerLineStationsAdapter(Context context, List<BusPassengerStation> stations){
this.mContext = context;
this.mStations = stations;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.bus_p_stations_common_item,parent,false);
StationViewHolder viewHolder = new StationViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
BusPassengerStation station = mStations.get(position);
StationViewHolder viewHolder = (StationViewHolder)holder;
viewHolder.stationName.setText(station.getName());
BlinkAnimationUtil.clearAnimation(viewHolder.stationCircle);
if (position == 0){ //第一个 起点
viewHolder.stationTagTxt.setText("");
viewHolder.stationStationTag.setBackground(mContext.getDrawable(R.drawable.bg_bus_p_start_tag_bg));
viewHolder.groupStationTagPanel.setVisibility(View.VISIBLE);
viewHolder.curArrowBg.setVisibility(View.GONE);
if (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving()){//到达未离开
viewHolder.stationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_current_station_txt_color));
viewHolder.stationCircle.setImageResource(R.drawable.bus_p_point_green);
BlinkAnimationUtil.setAnimation(viewHolder.stationCircle);
viewHolder.stationName.setEllipsize(TextUtils.TruncateAt.MARQUEE);
}else {
viewHolder.stationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_station_txt_color));
viewHolder.stationCircle.setImageResource(R.drawable.bus_p_point_gray);
viewHolder.stationName.setEllipsize(TextUtils.TruncateAt.END);
}
}else{
if (position == mStations.size() - 1){
viewHolder.stationTagTxt.setText("");
viewHolder.stationStationTag.setBackground(mContext.getDrawable(R.drawable.bg_bus_p_end_tag_bg));
viewHolder.groupStationTagPanel.setVisibility(View.VISIBLE);
}else {
viewHolder.groupStationTagPanel.setVisibility(View.GONE);
}
viewHolder.curArrowBg.setVisibility(View.VISIBLE);
BusPassengerStation preStation = mStations.get(position -1);
if (station.getDrivingStatus() == STATION_STATUS_LEAVING ||
(station.getDrivingStatus() == STATION_STATUS_STOPPED && station.isLeaving())){ //过站
viewHolder.stationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_station_txt_color));
viewHolder.curArrowBg.setImageResource(R.drawable.bus_p_line_grey);
viewHolder.stationCircle.setImageResource(R.drawable.bus_p_point_gray);
viewHolder.stationName.setEllipsize(TextUtils.TruncateAt.END);
} else if (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving()){//刚到站未离开的
viewHolder.stationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_current_station_txt_color));
viewHolder.curArrowBg.setImageResource(R.drawable.bus_p_line_grey);
viewHolder.stationCircle.setImageResource(R.drawable.bus_p_point_green);
BlinkAnimationUtil.setAnimation(viewHolder.stationCircle);
viewHolder.stationName.setEllipsize(TextUtils.TruncateAt.MARQUEE);
}else if (station.getDrivingStatus() == STATION_STATUS_ARRIVING && preStation.isLeaving()){//即将到站
viewHolder.stationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_current_station_txt_color));
viewHolder.curArrowBg.setImageResource(R.drawable.bus_p_line_green);
viewHolder.stationCircle.setImageResource(R.drawable.bus_p_point_green);
BlinkAnimationUtil.setAnimation(viewHolder.stationCircle);
viewHolder.stationName.setEllipsize(TextUtils.TruncateAt.MARQUEE);
}else if (station.getDrivingStatus() == STATION_STATUS_ARRIVING &&
(preStation.getDrivingStatus() == STATION_STATUS_ARRIVING
|| preStation.getDrivingStatus() == STATION_STATUS_STOPPED)){ //未到站的并且前面也是未到站或者刚到站的
viewHolder.stationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_station_txt_color));
viewHolder.curArrowBg.setImageResource(R.drawable.bus_p_line_blue);
viewHolder.stationCircle.setImageResource(R.drawable.bus_p_point_blue);
viewHolder.stationName.setEllipsize(TextUtils.TruncateAt.END);
}
}
}
@Override
public int getItemCount() {
return mStations.size();
}
}
class StationViewHolder extends RecyclerView.ViewHolder{
public MarqueeTextView stationName;
public ImageView stationCircle;
public ImageView curArrowBg;
public ImageView stationStationTag;
public TextView stationTagTxt;
public Group groupStationTagPanel;
public StationViewHolder(@NonNull View itemView) {
super(itemView);
stationName = itemView.findViewById(R.id.bus_p_station);
stationCircle = itemView.findViewById(R.id.bus_p_circle);
curArrowBg = itemView.findViewById(R.id.bus_p_cur_arrow_bg);
stationStationTag = itemView.findViewById(R.id.bus_p_tag);
stationTagTxt = itemView.findViewById(R.id.bus_p_tag_txt);
groupStationTagPanel = itemView.findViewById(R.id.group_station_tag_panel);
}
}

View File

@@ -0,0 +1,21 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态返回参数
*/
public class BusPassengerOperationStatusResponse extends BaseData {
public Result data;
public static class Result {
private String sn; //司机屏sn
private String phone; //司机手机号
public String plateNumber; //车牌号
public int driverStatus;//0:已收车1:已出车
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.bean;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
class BusPassengerQueryLineRequest {
private String sn;
public BusPassengerQueryLineRequest(String sn) {
this.sn = sn;
}
}

View File

@@ -0,0 +1,28 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* 网约车小巴路线接口请求响应结果 返回的是对应司机屏的线路信息
*
* @author tongchenfei
*/
public class BusPassengerRoutesResponse extends BaseData {
private BusPassengerRoutesResult data;
public BusPassengerRoutesResult getResult() {
return data;
}
public void setResult(BusPassengerRoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "OchBusRoutesResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -0,0 +1,79 @@
package com.mogo.och.bus.passenger.bean;
import java.util.List;
import java.util.Objects;
/**
* 网约车小巴路线接口返回接口数据封装
*
* @author tongchenfei
*/
public class BusPassengerRoutesResult {
private List<BusPassengerStation> sites;
private int lineId;
private String name; //线路名称
private int lineType; //线路类型0:环形
private String description;
private int status;
private String runningDur; //运营时间
private long taskTime; //线路时间班次
public List<BusPassengerStation> getSites() {
return sites;
}
public int getLineId() {
return lineId;
}
public String getName() {
return name;
}
public int getLineType() {
return lineType;
}
public String getDescription() {
return description;
}
public int getStatus() {
return status;
}
public String getRunningDur() {
return runningDur;
}
@Override
public String toString() {
return "BusPassengerRoutesResult{" +
"sites=" + sites +
", lineId=" + lineId +
", name='" + name + '\'' +
", lineType=" + lineType +
", description='" + description + '\'' +
", status=" + status +
", runningDur='" + runningDur + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BusPassengerRoutesResult that = (BusPassengerRoutesResult) o;
return lineId == that.lineId
&& lineType == that.lineType
&& status == that.status
&& sites.equals(that.sites)
&& name.equals(that.name)
&& runningDur.equals(that.runningDur);
}
@Override
public int hashCode() {
return Objects.hash(sites, lineId, name, lineType, description, status, runningDur);
}
}

View File

@@ -0,0 +1,173 @@
package com.mogo.och.bus.passenger.bean;
import java.util.Objects;
/**
* 单个网约车小巴车站信息
*
* @author wangmingjun
*/
public class BusPassengerStation {
private String name;
private String description;
private String cityCode;
private double lon; //高精坐标
private double lat; //高精坐标
private double gcjLon; //高德坐标
private double gcjLat; //高德坐标
private int businessType; //站点类型9:taxi10:bus
private int status;
private int siteId;
private int seq;
private int drivingStatus;//行驶信息0初始值1已经过2当前站3未到站
private int ifStop = 1; // 是否需要停靠、1需要、0不需要 // TODO: 2021/10/19 原来站点里有设计是否需要停靠字段,现设计暂无,默认都需要停靠
private boolean leaving;
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public void setLon(double lon) {
this.lon = lon;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setBusinessType(int businessType) {
this.businessType = businessType;
}
public void setStatus(int status) {
this.status = status;
}
public void setSiteId(int siteId) {
this.siteId = siteId;
}
public void setSeq(int seq) {
this.seq = seq;
}
public void setDrivingStatus(int drivingStatus) {
this.drivingStatus = drivingStatus;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getCityCode() {
return cityCode;
}
public double getGcjLon() {
return gcjLon;
}
public double getGcjLat() {
return gcjLat;
}
public int getBusinessType() {
return businessType;
}
public int getStatus() {
return status;
}
public int getSiteId() {
return siteId;
}
public int getSeq() {
return seq;
}
public int getDrivingStatus() {
return drivingStatus;
}
public double getLon() {
return lon;
}
public double getLat() {
return lat;
}
public void setIfStop(int ifStop) {
this.ifStop = ifStop;
}
public int getIfStop() {
return ifStop;
}
public void setLeaving(boolean leaving) {
this.leaving = leaving;
}
public boolean isLeaving() {
return leaving;
}
@Override
public String toString() {
return "OchBusStation{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
", cityCode='" + cityCode + '\'' +
", lon=" + lon +
", lat=" + lat +
", businessType=" + businessType +
", status=" + status +
", siteId=" + siteId +
", seq=" + seq +
", drivingStatus=" + drivingStatus +
", ifStop=" + ifStop +
", leaving=" + leaving +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BusPassengerStation that = (BusPassengerStation) o;
return Double.compare(that.lon, lon) == 0
&& Double.compare(that.lat, lat) == 0
&& Double.compare(that.gcjLon, gcjLon) == 0
&& Double.compare(that.gcjLat, gcjLat) == 0
&& businessType == that.businessType
&& status == that.status
&& siteId == that.siteId
&& seq == that.seq
&& drivingStatus == that.drivingStatus
&& ifStop == that.ifStop
&& leaving == that.leaving
&& Objects.equals(name, that.name)
&& Objects.equals(cityCode, that.cityCode);
}
@Override
public int hashCode() {
return Objects.hash(name, description, cityCode, lon, lat, gcjLon, gcjLat, businessType, status, siteId, seq, drivingStatus, ifStop, leaving);
}
}

View File

@@ -0,0 +1,10 @@
package com.mogo.och.bus.passenger.callback;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface IBusPassegerDriverStatusCallback {
void changeOperationStatus(boolean changeStatus);
void updatePlateNumber(String plateNumber);
}

View File

@@ -0,0 +1,20 @@
package com.mogo.och.bus.passenger.callback;
/**
* Created on 2022/3/31
*
* Model->Presenter回调ADAS相关自动驾驶状态回调到达终点等等
*/
public interface IBusPassengerADASStatusCallback {
// 自动驾驶触发的已到达目的地:暂未用到
void onAutopilotArriveEnd();
// 自动驾驶可用状态
void onAutopilotEnable();
// 自动驾驶不可用状态
void onAutopilotDisable();
// 自动驾驶运行中
void onAutopilotRunning();
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.callback;
import com.amap.api.maps.model.LatLng;
import java.util.List;
import mogo.telematics.pad.MessagePad;
/**
* Created on 2022/3/31
*/
public interface IBusPassengerAutopilotPlanningCallback {
void routeResult(List<LatLng> models,int haveArrivedIndex);
void routePlanningToNextStationChanged(long meters, long timeInSecond);
void updateTotalDistance();
}

View File

@@ -0,0 +1,15 @@
package com.mogo.och.bus.passenger.callback;
import com.mogo.eagle.core.data.map.MogoLocation;
/**
* Created on 2022/3/31
*
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface IBusPassengerControllerStatusCallback {
// 是否vr map模式
void onVRModeChanged(boolean isVRMode);
// 自车定位
void onCarLocationChanged(MogoLocation location);
}

View File

@@ -0,0 +1,9 @@
package com.mogo.och.bus.passenger.callback;
/**
* @author: wangmingjun
* @date: 2022/3/10
*/
public interface IBusPassengerMapViewCallback {
void onCameraChange(float bearing);
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.callback;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/4/6
*/
public interface IBusPassengerRouteLineInfoCallback {
void updateLineInfo(String lineName, String lineDurTime);
void updateStationsInfo(List<BusPassengerStation> stations, int currentStationIndex, boolean isArrived);
void showNoTaskView();
void hideNoTaskView();
}

View File

@@ -0,0 +1,580 @@
package com.mogo.och.bus.passenger.model;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.QUERY_BUS_P_STATION_DELAY;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_STOPPED;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amap.api.maps.model.LatLng;
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.module.intent.IMogoIntentListener;
import com.mogo.commons.module.intent.IntentManager;
import com.mogo.commons.module.status.IMogoStatusChangedListener;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.module.status.StatusDescriptor;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResult;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.bus.passenger.callback.IBusPassegerDriverStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerADASStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerAutopilotPlanningCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerControllerStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerRouteLineInfoCallback;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.network.BusPassengerModelLoopManager;
import com.mogo.och.bus.passenger.network.BusPassengerServiceManager;
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback;
import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager;
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import system_master.SystemStatusInfo;
/**
* Created on 2022/3/31
*/
public class BusPassengerModel {
private static final String TAG = BusPassengerModel.class.getSimpleName();
private List<MogoLocation> mRoutePoints = new ArrayList<>();
private static final class SingletonHolder {
private static final BusPassengerModel INSTANCE = new BusPassengerModel();
}
public static BusPassengerModel getInstance() {
return SingletonHolder.INSTANCE;
}
private Context mContext;
private IBusPassengerADASStatusCallback mADASStatusCallback; //Model->Presenter自动驾驶状态相关
private IBusPassengerAutopilotPlanningCallback mAutopilotPlanningCallback; //Model->Presenter自动驾驶线路规划
private Map<String, IBusPassengerControllerStatusCallback> mControllerStatusCallbackMap = new ConcurrentHashMap<>();
private IBusPassegerDriverStatusCallback mDriverStatusCallback; //出车收车状态
private IBusPassengerRouteLineInfoCallback mRouteLineInfoCallback; // bus路线信息更新
private MogoLocation mLocation = null;
private BusPassengerRoutesResult routesResult = null;
List<BusPassengerStation> mStations = new ArrayList<>();
private int mNextStationIndex = 0;// 要到达站的index
private List<MogoLocation> mTwoStationsRouts = new ArrayList<>();
private int mPreRouteIndex = 0;
private int mWipePreIndex = 0;
private static final int MSG_QUERY_BUS_P_STATION = 1001;
private final Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if ( msg.what == MSG_QUERY_BUS_P_STATION ) {
queryDriverOperationStatus();
return true;
}
return false;
}
});
private BusPassengerModel() {
}
public void init( Context context ) {
mContext = context.getApplicationContext();
initListeners();
// TODO: 2022/3/31
queryDriverOperationStatus();
startOrStopOrderLoop(true);
}
public void setDriverStatusCallback(IBusPassegerDriverStatusCallback callback){
this.mDriverStatusCallback = callback;
}
public void setRouteLineInfoCallback(IBusPassengerRouteLineInfoCallback callback){
this.mRouteLineInfoCallback = callback;
}
private void queryDriverOperationDelay() {
handler.sendEmptyMessageDelayed( MSG_QUERY_BUS_P_STATION, QUERY_BUS_P_STATION_DELAY );
}
private void queryDriverOperationStatus() {
BusPassengerServiceManager.queryDriverOperationStatus(mContext
, new OchCommonServiceCallback<BusPassengerOperationStatusResponse>() {
@Override
public void onSuccess(BusPassengerOperationStatusResponse data) {
if (data == null || data.data == null) return;
if (mDriverStatusCallback != null) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverOperationStatus = %s", data.data.plateNumber );
mDriverStatusCallback.changeOperationStatus(data.data.driverStatus == 1);
mDriverStatusCallback.updatePlateNumber(data.data.plateNumber);
}
}
@Override
public void onError() {
if (!NetworkUtils.isConnected(mContext)) {
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
} else {
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
}
queryDriverOperationDelay();
}
@Override
public void onFail(int code, String msg) {
//延迟3s再次查询
queryDriverOperationDelay();
}
});
}
public void queryDriverSiteByCoordinate(){
BusPassengerServiceManager.queryDriverSiteByCoordinate(mContext
, new OchCommonServiceCallback<BusPassengerRoutesResponse>() {
@Override
public void onSuccess(BusPassengerRoutesResponse data) {
if ( data == null || data.getResult() == null) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = null");
if (routesResult != null) {
routesResult = null;
mNextStationIndex = 0;
startOrStopCalculateRouteInfo(false);
if (mRouteLineInfoCallback != null){
mRouteLineInfoCallback.showNoTaskView();
}
}
return;
}
if (routesResult != null && data.getResult().equals(routesResult)){
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = not update");
return;
}
routesResult = data.getResult();
updatePassengerRouteInfo(data.getResult());
}
@Override
public void onFail(int code, String msg) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = %s", msg
+ ", sn = " +BusPassengerServiceManager.INSTANCE.getDriverAppSn());
if (code == 1003){
queryDriverOperationDelay();
}
if (BusPassengerServiceManager.INSTANCE.getDriverAppSn().isEmpty()){
//此处拦截是为了防止过程中乘客屏和司机端断连拿不到司机端sn, 造成请求失败去刷新了界面
return;
}
if (code == 1003){
routesResult = null;
startOrStopCalculateRouteInfo(false);
return;
}
}
});
}
private void updatePassengerRouteInfo(BusPassengerRoutesResult result) {
if (mRouteLineInfoCallback != null){
mRouteLineInfoCallback.updateLineInfo(result.getName(),result.getRunningDur());
mRouteLineInfoCallback.hideNoTaskView();
if (result.getSites() != null){
List<BusPassengerStation> stations = result.getSites();
mStations.clear();
mStations.addAll(stations);
for (int i = 0; i< stations.size(); i++){
BusPassengerStation station = stations.get(i);
if (station.getDrivingStatus() == STATION_STATUS_STOPPED && station.isLeaving() && i+1 < stations.size()){
mRouteLineInfoCallback.updateStationsInfo(stations,i+1,false);
if(mNextStationIndex != i+1){
mTwoStationsRouts.clear();
startRemainRouteInfo();
}
mNextStationIndex = i+1;
return;
}else if (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving()){
if (i == 0){
startOrStopRouteAndWipe(false);
}
mPreRouteIndex = 0;
startOrStopCalculateRouteInfo(false);
mRouteLineInfoCallback.updateStationsInfo(stations,i,true);
return;
}
}
}
}
}
public void release() {
releaseListeners();
startOrStopCalculateRouteInfo(false);
startOrStopOrderLoop(false);
}
public void setMoGoAutopilotPlanningListener(IBusPassengerAutopilotPlanningCallback
moGoAutopilotPlanningCallback) {
this.mAutopilotPlanningCallback = moGoAutopilotPlanningCallback;
}
public void setADASStatusCallback(IBusPassengerADASStatusCallback callback) {
this.mADASStatusCallback = callback;
}
public void setControllerStatusCallback(String tag, IBusPassengerControllerStatusCallback callback) {
if (tag == null || "".equals(tag)) return;
if (callback == null) {
mControllerStatusCallbackMap.remove(tag);
return;
}
mControllerStatusCallbackMap.put(tag,callback);
}
private void initListeners() {
// 2021.11.1重构自动驾驶 实现接口 IMoGoAutopilotStatusListener 注册监听 替换IMogoAdasOCHCallback接口
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener);
IntentManager.getInstance().registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener );
MogoStatusManager.getInstance().registerStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener );
// 定位监听
CallerChassisLocationGCJ02ListenerManager.INSTANCE.addListener(TAG, mMapLocationListener);
//2021.11.1 自动驾驶路线规划接口
CallerPlanningRottingListenerManager.INSTANCE.addListener(TAG,moGoAutopilotPlanningListener);
AbnormalFactorsLoopManager.INSTANCE.startLoopAbnormalFactors(mContext);
}
private void releaseListeners() {
MogoStatusManager.getInstance().unregisterStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
// 注销定位监听
CallerChassisLocationGCJ02ListenerManager.INSTANCE.removeListener(TAG);
MogoAiCloudSocketManager.getInstance(mContext)
.unregisterLifecycleListener(10010);
CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(mGoAutopilotStatusListener);
CallerPlanningRottingListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
AbnormalFactorsLoopManager.INSTANCE.stopLoopAbnormalFactors();
}
//监听网络变化,避免启动机器时无网导致无法更新订单信息
private final IMogoIntentListener mNetWorkIntentListener = new IMogoIntentListener() {
@Override
public void onIntentReceived( String intentStr, Intent intent ) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "onIntentReceived = %s", intentStr );
if ( ConnectivityManager.CONNECTIVITY_ACTION.equals( intentStr ) ) {
if ( NetworkUtils.isConnected( mContext ) ) {
queryDriverOperationStatus();
}
}
}
};
// VR mode变更回调
private final IMogoStatusChangedListener mMogoStatusChangedListener = (descriptor, isTrue) -> {
if (StatusDescriptor.VR_MODE == descriptor) {
if (mControllerStatusCallbackMap.size() > 0) {
for (IBusPassengerControllerStatusCallback callback :mControllerStatusCallbackMap.values()){
callback.onVRModeChanged(isTrue);
}
}
}
};
private final IMoGoChassisLocationGCJ02Listener mMapLocationListener = new IMoGoChassisLocationGCJ02Listener() {
@Override
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
if (null == gnssInfo) return;
mLocation = gnssInfo;
for (IBusPassengerControllerStatusCallback callback :mControllerStatusCallbackMap.values()){
callback.onCarLocationChanged(gnssInfo);
}
}
};
private volatile int mPreAutoStatus = -1;
private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener(){
@Override
public void onAutopilotRouteLineId(long lineId) {
}
@Override
public void onAutopilotIpcConnectStatusChanged(int status, @Nullable String reason) {
}
@Override
public void onAutopilotGuardian(@Nullable MogoReportMsg.MogoReportMessage guardianInfo) {
}
private boolean arriveAtEnd = false; //乘客app专用字段
@Override
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autopilotStatusInfo) {
if (autopilotStatusInfo == null) return;
int state = autopilotStatusInfo.getState();
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
//2022.7.20 自动驾驶更换成带档位的
// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotRunning();
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
if(state != mPreAutoStatus){
mTwoStationsRouts.clear();
}
// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotEnable();
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
if(state != mPreAutoStatus){
mTwoStationsRouts.clear();
}
// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotDisable();
}else if (state == IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING){
if(state != mPreAutoStatus){
mTwoStationsRouts.clear();
}
}
mPreAutoStatus = state;
}
@Override
public void onAutopilotSNRequest() {
}
@Override
public void onAutopilotArriveAtStation(@Nullable MessagePad.ArrivalNotification arrivalNotification) {
if (FunctionBuildConfig.isDemoMode
&& AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
arriveAtEnd = true;
}
// TODO: 2022/3/31
if (DebugConfig.isDebug()) {
// ToastUtils.showShort("到达目的地");
}
if (mADASStatusCallback != null){
mADASStatusCallback.onAutopilotArriveEnd();
}
}
@Override
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
}
};
private final IMoGoPlanningRottingListener moGoAutopilotPlanningListener = new IMoGoPlanningRottingListener(){
@Override
public void onAutopilotRotting(@Nullable MessagePad.GlobalPathResp routeList) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "onAutopilotRotting = "
+ GsonUtil.jsonFromObject(routeList));
List<MessagePad.Location> routePoints = routeList.getWayPointsList();
if (null != routePoints && routePoints.size() > 0){
updateRoutePoints(routePoints);
startToRouteAndWipe();
}
}
};
public void updateRoutePoints(List<MessagePad.Location> routePoints){
mRoutePoints.clear();
List<MogoLocation> latLngModels = CoordinateCalculateRouteUtil
.coordinateConverterWgsToGcjLocations(mContext,routePoints);
mRoutePoints.addAll(latLngModels);
calculateTwoStationsRoute();
}
private void calculateTwoStationsRoute(){
//找出前往站对应的轨迹点,拿出两站点的集合
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "mRoutePoints.size() = " + mRoutePoints.size());
if (mRoutePoints.size() > 0) {
if (mStations.size() > 1){ //两个站点及以上要计算两个站点间的轨迹路线
if (mNextStationIndex <= mStations.size()-1 && mNextStationIndex - 1 >=0){
mTwoStationsRouts.clear();
BusPassengerStation stationNext = mStations.get(mNextStationIndex);
BusPassengerStation stationCur = mStations.get(mNextStationIndex - 1);
//当前站在轨迹中对应的点
int currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(0
,mRoutePoints
,stationCur.getGcjLon(),stationCur.getGcjLat());
//要前往的站在轨迹中对应的点
int nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(currentRouteIndex
,mRoutePoints
,stationNext.getGcjLon(),stationNext.getGcjLat());
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "轨迹排查==currentRouteIndex = " + currentRouteIndex
+ " nextRouteIndex = " + nextRouteIndex);
if (currentRouteIndex < nextRouteIndex){ //如果找到的next在起点的轨迹前面直接舍弃这个轨迹不显示
mTwoStationsRouts.addAll(mRoutePoints.subList(currentRouteIndex,nextRouteIndex + 1));
}
}
}
// else { //只有两个站点的时候整个路线就是两个站点之间的轨迹
// mTwoStationsRouts.clear();
// mTwoStationsRouts.addAll(mRoutePoints);
// }
if (mTwoStationsRouts.size() > 0){
float sumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(mTwoStationsRouts);
SharedPrefsMgr.getInstance(mContext).putInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,(int) sumLength);
if (mAutopilotPlanningCallback != null){
mAutopilotPlanningCallback.updateTotalDistance();
}
}
}
}
public void dynamicCalculateRouteInfo() {
//计算当前位置和下一站的剩余点集合
//计算剩余点总里程和时间
if (mTwoStationsRouts.size() == 0){
calculateTwoStationsRoute();
}
if (mTwoStationsRouts.size() > 0 && mLocation != null){
Map<Integer,List<MogoLocation>> lastPointsMap = CoordinateCalculateRouteUtil
.getRemainPointListByCompareNew(mPreRouteIndex,mTwoStationsRouts,mLocation);
for (int index: lastPointsMap.keySet()) {
mPreRouteIndex = index;
break;
}
for (List<MogoLocation> lastPoints: lastPointsMap.values()){
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "轨迹排查==lastPoints.size() = " + lastPoints.size());
float lastSumLength = 0;
if (lastPoints.size() == 1){ //只是最后一个点,计算当前位置和最后一个点的距离
if (mNextStationIndex <= mStations.size()-1 && mNextStationIndex >= 0){
BusPassengerStation stationNext = mStations.get(mNextStationIndex);
lastSumLength = CoordinateUtils.calculateLineDistance(
stationNext.getGcjLon(), stationNext.getGcjLat(),
mLocation.getLongitude(), mLocation.getLatitude());
}else {
lastSumLength = CoordinateUtils.calculateLineDistance(
lastPoints.get(0).getLongitude(), lastPoints.get(0).getLatitude(),
mLocation.getLongitude(), mLocation.getLatitude());
}
}else {
lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints);
}
double lastTime = lastSumLength / getAverageSpeed() * 3.6 ; //秒
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "轨迹排查==lastSumLength = " + lastSumLength);
if (mAutopilotPlanningCallback != null){
mAutopilotPlanningCallback.routePlanningToNextStationChanged((long)lastSumLength,(long) lastTime);
}
}
}
}
public int getAverageSpeed(){
return BusPassengerConst.SHUTTLE_AVERAGE_SPEED;
}
public void startRemainRouteInfo() {
//开启实时计算剩余距离,剩余时间,预计时间
startOrStopCalculateRouteInfo(true);
}
public void startToRouteAndWipe() {
startOrStopRouteAndWipe(true);
}
/**
* 实时轨迹擦除
* @param isStart
*/
public void startOrStopRouteAndWipe(boolean isStart){
if (isStart){
BusPassengerModelLoopManager.getInstance().startOrStopRouteAndWipe();
}else {
mWipePreIndex = 0;
BusPassengerModelLoopManager.getInstance().stopOrStopRouteAndWipe();
}
}
public void loopRouteAndWipe() {
if (mRoutePoints != null && mRoutePoints.size() > 0 && mLocation != null){
int haveArrivedIndex = CoordinateCalculateRouteUtil
.getArrivedPointIndexNew(mWipePreIndex,
mRoutePoints,
mLocation);
mWipePreIndex = haveArrivedIndex;
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "thread = "+ Thread.currentThread().getName()+" haveArrivedIndex== " + haveArrivedIndex);
if (mAutopilotPlanningCallback != null){
List<LatLng> routePoints = CoordinateCalculateRouteUtil
.coordinateConverterLocationToLatLng(mContext,mRoutePoints);
mAutopilotPlanningCallback.routeResult(routePoints,haveArrivedIndex);
}
}
}
/**
* 开始轮询计算剩余里程和时间
* @param isStart
*/
public void startOrStopCalculateRouteInfo(boolean isStart) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startOrStopCalculateRouteInfo() " + isStart);
if (isStart) {
BusPassengerModelLoopManager.getInstance().startCalculateRouteInfoLoop();
} else {
mTwoStationsRouts.clear();
BusPassengerModelLoopManager.getInstance().stopCalculateRouteInfLoop();
}
}
private void startOrStopOrderLoop(boolean start) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startOrStopOrderLoop() " + start);
if (start) {
BusPassengerModelLoopManager.getInstance().startQueryDriverLineLoop();
} else {
BusPassengerModelLoopManager.getInstance().stopQueryDriverLineLoop();
}
}
}

View File

@@ -0,0 +1,160 @@
package com.mogo.och.bus.passenger.network;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.bus.passenger.model.BusPassengerModel;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.LOOP_DELAY;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.LOOP_LINE_2S;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.LOOP_LINE_1S;
/**
* Created on 2021/11/22
*
* 管理轮询逻辑(订单轮询、新单轮询、新单抢单结果轮询等等)
*/
public class BusPassengerModelLoopManager {
private static final String TAG = BusPassengerModelLoopManager.class.getSimpleName();
private static final class SingletonHolder {
private static final BusPassengerModelLoopManager INSTANCE = new BusPassengerModelLoopManager();
}
public static BusPassengerModelLoopManager getInstance() {
return SingletonHolder.INSTANCE;
}
private Disposable mQueryLineDisposable; //心跳轮询
private CompositeDisposable mRouteWipeDisposable;
private CompositeDisposable mCalculateRouteDisposable; //每隔2s计算一次剩余里程和时间
public void startOrStopRouteAndWipe() {
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "startOrStopRouteWipe()");
if (mRouteWipeDisposable != null) return;
if (mRouteWipeDisposable == null){
mRouteWipeDisposable = new CompositeDisposable();
}
Disposable disposable = startLoopRouteAndWipe()
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
}
})
.doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
})
.delay(LOOP_LINE_1S, TimeUnit.MILLISECONDS, true) // 设置delayError为true表示出现错误的时候也需要延迟5s进行通知达到无论是请求正常还是请求失败都是5s后重新订阅即重新请求。
.subscribeOn(Schedulers.io())
.repeat() // repeat保证请求成功后能够重新订阅。
.retry() // retry保证请求失败后能重新订阅
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
}
});
mRouteWipeDisposable.add(disposable);
}
public void stopOrStopRouteAndWipe() {
if (mRouteWipeDisposable != null) {
mRouteWipeDisposable.dispose();
mRouteWipeDisposable = null;
}
}
public void startQueryDriverLineLoop() {
if (mQueryLineDisposable != null && !mQueryLineDisposable.isDisposed()) {
return;
}
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "startQueryDriverLineLoop()");
mQueryLineDisposable = Observable.interval(LOOP_DELAY,
LOOP_LINE_2S, TimeUnit.MILLISECONDS)
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> BusPassengerModel.getInstance().queryDriverSiteByCoordinate());
}
public void stopQueryDriverLineLoop() {
if (mQueryLineDisposable != null) {
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "stopQueryDriverLineLoop()");
mQueryLineDisposable.dispose();
mQueryLineDisposable = null;
}
}
public void startCalculateRouteInfoLoop() {
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "startCalculateRouteInfoLoop()");
if (mCalculateRouteDisposable != null) return;
if (mCalculateRouteDisposable == null){
mCalculateRouteDisposable = new CompositeDisposable();
}
Disposable disposable = startLoopCalculateRouteInfo()
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
}
})
.doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
}
})
.delay(LOOP_LINE_2S, TimeUnit.MILLISECONDS, true) // 设置delayError为true表示出现错误的时候也需要延迟5s进行通知达到无论是请求正常还是请求失败都是5s后重新订阅即重新请求。
.subscribeOn(Schedulers.io())
.repeat() // repeat保证请求成功后能够重新订阅。
.retry() // retry保证请求失败后能重新订阅
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
}
});
mCalculateRouteDisposable.add(disposable);
}
public void stopCalculateRouteInfLoop() {
if (mCalculateRouteDisposable != null) {
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "stopCalculateRouteInfLoop()");
mCalculateRouteDisposable.dispose();
mCalculateRouteDisposable = null;
}
}
private Observable<Integer> startLoopRouteAndWipe(){
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
if (emitter.isDisposed()) return;
BusPassengerModel.getInstance().loopRouteAndWipe();
emitter.onComplete();
}
});
}
private Observable<Integer> startLoopCalculateRouteInfo(){
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
if (emitter.isDisposed()) return;
BusPassengerModel.getInstance().dynamicCalculateRouteInfo();
emitter.onComplete();
}
});
}
}

View File

@@ -0,0 +1,79 @@
package com.mogo.och.bus.passenger.network
import android.content.Context
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager.getServerToken
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.biz.network.interceptor.transformTry
/**
* Created on 2022/3/31
*/
object BusPassengerServiceManager {
private var driverSnCache = ""
private var mShuttleBusPassengerServiceApi =
MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(ShettlePassengerServiceApi::class.java)
/**
* 获取Bus司机端的sn
* @return
*/
val driverAppSn: String
get() {
val serverToken = getServerToken()
if (serverToken != driverSnCache && serverToken.isNotEmpty()) {
driverSnCache = serverToken
}
return driverSnCache
}
/**
* 查询绑定行驶的小巴车路线
* @param context
* @param callback
*/
@JvmStatic
fun queryDriverSiteByCoordinate(
context: Context, callback: OchCommonServiceCallback<BusPassengerRoutesResponse>?
) {
mShuttleBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
BusPassengerQueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate"))
}
/**
* 查询司机端出车收车状态,以及车牌号
* @param context
* @param callback
*/
@JvmStatic
fun queryDriverOperationStatus(
context: Context,
callback: OchCommonServiceCallback<BusPassengerOperationStatusResponse>?
) {
mShuttleBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus"))
}
}

View File

@@ -0,0 +1,164 @@
package com.mogo.och.bus.passenger.presenter;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import com.amap.api.maps.model.LatLng;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.bus.passenger.callback.IBusPassegerDriverStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerADASStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerAutopilotPlanningCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerControllerStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerRouteLineInfoCallback;
import com.mogo.och.bus.passenger.model.BusPassengerModel;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import java.util.List;
/**
* Created on 2022/3/31
*/
public class BaseBusPassengerPresenter extends Presenter<BusPassengerRouteFragment> implements
IBusPassengerADASStatusCallback, IBusPassengerControllerStatusCallback, IBusPassegerDriverStatusCallback, IBusPassengerRouteLineInfoCallback, IBusPassengerAutopilotPlanningCallback {
private static final String TAG = BaseBusPassengerPresenter.class.getSimpleName();
public BaseBusPassengerPresenter(BusPassengerRouteFragment view) {
super(view);
BusPassengerModel.getInstance().init(AbsMogoApplication.getApp());
initListeners();
}
@Override
public void onCreate( @NonNull LifecycleOwner owner ) {
super.onCreate( owner );
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "Bus乘客端Presenter onCreate()" );
}
@Override
public void onDestroy( @NonNull LifecycleOwner owner ) {
super.onDestroy( owner );
releaseListeners();
BusPassengerModel.getInstance().release();
}
private void initListeners() {
BusPassengerModel.getInstance().setADASStatusCallback(this);
BusPassengerModel.getInstance().setControllerStatusCallback(TAG, this);
BusPassengerModel.getInstance().setDriverStatusCallback(this);
BusPassengerModel.getInstance().setRouteLineInfoCallback(this);
BusPassengerModel.getInstance().setMoGoAutopilotPlanningListener(this);
}
private void releaseListeners() {
BusPassengerModel.getInstance().setADASStatusCallback(null);
BusPassengerModel.getInstance().setControllerStatusCallback(TAG, null);
BusPassengerModel.getInstance().setDriverStatusCallback(null);
BusPassengerModel.getInstance().setRouteLineInfoCallback(null);
BusPassengerModel.getInstance().setMoGoAutopilotPlanningListener(null);
}
private void runOnUIThread( Runnable executor ) {
if ( executor == null ) {
return;
}
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( executor );
} else {
executor.run();
}
}
@Override
public void onAutopilotArriveEnd() {
// mView.showOverviewFragment();
}
@Override
public void onAutopilotEnable() {
runOnUIThread(() -> mView.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE));
}
@Override
public void onAutopilotDisable() {
runOnUIThread(() -> mView.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE));
}
@Override
public void onAutopilotRunning() {
runOnUIThread(() -> mView.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING));
}
@Override
public void onVRModeChanged(boolean isVRMode) {
}
@Override
public void onCarLocationChanged(MogoLocation location) {
if (location != null){
runOnUIThread(() -> mView.onCarLocationChanged(location));
}
}
@Override
public void changeOperationStatus(boolean changeStatus) {
runOnUIThread(() -> mView.changeOperationStatus(changeStatus));
}
@Override
public void updatePlateNumber(String plateNumber) {
runOnUIThread(() -> mView.updatePlateNum(plateNumber));
}
@Override
public void updateLineInfo(String lineName, String lineDurTime) {
runOnUIThread(() -> mView.updateLineInfo(lineName, lineDurTime));
}
@Override
public void updateStationsInfo(List<BusPassengerStation> stations,int currentStationIndex,boolean isArrived) {
runOnUIThread(() -> mView.updateStationsInfo(stations,currentStationIndex, isArrived));
}
@Override
public void showNoTaskView() {
runOnUIThread(() -> mView.showNoTaskView());
}
@Override
public void hideNoTaskView() {
runOnUIThread(() -> mView.hideNoTaskView());
}
@Override
public void routeResult(List<LatLng> models, int haveArrivedIndex) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "routeResult:" + models.size()
+ " haveArrivedIndex = "+haveArrivedIndex);
runOnUIThread(() ->mView.routeResult(models,haveArrivedIndex));
}
@Override
public void routePlanningToNextStationChanged(long meters, long timeInSecond) {
runOnUIThread(() -> mView.updateRoutePlanningToNextStation(meters, timeInSecond));
}
@Override
public void updateTotalDistance() {
runOnUIThread(() -> mView.setProgressBarMax());
}
}

View File

@@ -0,0 +1,223 @@
package com.mogo.och.bus.passenger.ui;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.widget.ContentLoadingProgressBar;
import com.mogo.commons.mvp.IView;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.view.MapBizView;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.common.module.utils.NumberFormatUtil;
/**
* Created on 2022/3/31
* <p>
* Bus乘客端基础Fragment
*/
public abstract class BusPassengerBaseFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> {
private static final String TAG = BusPassengerBaseFragment.class.getSimpleName();
private MapBizView mapBizView;
private TextView mCurrentArriveStation;
private TextView mCurrentArriveStationTitle;
private TextView mCurrentArriveTip;
private ImageView mAutopilotIv;
private FrameLayout flContainer;
private ContentLoadingProgressBar mProgressBar;
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
private int mPrevAPStatus = -1;
@Override
protected int getLayoutId() {
return R.layout.bus_p_base_fragment;
}
@Override
public String getTagName() {
return TAG;
}
@Override
protected void initViews() {
mapBizView = findViewById(R.id.mapBizView);
mCurrentArriveStation = findViewById(R.id.bus_p_cur_station_name);
mCurrentArriveStationTitle = findViewById(R.id.bus_p_cur_station_title);
mCurrentArriveTip = findViewById(R.id.bus_p_cur_station_tip);
mAutopilotIv = findViewById(R.id.bus_p_autopilot_iv);
mProgressBar = findViewById(R.id.bus_progress_bar);
showRouteFragment();
// mCurrentArriveStation.setOnLongClickListener(new View.OnLongClickListener() {
// @Override
// public boolean onLongClick(View v) {
// showOverviewFragment();
// return false;
// }
// });
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mapBizView.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
mapBizView.onResume();
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapBizView.onSaveInstanceState(outState);
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapBizView.onLowMemory();
}
@Override
public void onPause() {
super.onPause();
mapBizView.onPause();
}
@Override
public void onDestroyView() {
mapBizView.onDestroy();
super.onDestroyView();
}
/**
* 获取站点面板view在{@link #initViews()}时候添加到container中
*
* @return 站点面板view
*/
public abstract int getStationPanelViewId();
/**
* 显示线路信息
*/
public void showRouteFragment() {
flContainer = findViewById(R.id.bus_p_route_panel);
LayoutInflater.from(getContext()).inflate(getStationPanelViewId(), flContainer);
}
public void updateArrivedStation(String station,int currentIndex,boolean isArrived){
if (null == station){
mCurrentArriveStation.setText("----");
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_station_title_init));
mCurrentArriveTip.setText(getResources().getString(R.string.bus_p_cur_station_arrived_tip));
removeProgressBar();
}else {
mCurrentArriveStation.setText(station);
if (currentIndex == 0){
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_station_title_init));
mCurrentArriveTip.setText(getResources().getString(R.string.bus_p_cur_station_arrived_tip_init));
removeProgressBar();
return;
}
if (isArrived){
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_station_title));
mCurrentArriveTip.setText(getResources().getString(R.string.bus_p_cur_station_arrived_tip));
removeProgressBar();
}else {
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_next_station_title));
mProgressBar.setVisibility(View.VISIBLE);
}
}
}
private void removeProgressBar() {
mProgressBar.setProgress(0);
mProgressBar.setMax(0);
mProgressBar.setVisibility(View.GONE);
}
public void updateRoutePlanningToNextStation(long meters, long timeInSecond){
//更新进度条
updateProgressBar(meters);
String dis = "0";
String disUnit = "公里";
if (meters > 0){
if (meters / 1000 < 1){
disUnit = "";
dis = String.valueOf(Math.round(meters));
}else {
disUnit = "公里";
dis = NumberFormatUtil.formatLong((double)meters / 1000);
}
}
String strHtml2 = "<font color=\"#2D3E5F\">距离 </font>" + "<b><font color=\"#0043FF\">" + dis + "</font></b>" + "<font color=\"#2D3E5F\"> "+disUnit+"</font>"
+ "<font color=\"#2D3E5F\"> &nbsp 剩余 </font>" + "<b><font color=\"#0043FF\">" + (int)Math.ceil((double)timeInSecond/ 60f) + "</font></b>" + "<font color=\"#2D3E5F\"> 分钟</font>";
mCurrentArriveTip.setText(Html.fromHtml(strHtml2));
}
private void updateProgressBar(long meters) {
int haveDriven = new Long(meters).intValue();
int progressInt = SharedPrefsMgr.getInstance(getContext())
.getInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,0) - haveDriven;
mProgressBar.setProgress(progressInt);
}
public void setProgressBarMax(){
int max = SharedPrefsMgr.getInstance(getContext())
.getInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,0);
mProgressBar.setMax(max);
}
public void onAutopilotStatusChanged(int status) {
getActivity().runOnUiThread(() -> {
// 3. 其他过程直接更新
if (mPrevAPStatus != status){
AutopilotStatusChanged(status);
}
mPrevAPStatus = status;
});
}
public void AutopilotStatusChanged(int status) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status) {
mAutopilotIv.setImageResource(R.drawable.bus_p_auto_nor);
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == status){
mAutopilotIv.setImageResource(R.drawable.bus_p_un_auto_nor);
} else {
mAutopilotIv.setImageResource(R.drawable.bus_p_un_auto_nor);
}
}
public void showOverviewFragment() {
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
}
},5000L);
}
}

View File

@@ -0,0 +1,346 @@
package com.mogo.och.bus.passenger.ui;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.CustomMapStyleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.callback.IBusPassengerMapViewCallback;
import com.mogo.och.bus.passenger.utils.BusPassengerMapAssetStyleUtil;
import java.util.ArrayList;
import java.util.List;
/**
* 乘客屏小地图
*/
public class BusPassengerMapDirectionView
extends RelativeLayout
implements IMoGoChassisLocationGCJ02Listener,
IBusPassengerMapDirectionView,
AMap.OnCameraChangeListener {
//小地图名称
public static final String TAG = "TPMapDirectionView";
private TextureMapView mAMapNaviView;
private AMap mAMap;
private Marker mCarMarker;
private List<LatLng> mCoordinatesLatLng = new ArrayList<>(); //轨迹坐标数据
private List<LatLng> mLineStationLatLng = new ArrayList<>();//站点坐标数据
private Polyline mPolyline;
private CameraUpdate mCameraUpdate;
private Context mContext;
List<BitmapDescriptor> textureList = new ArrayList<>();
List<Integer> texIndexList = new ArrayList<>();
private int mHaveArrivedIndex = 0;
private List<Marker> mLineMarkers = new ArrayList<>();
private IBusPassengerMapViewCallback mIBusPassengerMapViewCallback;
private BitmapDescriptor mArrivedRes;
private BitmapDescriptor mUnArrivedRes;
public BusPassengerMapDirectionView(Context context) {
this(context, null);
}
public BusPassengerMapDirectionView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BusPassengerMapDirectionView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
try {
initView(context);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setTaxiPassengerMapViewCallback(IBusPassengerMapViewCallback iBusPassengerMapViewCallback) {
this.mIBusPassengerMapViewCallback = iBusPassengerMapViewCallback;
}
private void initView(Context context) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "initView");
mContext = context;
View smpView = LayoutInflater.from(context).inflate(R.layout.bus_p_map_view, this);
mAMapNaviView = (TextureMapView) smpView.findViewById(R.id.bus_p_line_amap_view);
initAMapView();
// 注册定位监听
CallerChassisLocationGCJ02ListenerManager.INSTANCE.addListener(TAG, this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// 注册定位监听
CallerChassisLocationGCJ02ListenerManager.INSTANCE.removeListener(TAG);
}
private void initAMapView() {
// mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
mAMap = mAMapNaviView.getMap();
// 设置导航地图模式aMap是地图控制器对象。
mAMap.setMapType(AMap.MAP_TYPE_NIGHT);
// 关闭显示实时路况图层aMap是地图控制器对象。
mAMap.setTrafficEnabled(false);
// 设置 锚点 图标
mCarMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_car))
.anchor(0.5f, 0.5f));
mArrivedRes = BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_arrow_arrived);
mUnArrivedRes = BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_arrow_un_arrive);
// 加载自定义样式
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(BusPassengerMapAssetStyleUtil.getAssetsStyle(getContext(), "map_style.data"))
.setStyleExtraData(BusPassengerMapAssetStyleUtil.getAssetsExtraStyle(getContext(), "map_style_extra.data"));
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions);
//设置希望展示的地图缩放级别
// mAMap.moveCamera(mCameraUpdate);
// 设置地图的样式
UiSettings uiSettings = mAMap.getUiSettings();
uiSettings.setZoomControlsEnabled(false);// 地图缩放级别的交换按钮
uiSettings.setAllGesturesEnabled(false);// 所有手势
uiSettings.setMyLocationButtonEnabled(false); // 显示默认的定位按钮
uiSettings.setLogoBottomMargin(-150); //设置Logo下边界距离屏幕底部的边距,设置为负值即可
mAMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
@Override
public void onMapLoaded() {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "smp---onMapLoaded");
// 加载自定义样式
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(BusPassengerMapAssetStyleUtil.getAssetsStyle(getContext(), "map_style.data"))
.setStyleExtraData(BusPassengerMapAssetStyleUtil.getAssetsExtraStyle(getContext(), "map_style_extra.data"));
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions);
mAMapNaviView.getMap().setPointToCenter(mAMapNaviView.getWidth() / 2, mAMapNaviView.getHeight() / 2);
}
});
//设置地图状态的监听接口
mAMap.setOnCameraChangeListener(this);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
@Override
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
if (gnssInfo == null) {
return;
}
// CallerLogger.INSTANCE.d(M_BUS_P + TAG, "onCarLocationChanged2 :" + location.getLatitude() + ":" + location.getLongitude());
LatLng currentLatLng = new LatLng(gnssInfo.getLatitude(), gnssInfo.getLongitude());
//更新车辆位置
if (mCarMarker != null) {
// CallerLogger.INSTANCE.d(M_BUS_P + TAG, "location.getBearing() = " + location.getBearing());
mCarMarker.setRotateAngle((float) (360 - gnssInfo.getHeading()));
mCarMarker.setPosition(currentLatLng);
mCarMarker.setToTop();
}
//圈定地图显示范围
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
if (mCoordinatesLatLng.size() > 0){
//存放经纬度
for (int i = 0; i < mCoordinatesLatLng.size(); i++) {
boundsBuilder.include(mCoordinatesLatLng.get(i));
}
//第二个参数为四周留空宽度
}else if (mLineStationLatLng.size() > 0){
for (int i = 0; i< mLineStationLatLng.size();i++){
boundsBuilder.include(mLineStationLatLng.get(i));
}
}
boundsBuilder.include(currentLatLng);
mAMap.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(),100,100,100,100));
}
@Override
public void drawablePolyline() {
if (mPolyline != null) {
mPolyline.remove();
}
if (mAMap != null) {
addRouteColorList();
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "mLinePointsLatLng.size() = " +mLineStationLatLng.size()
+" mCoordinatesLatLng.size()= " + mCoordinatesLatLng.size());
if (mLineStationLatLng.size() >= 2 && mCoordinatesLatLng.size() > 2) {
//设置线段纹理
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.addAll(mCoordinatesLatLng);
polylineOptions.width(14); //线段宽度
polylineOptions.setUseTexture(true);
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound);
polylineOptions.setCustomTextureList(textureList);
polylineOptions.setCustomTextureIndex(texIndexList);
// polylineOptions.colorValues(colorList);
// polylineOptions.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.taxi_p_map_arrow));
// 绘制线
mPolyline = mAMap.addPolyline(polylineOptions);
}
}
}
/**
* 添加画线颜色值
*/
private void addRouteColorList() {
textureList.clear();
texIndexList.clear();
for (int i = 0; i < mCoordinatesLatLng.size(); i++){
if (i <= mHaveArrivedIndex){
textureList.add(mArrivedRes);
}else {
textureList.add(mUnArrivedRes);
}
texIndexList.add(i);
}
}
@Override
public void clearPolyline() {
if (mPolyline != null) {
mPolyline.remove();
}
}
@Override
public void setLineMarker() {
}
public void clearCoordinatesLatLng(){
textureList.clear();
texIndexList.clear();
mCoordinatesLatLng.clear();
mLineStationLatLng.clear();
CallerLogger.INSTANCE.d(M_BUS_P + TAG, " mCoordinatesLatLng.clear " );
}
public void onCreateView(Bundle savedInstanceState) {
if (mAMapNaviView != null) {
mAMapNaviView.onCreate(savedInstanceState);
}
}
public void onResume() {
if (mAMapNaviView != null) {
mAMapNaviView.onResume();
}
}
public void onPause() {
if (mAMapNaviView != null) {
mAMapNaviView.onPause();
}
}
public void onDestroy() {
if (mAMapNaviView != null) {
mAMapNaviView.onDestroy();
}
}
public void setCoordinatesLatLng(List<LatLng> latLngs,int haveArrivedIndex) {
mCoordinatesLatLng.clear();
mCoordinatesLatLng.addAll(latLngs);
mHaveArrivedIndex = haveArrivedIndex;
}
public void clearLineMarkers(){
for (int i =0; i< mLineMarkers.size();i++){
mLineMarkers.get(i).setVisible(false);
mLineMarkers.get(i).remove();
}
mLineMarkers.clear();
}
public void setLinePointMarkerAndDraw(List<LatLng> mLineStationsList, int currentIndex) {
clearLineMarkers();
mLineStationLatLng.clear();
mLineStationLatLng.addAll(mLineStationsList);
if (mLineStationsList.size() > 0){
for (int i = 0; i < mLineStationsList.size(); i++) {
if (currentIndex == i){
Marker mEndMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_view_dir_end_point)));
mEndMarker.setPosition(mLineStationsList.get(i));
mLineMarkers.add(i,mEndMarker);
}else {
Marker mStartMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_view_dir_way_point)));
mStartMarker.setPosition(mLineStationsList.get(i));
mLineMarkers.add(i,mStartMarker);
}
}
}
}
@Override
public void onCameraChange(CameraPosition cameraPosition) {
mIBusPassengerMapViewCallback.onCameraChange(cameraPosition.bearing);
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
}
}

View File

@@ -0,0 +1,314 @@
package com.mogo.och.bus.passenger.ui;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.amap.api.maps.model.LatLng;
import com.elegant.utils.UiThreadHandler;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.adapter.BusPassengerLineStationsAdapter;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.bus.passenger.callback.IBusPassengerMapViewCallback;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.presenter.BaseBusPassengerPresenter;
import com.mogo.och.bus.passenger.ui.layoutmanager.CenterLayoutManager;
import com.mogo.och.bus.passenger.utils.BPRouteDataTestUtils;
import com.mogo.och.common.module.wigets.MarqueeTextView;
import java.util.ArrayList;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
public class BusPassengerRouteFragment extends
BusPassengerBaseFragment<BusPassengerRouteFragment, BaseBusPassengerPresenter>
implements IBusPassengerMapViewCallback {
private final String TAG = "BusPassengerRouteFragment";
private final List<BusPassengerStation> mStationsList = new ArrayList<>();
private TextView mSpeedTv;
private ConstraintLayout mNoLineInfoView;
private TextView mCarPlateNum;
private MarqueeTextView mLineName;
private TextView mOperationTime;
private ConstraintLayout mRouteInfoView;
private RecyclerView mStationsListRv;
private BusPassengerMapDirectionView mMapDirectionView;
private ImageView mMapArrowIcon;
private RotateAnimation rotateAnimation;
private float lastBearing = 0;
private BusPassengerLineStationsAdapter mAdapter;
private TextView emptyTv;
@Override
public int getStationPanelViewId() {
return R.layout.bus_p_route_fragment;
}
@NonNull
@Override
protected BaseBusPassengerPresenter createPresenter() {
return new BaseBusPassengerPresenter(this);
}
@Override
protected void initViews() {
super.initViews();
mSpeedTv = findViewById(R.id.bus_p_speed_tv);
mNoLineInfoView =findViewById(R.id.bus_p_no_order_data_view);
emptyTv = findViewById(R.id.no_order_data_tv);
mCarPlateNum = findViewById(R.id.bus_p_driver_num_plate_tv);
mLineName = findViewById(R.id.bus_p_line_name_tv);
mOperationTime = findViewById(R.id.line_operation_time_tv);
mRouteInfoView = findViewById(R.id.bus_p_line_cl);
mStationsListRv = findViewById(R.id.bus_p_line_stations_rl);
CenterLayoutManager manager = new CenterLayoutManager(getContext());
mStationsListRv.setLayoutManager(manager);
mAdapter = new BusPassengerLineStationsAdapter(getContext(), mStationsList);
mStationsListRv.setAdapter(mAdapter);
mMapArrowIcon = findViewById(R.id.bus_p_arrow_nor);
//测试
if (DebugConfig.isDebug()){
mSpeedTv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
BPRouteDataTestUtils.converToRouteData();
return false;
}
});
}
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mMapDirectionView = findViewById(R.id.bus_p_line_map_view);
mMapDirectionView.onCreateView(savedInstanceState);
mMapDirectionView.setTaxiPassengerMapViewCallback(this);
}
@Override
public void onResume() {
super.onResume();
if (mMapDirectionView != null) {
mMapDirectionView.onResume();
}
}
@Override
public void onPause() {
super.onPause();
if (mMapDirectionView != null) {
mMapDirectionView.onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mMapDirectionView != null) {
mMapDirectionView.onDestroy();
}
}
public void routeResult(List<LatLng> latLngList,int haveArrivedIndex) {
if (latLngList.size() > 0) {
drawablePolyline(latLngList,haveArrivedIndex);
} else {
clearMapView();
}
}
/**
* 绘制
*
* @param coordinates
*/
private void drawablePolyline(List<LatLng> coordinates,int haveArrivedIndex) {
if (mMapDirectionView != null) {
mMapDirectionView.setCoordinatesLatLng(coordinates,haveArrivedIndex);
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.drawablePolyline();
}
});
}
}
public void clearMapView() {
if (mMapDirectionView != null) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.clearPolyline();
mMapDirectionView.clearCoordinatesLatLng();
}
});
}
}
public void clearMapMarkers() {
if (mMapDirectionView != null) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.clearLineMarkers();
}
});
}
}
public void changeOperationStatus(boolean status) {
if (status) {
mNoLineInfoView.setVisibility(View.GONE);
mRouteInfoView.setVisibility(View.VISIBLE);
} else {
emptyTv.setText(getString(R.string.bus_p_no_out));
mNoLineInfoView.setVisibility(View.VISIBLE);
mRouteInfoView.setVisibility(View.GONE);
updateArrivedStation(null,0,true);
clearMapView();
clearMapMarkers();
}
}
public void showNoTaskView(){
if (mNoLineInfoView.getVisibility() == View.GONE){
mNoLineInfoView.setVisibility(View.VISIBLE);
mRouteInfoView.setVisibility(View.GONE);
updateArrivedStation(null,0,true);
clearMapView();
clearMapMarkers();
}
emptyTv.setText(getString(R.string.bus_p_no_task));
}
public void hideNoTaskView(){
if (mNoLineInfoView.getVisibility() == View.VISIBLE){
mNoLineInfoView.setVisibility(View.GONE);
mRouteInfoView.setVisibility(View.VISIBLE);
}
}
public void updatePlateNum(String plateNum){
if ("".equals(plateNum) || null == plateNum) {
mCarPlateNum.setText("-- --");
}else {
mCarPlateNum.setText((plateNum));
}
}
public void updateLineInfo(String lineName, String lineDurTime) {
mLineName.setText(lineName);
mOperationTime.setText(lineDurTime);
}
/**
*
* @param stations
* @param currentStationIndex
* @param isArrived 是否到站并离开true 到达当前站 currentStationIndex 未离开, false 正在前往此站 currentStationIndex
*/
public void updateStationsInfo(List<BusPassengerStation> stations, int currentStationIndex,boolean isArrived) {
updateArrivedStation(stations.get(currentStationIndex).getName(),currentStationIndex,isArrived);
mStationsList.clear();
mStationsList.addAll(stations);
mAdapter.notifyDataSetChanged();
if (currentStationIndex > -1){
updateCurrentStation(currentStationIndex);
}
if (currentStationIndex == 0 && isArrived){ //到达始发站且并未出发, 恢复站点marker 清楚路径 清空路径点
SharedPrefsMgr.getInstance(getContext())
.remove(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS);
clearMapView();
}
if (stations.size() > 0){
updateWayPointList(stations,currentStationIndex);
}
}
private void updateWayPointList(List<BusPassengerStation> stations,int currentStationIndex) {
List<LatLng> mLineStationsList = new ArrayList<>();
for (int i = 0; i< stations.size(); i++) {//站点集合
// LatLng latLng = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(getContext()
// ,stations.get(i).getLon(),stations.get(i).getLat());// lat,lon
LatLng latLng = new LatLng(stations.get(i).getGcjLat(),stations.get(i).getGcjLon());// lat,lon
mLineStationsList.add(latLng);
}
if (mMapDirectionView != null) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.setLinePointMarkerAndDraw(mLineStationsList,currentStationIndex);
}
});
}
}
@Override
public void onCameraChange(float bearing) {
startIvCompass(bearing);
}
/**
* 设置指南针旋转
*
* @param bearing
*/
private void startIvCompass(float bearing) {
bearing = 360 - bearing;
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startIvCompass: " + bearing);
rotateAnimation = new RotateAnimation(lastBearing, bearing, Animation.RELATIVE_TO_SELF
, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setFillAfter(true);
mMapArrowIcon.startAnimation(rotateAnimation);
lastBearing = bearing;
}
public void onCarLocationChanged(MogoLocation location) {
updateSpeedView((float) location.getGnssSpeed());
}
public void updateSpeedView(float speed){
int speedKM = (int) (Math.abs(speed) * 3.6F);
mSpeedTv.setText(String.valueOf(speedKM));
}
public void updateCurrentStation(int position) {
if (mStationsListRv != null){
mStationsListRv.smoothScrollToPosition(position);
}
}
}

View File

@@ -0,0 +1,179 @@
package com.mogo.och.bus.passenger.ui
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.TrafficLightEnum
import com.mogo.eagle.core.function.api.datacenter.union.IMoGoTrafficLightListener
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.bus.passenger.R
import kotlinx.android.synthetic.jinlvvan.bus_p_traffic_light_view.view.*
/**
* bus乘客端红绿灯view
*
* Created on 2022/3/14
*/
class BusPassengerTrafficLightView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr), IMoGoTrafficLightListener {
companion object {
private const val TAG = "BusPassengerTrafficLightView"
}
private var mCurrentLightId = TrafficLightEnum.BLACK
init {
init(context)
}
private fun init(context: Context?) {
LayoutInflater.from(context).inflate(R.layout.bus_p_traffic_light_view, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerTrafficLightListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerTrafficLightListenerManager.removeListener(TAG)
}
/**
* 展示红绿灯预警
*
* @param checkLightId 0-都是默认1-红2-黄3-绿
* @param lightSource 1:云端下发2:自车感知
*/
override fun showTrafficLight(checkLightId: TrafficLightEnum, lightSource: DataSourceType) {
super.showTrafficLight(checkLightId, lightSource)
mCurrentLightId = checkLightId
updateTrafficLightIcon(checkLightId)
}
/**
* 关闭红绿灯预警展示,并重制灯态
*/
override fun disableTrafficLight() {
super.disableTrafficLight()
UiThreadHandler.post {
mCurrentLightId = TrafficLightEnum.BLACK
this@BusPassengerTrafficLightView.visibility = GONE
}
}
/**
* @param redNum 红灯倒计时
* @param yellowNum 黄灯倒计时
* @param greenNum 绿灯倒计时
*/
override fun changeCountdownTrafficLightNum(redNum: Int, yellowNum: Int, greenNum: Int) {
super.changeCountdownTrafficLightNum(redNum, yellowNum, greenNum)
resetView()
when (mCurrentLightId) {
TrafficLightEnum.RED -> changeCountdownRed(redNum)
TrafficLightEnum.YELLOW -> changeCountdownYellow(yellowNum)
TrafficLightEnum.GREEN -> changeCountdownGreen(greenNum)
else -> UiThreadHandler.post { bus_p_traffic_light_time_tv.text = "" }
}
}
override fun changeCountdownRed(redNum: Int) {
super.changeCountdownRed(redNum)
UiThreadHandler.post {
if (redNum > 0) {
resetView()
bus_p_traffic_light_time_tv.text = redNum.toString()
} else {
disableTrafficLightCountDown()
bus_p_traffic_light_time_tv.text = ""
}
}
}
override fun changeCountdownGreen(greenNum: Int) {
super.changeCountdownGreen(greenNum)
UiThreadHandler.post {
if (greenNum > 0) {
resetView()
bus_p_traffic_light_time_tv.text = greenNum.toString()
} else {
disableTrafficLightCountDown()
bus_p_traffic_light_time_tv.text = ""
}
}
}
override fun changeCountdownYellow(yellowNum: Int) {
super.changeCountdownYellow(yellowNum)
UiThreadHandler.post {
if (yellowNum > 0) {
resetView()
bus_p_traffic_light_time_tv.text = yellowNum.toString()
} else {
disableTrafficLightCountDown()
bus_p_traffic_light_time_tv.text = ""
}
}
}
/**
* 更新红绿灯icon
*
* @param lightId 0-都是默认1-红2-黄3-绿
*/
private fun updateTrafficLightIcon(lightId: TrafficLightEnum) {
UiThreadHandler.post {
when (lightId) {
TrafficLightEnum.RED -> {
bus_p_traffic_light_iv.setBackgroundResource(R.drawable.bus_p_light_red_nor)
this@BusPassengerTrafficLightView.visibility = VISIBLE
}
TrafficLightEnum.YELLOW -> {
bus_p_traffic_light_iv.setBackgroundResource(R.drawable.bus_p_light_yellow_nor)
this@BusPassengerTrafficLightView.visibility = VISIBLE
}
TrafficLightEnum.GREEN -> {
bus_p_traffic_light_iv.setBackgroundResource(R.drawable.bus_p_light_green_nor)
this@BusPassengerTrafficLightView.visibility = VISIBLE
}
else -> this@BusPassengerTrafficLightView.visibility = GONE
}
}
}
override fun disableTrafficLightCountDown() {
super.disableTrafficLightCountDown()
UiThreadHandler.post {
val layoutParams = layoutParams
if (layoutParams is MarginLayoutParams) {
val lp = layoutParams
lp.width = resources.getDimension(R.dimen.bus_p_traffic_light_icon_size).toInt()
setLayoutParams(lp)
bus_p_traffic_light_time_tv.visibility = GONE
bus_p_traffic_light_bg.layoutParams.width =
resources.getDimension(R.dimen.dp_90).toInt()
}
}
}
private fun resetView() {
val layoutParams = layoutParams
if (layoutParams is MarginLayoutParams) {
val lp = layoutParams
lp.width = resources.getDimension(R.dimen.bus_p_route_traffic_light_view_width).toInt()
setLayoutParams(lp)
bus_p_traffic_light_time_tv.visibility = VISIBLE
bus_p_traffic_light_bg.layoutParams.width =
resources.getDimension(R.dimen.bus_p_traffic_light_bg_width).toInt()
}
}
}

View File

@@ -0,0 +1,23 @@
package com.mogo.och.bus.passenger.ui;
/**
* @author xiaoyuzhou
* @date 2021/6/24 11:33 上午
*/
public interface IBusPassengerMapDirectionView {
/**
* 绘制路径线
*/
void drawablePolyline();
/**
* 清除路径线
*/
void clearPolyline();
/**
* 设置路径中起终点marker
*/
void setLineMarker();
}

View File

@@ -0,0 +1,42 @@
package com.mogo.och.bus.passenger.ui.layoutmanager;
import android.content.Context;
import android.util.AttributeSet;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
public class CenterLayoutManager extends LinearLayoutManager {
public CenterLayoutManager(Context context) {
super(context);
}
public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private static class CenterSmoothScroller extends LinearSmoothScroller {
CenterSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_end_station_circle_borner_color" />
<corners android:radius="@dimen/bus_p_station_circle_radius_size" />
</shape>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="@dimen/bus_p_station_tag_width_height"
android:height="@dimen/bus_p_station_tag_width_height">
<shape android:shape="rectangle">
<corners android:radius="@dimen/bus_p_station_tag_radius_size"/>
<gradient
android:angle="90"
android:endColor="@color/bus_p_end_tag_bg_color1"
android:startColor="@color/bus_p_end_tag_bg_color2"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_tag_line_color" />
<corners android:radius="@dimen/bus_p_station_circle_radius_size" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_start_station_circle_borner_color" />
<corners android:radius="@dimen/bus_p_station_circle_radius_size" />
</shape>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="@dimen/bus_p_station_tag_width_height"
android:height="@dimen/bus_p_station_tag_width_height">
<shape android:shape="rectangle">
<corners android:radius="@dimen/bus_p_station_tag_radius_size"/>
<gradient
android:angle="90"
android:endColor="@color/bus_p_start_tag_bg_color1"
android:startColor="@color/bus_p_start_tag_bg_color2"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_traffic_light_bg_color"/>
<corners android:radius="@dimen/bus_p_route_traffic_light_view_corner"/>
<stroke android:color="@color/bus_p_traffic_light_bg_stroke"
android:width="@dimen/bus_p_traffic_light_bg_stroke_width"/>
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:angle="180"
android:endColor="#B6CCF5"
android:startColor="#CDDBF6"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="270"
android:startColor="#D8E4FF"
android:endColor="#D8E4FF"
android:type="linear"/>
<corners android:radius="@dimen/dp_30"/>
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#F2F6FF"
android:startColor="#E1E7F5"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="@dimen/dp_10" />
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item android:id="@android:id/progress">
<scale
android:drawable="@drawable/progress_item_round"
android:scaleWidth="100%" />
</item>
</layer-list>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:bottomLeftRadius="@dimen/dp_60"
android:bottomRightRadius="@dimen/dp_30"
android:topRightRadius="@dimen/dp_30"/>
<gradient
android:angle="0"
android:endColor="#009EFF"
android:startColor="#4D006AFF"
android:type="linear" />
</shape>

View File

@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mogo.eagle.core.function.view.MapBizView
android:id="@+id/mapBizView"
android:layout_width="@dimen/dp_1860"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugViewTrigger
android:layout_width="@dimen/dp_400"
android:layout_height="@dimen/dp_100"
android:longClickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.mogo.eagle.core.function.hmi.ui.widget.SteeringWheelView
android:id="@+id/steering_wheel"
android:layout_width="@dimen/dp_490"
android:layout_height="@dimen/dp_490"
android:layout_marginLeft="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_88"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bus_p_autopilot_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_curent_station_panel_margin"
android:layout_marginTop="@dimen/dp_112"
android:scaleType="fitXY"
android:visibility="gone"
android:layout_gravity="center_horizontal"
android:src="@drawable/bus_p_un_auto_nor"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!--浓雾预警动画-->
<com.mogo.eagle.core.function.hmi.ui.widget.V2XFogEventView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--pnc行为决策-->
<com.mogo.eagle.core.function.hmi.ui.vehicle.PncActionsView
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_100"
android:layout_marginBottom="@dimen/dp_110"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.mogo.och.common.module.wigets.OCHBorderShadowLayout
android:id="@+id/arrive_station_shadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_curent_station_panel_margin_left"
android:layout_marginBottom="@dimen/bus_p_curent_station_panel_margin"
app:bgColor="@android:color/transparent"
app:blurRadius="@dimen/dp_30"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:shadowColor="@color/bus_p_panel_edge_shadow"
app:shadowRadius="@dimen/dp_30"
app:xOffset="0dp"
app:yOffset="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/bus_p_curent_station_panel_width"
android:layout_height="@dimen/bus_p_curent_station_panel_height"
android:layout_margin="@dimen/dp_10"
android:background="@drawable/bus_p_panel_cur_station_panel">
<TextView
android:id="@+id/bus_p_cur_station_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_56"
android:layout_marginTop="@dimen/dp_40"
android:elevation="@dimen/dp_10"
android:text="@string/bus_p_cur_station_title"
android:textColor="@color/bus_p_panel_cur_txt_color"
android:textSize="@dimen/bus_p_curent_station_txt_size"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bus_p_cur_station_name"
android:layout_width="@dimen/bus_p_curent_station_txt_width"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:elevation="@dimen/dp_10"
android:ellipsize="end"
android:maxLines="1"
android:text="-- --"
android:textColor="@color/bus_p_panel_cur_station_txt_color"
android:textSize="@dimen/bus_p_curent_station_txt_size1"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_cur_station_title"
app:layout_constraintTop_toBottomOf="@+id/bus_p_cur_station_title" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_27"
app:layout_constraintTop_toTopOf="@+id/bus_p_cur_station_name"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_cur_station_name"
app:layout_constraintRight_toLeftOf="@+id/bus_p_cur_station_name"
android:layout_marginRight="@dimen/dp_10"
android:src="@drawable/station_arrow">
</androidx.appcompat.widget.AppCompatImageView>
<TextView
android:id="@+id/bus_p_cur_station_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_20"
android:elevation="@dimen/dp_10"
android:text="@string/bus_p_cur_station_arrived_tip"
android:textColor="@color/bus_p_panel_cur_station_tips_color"
android:textSize="@dimen/bus_p_curent_station_tip_size1"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_cur_station_name"
app:layout_constraintTop_toBottomOf="@+id/bus_p_cur_station_name" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/bus_progress_bar"
android:layout_width="0dp"
android:layout_height="@dimen/dp_10"
android:progress="0"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="@dimen/dp_12"
android:layout_marginRight="@dimen/dp_15"
app:layout_constraintRight_toRightOf="parent"
android:progressDrawable="@drawable/bus_progress_bar_bg" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.och.common.module.wigets.OCHBorderShadowLayout>
<FrameLayout
android:id="@+id/bus_p_route_panel"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="@dimen/dp_299"
android:layout_height="@dimen/dp_75"
android:layout_marginRight="@dimen/dp_40"
android:layout_marginBottom="@dimen/dp_48"
android:src="@drawable/bus_p_mogo_nor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/bus_p_route_panel" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent">
<com.amap.api.maps.TextureMapView
android:id="@+id/bus_p_line_amap_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bus_p_no_order_data_view">
<ImageView
android:id="@+id/no_order_data_iv"
android:layout_width="@dimen/dp_386"
android:layout_height="@dimen/dp_350"
android:src="@drawable/bus_p_no_order_data"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/no_order_data_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/bus_p_no_data_color"
android:textSize="@dimen/bus_p_no_data_size"
android:layout_marginTop="50dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_order_data_iv"
android:text="@string/bus_p_no_out"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<com.mogo.och.common.module.wigets.OCHBorderShadowLayout
android:id="@+id/edge_view"
android:layout_width="725dp"
android:layout_height="match_parent"
app:shadowColor="@color/bus_p_route_view_left_edge_shadow"
app:xOffset="0dp"
app:yOffset="0dp"
app:bgColor="@android:color/transparent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/bus_p_route_info_panel_width"
android:layout_height="match_parent"
android:background="@android:color/transparent" />
</com.mogo.och.common.module.wigets.OCHBorderShadowLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/bus_p_route_info_panel_width"
android:layout_height="match_parent"
android:background="@drawable/bus_p_route_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/bus_p_speed_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_route_info_margin_left"
android:layout_marginTop="@dimen/bus_p_route_info_margin_top"
android:includeFontPadding="false"
android:letterSpacing="-0.05"
android:text="0"
android:textColor="@color/bus_p_speed_txt_color"
android:textSize="@dimen/bus_p_speed_txt_size"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bus_p_unit_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/bus_p_route_info_margin_right"
android:layout_marginBottom="@dimen/dp_20"
android:includeFontPadding="false"
android:textStyle="bold"
android:text="@string/bus_p_speed_unit_txt"
android:textColor="@color/bus_p_speed_txt_color"
android:textSize="@dimen/bus_p_speed_unit_txt_size"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_speed_tv"
app:layout_constraintLeft_toRightOf="@+id/bus_p_speed_tv" />
<com.mogo.och.bus.passenger.ui.BusPassengerTrafficLightView
android:id="@+id/bus_p_traffic_light_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/bus_p_route_info_margin_right"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_unit_tv"/>
<View
android:id="@+id/dividing_line_1"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_route_line_dividing_view_height"
android:background="@drawable/bus_p_dividing_line_bg"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bus_p_speed_tv" />
<include
layout="@layout/bus_p_no_data_common_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/bus_p_line_map_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dividing_line_1" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bus_p_line_cl"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bus_p_line_map_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dividing_line_1">
<TextView
android:id="@+id/bus_p_driver_num_plate_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_route_info_margin_left"
android:layout_marginTop="@dimen/bus_p_driver_number_plate_margin_top"
android:text="----"
android:textColor="@color/bus_p_driver_number_plate_color"
android:textSize="@dimen/bus_p_driver_number_plate_size"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.mogo.och.common.module.wigets.MarqueeTextView
android:id="@+id/bus_p_line_name_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginRight="@dimen/dp_20"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:text="----"
app:customGap="0.5"
app:useCustomGap="true"
android:textColor="@color/bus_p_line_name_color"
android:textSize="@dimen/bus_p_driver_number_plate_size"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_driver_num_plate_tv"
app:layout_goneMarginLeft="0dp" />
<TextView
android:id="@+id/line_operation_time_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/bus_p_line_operation_time_margin_top"
android:text="-- --"
android:textColor="@color/bus_p_line_operation_time_color"
android:textSize="@dimen/bus_p_line_operation_time_size"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/dividing_line_2"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_route_line_dividing_view_height"
android:layout_marginTop="@dimen/bus_p_route_dividing_line2_margin_top"
android:background="@drawable/bus_p_dividing_line_bg"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/bus_p_line_stations_rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_260"
android:paddingBottom="@dimen/dp_20"
android:paddingLeft="@dimen/dp_30"
android:paddingRight="@dimen/bus_p_route_info_margin_right"
android:requiresFadingEdge="vertical"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintTop_toBottomOf="@+id/dividing_line_2" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.mogo.och.bus.passenger.ui.BusPassengerMapDirectionView
android:id="@+id/bus_p_line_map_view"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_route_line_map_view_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<ImageView
android:id="@+id/bus_p_arrow_nor"
android:layout_width="@dimen/dp_108"
android:layout_height="@dimen/dp_107"
android:layout_marginRight="@dimen/dp_20"
android:layout_marginBottom="@dimen/dp_370"
android:src="@drawable/bus_p_arrow_nor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.mogo.och.common.module.wigets.MarqueeTextView
android:id="@+id/bus_p_station"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="--"
android:textSize="@dimen/bus_p_station_txt_size"
android:textStyle="bold"
android:includeFontPadding = "false"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:layout_marginRight="@dimen/dp_60"
android:textColor="@color/bus_p_station_txt_color"
android:layout_marginLeft="@dimen/dp_90"
app:customGap="0.5"
app:useCustomGap="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/bus_p_tag"
app:layout_constraintTop_toBottomOf="@+id/bus_p_cur_arrow_bg"/>
<ImageView
android:layout_width="62dp"
android:layout_height="62dp"
android:src="@drawable/bus_p_point_gray"
app:layout_constraintTop_toTopOf="@+id/bus_p_circle"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_circle"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_circle"
app:layout_constraintRight_toRightOf="@+id/bus_p_circle"/>
<ImageView
android:id="@+id/bus_p_circle"
android:layout_width="62dp"
android:layout_height="62dp"
android:src="@drawable/bus_p_point_blue"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_station"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_station"/>
<ImageView
android:id="@+id/bus_p_cur_arrow_bg"
android:layout_width="@dimen/dp_12"
android:layout_height="@dimen/dp_61"
android:scaleType="fitXY"
android:layout_marginLeft="8dp"
android:src="@drawable/bus_p_line_blue"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_circle"
app:layout_constraintRight_toRightOf="@+id/bus_p_circle"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/bus_p_tag"
android:layout_width="@dimen/bus_p_station_tag_width_height"
android:layout_height="@dimen/bus_p_station_tag_width_height"
android:background="@drawable/bg_bus_p_end_tag_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_circle"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_circle"/>
<TextView
android:id="@+id/bus_p_tag_txt"
android:layout_width="@dimen/bus_p_station_tag_width_height"
android:layout_height="@dimen/bus_p_station_tag_width_height"
android:textSize="@dimen/bus_p_station_tag_txt_size"
android:textColor="@color/bus_p_end_tag_txt_color"
android:text="@string/bus_p_end_station_txt_tag"
android:includeFontPadding="false"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_tag"
app:layout_constraintRight_toRightOf="@+id/bus_p_tag"
app:layout_constraintTop_toTopOf="@+id/bus_p_tag"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_tag"/>
<androidx.constraintlayout.widget.Group
android:id="@+id/group_station_tag_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="bus_p_tag,bus_p_tag_txt"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/bus_p_route_traffic_light_view_width"
android:layout_height="@dimen/bus_p_route_traffic_light_view_height"
android:visibility="visible">
<ImageView
android:id="@+id/bus_p_traffic_light_bg"
android:layout_width="@dimen/bus_p_traffic_light_bg_width"
android:layout_height="@dimen/bus_p_traffic_light_bg_height"
android:background="@drawable/bg_bus_p_traffic_light_background"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bus_p_traffic_light_iv"
android:layout_width="@dimen/bus_p_traffic_light_icon_size"
android:layout_height="@dimen/bus_p_traffic_light_icon_size"
android:layout_marginTop="@dimen/dp_8"
android:scaleType="fitXY"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/bus_p_traffic_light_time_tv"
android:layout_width="@dimen/bus_p_traffic_light_time_view_width"
android:layout_height="match_parent"
android:textSize="@dimen/bus_p_traffic_light_time_size"
android:textStyle="bold"
android:textColor="@color/bus_p_traffic_txt_color"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="bus_p_speed_txt_color">#2D3E5F</color>
<color name="bus_p_traffic_light_bg_color">#CCE9EFFC</color>
<color name="bus_p_traffic_light_bg_stroke">#C7D2E1</color>
<color name="bus_p_driver_number_plate_color">#2D3E5F</color>
<color name="bus_p_line_name_color">#0043FF</color>
<color name="bus_p_line_operation_time_color">#2D3E5F</color>
<color name="bus_p_no_data_color">#596A8A</color>
<color name="bus_p_station_circle_color">#D8E5F8</color>
<color name="bus_p_start_station_circle_borner_color">#FFB327</color>
<color name="bus_p_station_txt_color">#2D3E5F</color>
<color name="bus_p_current_station_txt_color">#0043FF</color>
<color name="bus_p_middle_station_circle_color2">#276AFE</color>
<color name="bus_p_middle_station_circle_color1">#0043FF</color>
<color name="bus_p_end_station_circle_borner_color">#276AFE</color>
<color name="bus_p_start_tag_bg_color1">#FFC125</color>
<color name="bus_p_start_tag_bg_color2">#FF8131</color>
<color name="bus_p_end_tag_bg_color1">#31BFF2</color>
<color name="bus_p_end_tag_bg_color2">#3257E9</color>
<color name="bus_p_end_tag_txt_color">#FFFFFF</color>
<color name="bus_p_tag_line_color">#CDDBF6</color>
<color name="bus_p_panel_cur_txt_color">#2D3E5F</color>
<color name="bus_p_panel_cur_station_txt_color">#0043FF</color>
<color name="bus_p_panel_cur_station_tips_color">#2D3E5F</color>
<color name="bus_p_panel_cur_station_panel_color">#E6E9EFFC</color>
<color name="bus_p_route_view_left_edge_shadow">#33394C63</color>
<color name="bus_p_traffic_txt_color">#2D3E5F</color>
<color name="bus_p_panel_edge_shadow">#33394C63</color>
</resources>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="bus_p_route_info_panel_width">700dp</dimen>
<dimen name="bus_p_auto_icon_margin_top">40dp</dimen>
<dimen name="bus_p_route_info_margin_right">40dp</dimen>
<dimen name="bus_p_route_info_margin_left">40dp</dimen>
<dimen name="bus_p_route_info_margin_bottom">40dp</dimen>
<dimen name="bus_p_route_info_margin_top">110dp</dimen>
<dimen name="bus_p_route_line_info_height">224dp</dimen>
<dimen name="bus_p_route_line_map_view_height">510dp</dimen>
<dimen name="bus_p_route_line_dividing_view_height">3dp</dimen>
<dimen name="bus_p_route_traffic_light_view_width">158dp</dimen>
<dimen name="bus_p_route_traffic_light_view_height">90dp</dimen>
<dimen name="bus_p_route_traffic_light_view_corner">45dp</dimen>
<dimen name="bus_p_traffic_light_bg_width">158dp</dimen>
<dimen name="bus_p_traffic_light_bg_height">90dp</dimen>
<dimen name="bus_p_traffic_light_time_size">45dp</dimen>
<dimen name="bus_p_traffic_light_time_view_width">90dp</dimen>
<dimen name="bus_p_traffic_light_icon_size">90dp</dimen>
<dimen name="bus_p_traffic_light_bg_stroke_width">3dp</dimen>
<dimen name="bus_p_route_dividing_line2_margin_top">224dp</dimen>
<dimen name="bus_p_driver_number_plate_margin_top">50dp</dimen>
<dimen name="bus_p_driver_number_plate_margin_bottom">50dp</dimen>
<dimen name="bus_p_driver_number_plate_size">44dp</dimen>
<dimen name="bus_p_line_operation_time_margin_top">130dp</dimen>
<dimen name="bus_p_line_operation_time_size">38dp</dimen>
<dimen name="bus_p_no_data_size">36dp</dimen>
<dimen name="bus_p_speed_txt_size">110dp</dimen>
<dimen name="bus_p_speed_unit_txt_size">42dp</dimen>
<dimen name="bus_p_station_circle_borner_size">4dp</dimen>
<dimen name="bus_p_station_circle_radius_size">10dp</dimen>
<dimen name="bus_p_station_circle_width_height">20dp</dimen>
<dimen name="bus_p_station_tag_width_height">60dp</dimen>
<dimen name="bus_p_station_tag_radius_size">30dp</dimen>
<dimen name="bus_p_cur_station_circle_width">20dp</dimen>
<dimen name="bus_p_cur_station_circle_height">50dp</dimen>
<dimen name="bus_p_mid_station_circle_cor">6dp</dimen>
<dimen name="bus_p_station_txt_size">50dp</dimen>
<dimen name="bus_p_station_tag_txt_size">36dp</dimen>
<dimen name="bus_p_station_item_height">80dp</dimen>
<dimen name="bus_p_station_item_middle_height">100dp</dimen>
<dimen name="bus_p_station_tag_line_height">80dp</dimen>
<dimen name="bus_p_station_tag_line_height1">60dp</dimen>
<dimen name="bus_p_station_tag_line_width">6dp</dimen>
<dimen name="bus_p_curent_station_panel_width">685dp</dimen>
<dimen name="bus_p_curent_station_panel_height">309dp</dimen>
<dimen name="bus_p_curent_station_panel_margin">50dp</dimen>
<dimen name="bus_p_curent_station_panel_margin_left">10dp</dimen>
<dimen name="bus_p_curent_station_txt_size">44dp</dimen>
<dimen name="bus_p_curent_station_txt_size1">55dp</dimen>
<dimen name="bus_p_curent_station_tip_size1">40dp</dimen>
<dimen name="bus_p_curent_station_txt_width">584dp</dimen>
<dimen name="bus_p_station_txt_width">550dp</dimen>
</resources>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="bus_p_speed_unit_txt">KM/H</string>
<string name="bus_p_no_out">您已收车</string>
<string name="bus_p_no_task">暂无班次</string>
<string name="bus_p_start_station_txt_tag"></string>
<string name="bus_p_end_station_txt_tag"></string>
<string name="bus_p_cur_station_title">到达站:</string>
<string name="bus_p_cur_next_station_title">下一站:</string>
<string name="bus_p_cur_station_title_init">始发站:</string>
<string name="bus_p_cur_station_arrived_tip">请携带好随身物品下车。</string>
<string name="bus_p_cur_station_arrived_tip_init">欢迎乘坐蘑菇车联自动驾驶车。</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More