[shuttle]
[分离shuttle]
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
OCH/mogo-och-shuttle-passenger/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
15
OCH/mogo-och-shuttle-passenger/README.md
Normal 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 普通代码测试
|
||||
83
OCH/mogo-och-shuttle-passenger/build.gradle
Normal 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()
|
||||
0
OCH/mogo-och-shuttle-passenger/consumer-rules.pro
Normal file
3
OCH/mogo-och-shuttle-passenger/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
GROUP=com.mogo.och
|
||||
POM_ARTIFACT_ID=och-bus-passenger
|
||||
VERSION_CODE=1
|
||||
21
OCH/mogo-och-shuttle-passenger/proguard-rules.pro
vendored
Normal 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
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:已出车
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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:taxi,10: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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.mogo.och.bus.passenger.callback;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/3/10
|
||||
*/
|
||||
public interface IBusPassengerMapViewCallback {
|
||||
void onCameraChange(float bearing);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
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.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
|
||||
|
||||
/**
|
||||
* 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"))
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mogo.och.bus.passenger.network;
|
||||
|
||||
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
|
||||
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest;
|
||||
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
/**
|
||||
* Created on 2022/3/31
|
||||
*
|
||||
* Bus乘客端接口定义
|
||||
*/
|
||||
interface ShettlePassengerServiceApi {
|
||||
/**
|
||||
* 查询bus司机端绑定路线
|
||||
* @return 接口返回数据
|
||||
*/
|
||||
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
|
||||
@POST( "/och-shuttle-cabin/api/business/v1/passenger/lineDataWithDriver/query" )
|
||||
Observable<BusPassengerRoutesResponse> queryDriverSiteByCoordinate(@Header("appId") String appId, @Header("ticket") String ticket, @Body BusPassengerQueryLineRequest request);
|
||||
|
||||
/**
|
||||
* 查询司机端的登陆状态
|
||||
* @param sn
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
// @GET("/autopilot-car-hailing/car/v2/driver/bus/passenger/takeOrderStatus/query")
|
||||
@GET("/och-shuttle-cabin/api/business/v1/passenger/loginStatus")
|
||||
Observable<BusPassengerOperationStatusResponse> queryDriverOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
|
||||
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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\">   剩余 </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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 765 B |
|
After Width: | Height: | Size: 797 B |
|
After Width: | Height: | Size: 795 B |
|
After Width: | Height: | Size: 765 B |
|
After Width: | Height: | Size: 879 B |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 628 B |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 594 B |
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mogo.och.bus.passenger">
|
||||
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
</manifest>
|
||||
BIN
OCH/mogo-och-shuttle-passenger/src/m2/assets/m2_map_style.data
Normal file
@@ -0,0 +1,92 @@
|
||||
package com.mogo.och.bus.passenger
|
||||
|
||||
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.commons.module.status.IMogoStatusChangedListener
|
||||
import com.mogo.commons.module.status.MogoStatusManager
|
||||
import com.mogo.commons.module.status.StatusDescriptor
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
|
||||
import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager.stepInDayMode
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.och.bus.passenger.constant.BusPassengerConst
|
||||
import com.mogo.och.bus.passenger.ui.PM2BaseFragment
|
||||
|
||||
/**
|
||||
* 网约车-Bus-乘客端
|
||||
*
|
||||
* Created on 2022/3/29
|
||||
*/
|
||||
@Route(path = BusPassengerConst.PATH)
|
||||
class MogoOCHBusPassenger : IMogoOCH, IMogoStatusChangedListener {
|
||||
private var mActivity: FragmentActivity? = null
|
||||
private var mContainerId = 0
|
||||
private var mPM2Fragment: PM2BaseFragment? = null
|
||||
override fun createCoverage(activity: FragmentActivity, containerId: Int) {}
|
||||
override fun createCoverage(activity: FragmentActivity?, containerId: Int?): Fragment? {
|
||||
mActivity = activity
|
||||
mContainerId = containerId!!
|
||||
// if (MogoStatusManager.getInstance().isScreenCoverDismiss){
|
||||
showFragment()
|
||||
// }else{
|
||||
// MogoStatusManager.getInstance()
|
||||
// .registerStatusChangedListener("ochM2Passenger", StatusDescriptor.SCREEN_COVER, this)
|
||||
// }
|
||||
return null
|
||||
}
|
||||
|
||||
override val functionName: String
|
||||
get() = "och-bus-passenger-m2"
|
||||
|
||||
override fun onDestroy() {
|
||||
// 若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
|
||||
mActivity?.finish()
|
||||
}
|
||||
|
||||
override fun init(context: Context) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入鹰眼模式,设置手势缩放地图失效
|
||||
*/
|
||||
private fun stepIntoVrMode() {
|
||||
d(SceneConstant.M_TAXI_P + TAG, "进入vr模式")
|
||||
getMapUIController()?.stepInVrMode(true) // 白天模式
|
||||
stepInDayMode() //白天模式 状态栏字体颜色变黑
|
||||
}
|
||||
|
||||
private fun showFragment() {
|
||||
if (mPM2Fragment == null) {
|
||||
d(SceneConstant.M_TAXI_P + TAG, "准备add fragment======")
|
||||
mPM2Fragment = PM2BaseFragment()
|
||||
mActivity?.supportFragmentManager?.beginTransaction()
|
||||
?.add(mContainerId, mPM2Fragment!!)?.commitAllowingStateLoss()
|
||||
}
|
||||
d(SceneConstant.M_TAXI_P + TAG, "准备show fragment")
|
||||
mActivity?.supportFragmentManager?.beginTransaction()?.show(mPM2Fragment!!)
|
||||
?.commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
private fun hideFragment() {
|
||||
if (mPM2Fragment != null) {
|
||||
mActivity?.supportFragmentManager?.beginTransaction()?.hide(mPM2Fragment!!)
|
||||
?.commitAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = MogoOCHBusPassenger::class.java.simpleName
|
||||
}
|
||||
|
||||
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
|
||||
if (descriptor == StatusDescriptor.SCREEN_COVER){
|
||||
if (isTrue){
|
||||
showFragment()
|
||||
}else{
|
||||
hideFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 PM2OperationStatusResponse extends BaseData {
|
||||
|
||||
public Result data;
|
||||
|
||||
public static class Result {
|
||||
private String sn; //司机屏sn
|
||||
private String phone; //司机手机号
|
||||
public String plateNumber; //车牌号
|
||||
public int driverStatus;//0:已收车,1:已出车
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mogo.och.bus.passenger.bean;
|
||||
|
||||
public
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2021/3/22
|
||||
*
|
||||
* 根据车机行驶线路站点信息
|
||||
*/
|
||||
class PM2QueryLineRequest {
|
||||
|
||||
private String sn;
|
||||
public PM2QueryLineRequest(String sn) {
|
||||
this.sn = sn;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mogo.och.bus.passenger.bean;
|
||||
|
||||
import com.mogo.eagle.core.data.BaseData;
|
||||
|
||||
/**
|
||||
* 网约车小巴路线接口请求响应结果 返回的是对应司机屏的线路信息
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class PM2RoutesResponse extends BaseData {
|
||||
private PM2RoutesResult data;
|
||||
|
||||
public PM2RoutesResult getResult() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setResult(PM2RoutesResult data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OchBusRoutesResponse{" +
|
||||
"data=" + data +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.mogo.och.bus.passenger.bean;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 网约车小巴路线接口返回接口数据封装
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class PM2RoutesResult {
|
||||
private List<PM2Station> 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<PM2Station> 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;
|
||||
PM2RoutesResult that = (PM2RoutesResult) 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.mogo.och.bus.passenger.bean;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 单个网约车小巴车站信息
|
||||
*
|
||||
* @author wangmingjun
|
||||
*/
|
||||
public class PM2Station {
|
||||
|
||||
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:taxi,10: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;
|
||||
PM2Station that = (PM2Station) 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.mogo.och.bus.passenger.callback
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2023/2/15
|
||||
*/
|
||||
interface ADASCallback {
|
||||
fun updateHDMapStations(stations: MutableList<MutableList<Double>>)
|
||||
fun removeHDMapStations()
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.mogo.och.bus.passenger.callback
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2023/2/13
|
||||
*/
|
||||
interface AutoPilotStatusCallback {
|
||||
/**
|
||||
* false: 未开启自驾, true : 开启自驾
|
||||
*/
|
||||
fun updateAutoStatus(isOpen: Boolean)
|
||||
|
||||
fun updateAutoStatus(status: Int)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.mogo.och.bus.passenger.callback
|
||||
|
||||
import com.mogo.och.bus.passenger.bean.PM2Station
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2023/2/2
|
||||
*/
|
||||
interface DrivingInfoCallback {
|
||||
fun updateSpeed(speed: Int)
|
||||
fun updatePlateNumber(carNum: String)
|
||||
fun updateLine(lineName: String, lineDuring: String)
|
||||
fun updateRemainMT(meters : Long, timeInSecond : Long) // 米,秒
|
||||
fun changeOperationStatus(loginStatus : Boolean)
|
||||
fun showNoTaskView(isTrue : Boolean)
|
||||
fun updateLineStations(stations: MutableList<PM2Station>)
|
||||
fun updateStationsInfo(stations: MutableList<PM2Station>, i: Int, isArrived: Boolean)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mogo.och.bus.passenger.constant
|
||||
|
||||
/**
|
||||
* Created on 2021/12/6
|
||||
*/
|
||||
class M2Const {
|
||||
companion object {
|
||||
//站点UUID
|
||||
const val M2_MAP_STATION_MAKER = "m2_map_station_maker"
|
||||
|
||||
/**
|
||||
* Marker类型
|
||||
*/
|
||||
const val TYPE_MARKER_M2_LINE = "TYPE_MARKER_M2_LINE"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mogo.och.bus.passenger.model
|
||||
|
||||
import android.content.Context
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.och.bus.passenger.bean.PM2Station
|
||||
import com.mogo.och.bus.passenger.callback.ADASCallback
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2023/2/2
|
||||
*/
|
||||
class PM2ADASModel private constructor() {
|
||||
|
||||
private var mContext: Context? = null
|
||||
private var mAdasCallback: ADASCallback? = null
|
||||
|
||||
companion object {
|
||||
val TAG = PM2ADASModel::class.java.simpleName
|
||||
val INSTANCE: PM2ADASModel by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
PM2ADASModel()
|
||||
}
|
||||
}
|
||||
|
||||
fun init(context : Context){
|
||||
this.mContext = context
|
||||
}
|
||||
|
||||
fun setAdasCallback(adasCallback: ADASCallback?){
|
||||
this.mAdasCallback = adasCallback
|
||||
}
|
||||
|
||||
fun updateHDMapStations(stations: MutableList<PM2Station>){
|
||||
var stationsList = mutableListOf<MutableList<Double>>()
|
||||
for (i in stations.indices){
|
||||
var listLatLng = mutableListOf<Double>() // 0: long 1:lat
|
||||
listLatLng.add(stations[i].lon)
|
||||
listLatLng.add(stations[i].lat)
|
||||
stationsList.add(listLatLng)
|
||||
}
|
||||
mAdasCallback?.updateHDMapStations(stationsList)
|
||||
}
|
||||
|
||||
fun removeHDMapStations(){
|
||||
mAdasCallback?.removeHDMapStations()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,530 @@
|
||||
package com.mogo.och.bus.passenger.model
|
||||
|
||||
import android.content.Context
|
||||
import android.media.AudioAttributes
|
||||
import android.media.AudioFocusRequest
|
||||
import android.media.AudioManager
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.mogo.commons.module.intent.IMogoIntentListener
|
||||
import com.mogo.commons.module.intent.IntentManager
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.commons.voice.IMogoVoiceCmdCallBack
|
||||
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.api.telematic.IReceivedMsgListener
|
||||
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.function.call.telematic.CallerTelematicListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
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.PM2OperationStatusResponse
|
||||
import com.mogo.och.bus.passenger.bean.PM2RoutesResponse
|
||||
import com.mogo.och.bus.passenger.bean.PM2RoutesResult
|
||||
import com.mogo.och.bus.passenger.bean.PM2Station
|
||||
import com.mogo.och.bus.passenger.callback.AutoPilotStatusCallback
|
||||
import com.mogo.och.bus.passenger.callback.DrivingInfoCallback
|
||||
import com.mogo.och.bus.passenger.constant.BusPassengerConst
|
||||
import com.mogo.och.bus.passenger.network.PM2ModelLoopManager
|
||||
import com.mogo.och.common.module.bean.AppConnectMsg
|
||||
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager
|
||||
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
|
||||
import com.mogo.och.common.module.biz.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2023/1/31
|
||||
*/
|
||||
class PM2DrivingModel private constructor() {
|
||||
|
||||
private var mContext: Context? = null
|
||||
private var mLocation: MogoLocation? = null
|
||||
|
||||
private var mRoutePoints = mutableListOf<MogoLocation>()
|
||||
private var routesResult: PM2RoutesResult? = null
|
||||
|
||||
private var mCurrentAutoStatus = -1
|
||||
|
||||
var mStations = mutableListOf<PM2Station>()
|
||||
private var mNextStationIndex = 0 // A-B要到达站的index
|
||||
private var isGoingToNextStation = false //是否前往下一站过程中
|
||||
|
||||
private var mTwoStationsRouts = mutableListOf<MogoLocation>()
|
||||
private var mPreRouteIndex = 0
|
||||
private var mWipePreIndex = 0
|
||||
|
||||
private var mDrivingInfoCallback: DrivingInfoCallback? = null //行程信息
|
||||
private var mAutoStatusCallback: AutoPilotStatusCallback? = null //自动驾驶状态
|
||||
|
||||
private var operationStatus: PM2OperationStatusResponse.Result? = null
|
||||
|
||||
private val handler = Handler(Handler.Callback { msg ->
|
||||
if (msg.what == MSG_QUERY_BUS_P_STATION) {
|
||||
queryDriverOperationStatus()
|
||||
return@Callback true
|
||||
}
|
||||
false
|
||||
})
|
||||
|
||||
companion object {
|
||||
val TAG = PM2DrivingModel::class.java.simpleName
|
||||
const val MSG_QUERY_BUS_P_STATION = 1001
|
||||
val INSTANCE: PM2DrivingModel by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
PM2DrivingModel()
|
||||
}
|
||||
}
|
||||
|
||||
fun init(context : Context){
|
||||
mContext = context
|
||||
initListener()
|
||||
// TODO: 2022/3/31
|
||||
queryDriverOperationStatus()
|
||||
startOrStopOrderLoop(true)
|
||||
}
|
||||
|
||||
private fun initListener() {
|
||||
//自动驾驶状态监听
|
||||
CallerAutoPilotStatusListenerManager.addListener(TAG, mAutoPilotStatusListener)
|
||||
|
||||
// 定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, mMapLocationListener)
|
||||
// CallerChassisLocationGCJ02ListenerManager.setListenerHz(TAG,2)//设置2hz, 1s返回2次
|
||||
|
||||
//司乘屏通信监听
|
||||
CallerTelematicListenerManager.addListener(TAG,mReceivedMsgListener)
|
||||
|
||||
//自动驾驶轨迹监听
|
||||
CallerPlanningRottingListenerManager.addListener(TAG, moGoAutopilotPlanningListener)
|
||||
|
||||
//网络监听
|
||||
IntentManager.getInstance().registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener)
|
||||
|
||||
}
|
||||
|
||||
fun releaseListener(){
|
||||
//自动驾驶状态监听
|
||||
CallerAutoPilotStatusListenerManager.removeListener(TAG)
|
||||
|
||||
// 定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
|
||||
|
||||
CallerTelematicListenerManager.removeListener(TAG)
|
||||
|
||||
//自动驾驶轨迹监听
|
||||
CallerPlanningRottingListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
fun setDrivingInfoCallback(drivingInfoCallback : DrivingInfoCallback?){
|
||||
mDrivingInfoCallback = drivingInfoCallback
|
||||
}
|
||||
|
||||
fun setAutoStatusCallback(autoPilotStatusCallback: AutoPilotStatusCallback?){
|
||||
mAutoStatusCallback = autoPilotStatusCallback
|
||||
}
|
||||
|
||||
private val mNetWorkIntentListener = IMogoIntentListener { intentStr, _ ->
|
||||
if (ConnectivityManager.CONNECTIVITY_ACTION == intentStr) {
|
||||
if (NetworkUtils.isConnected(mContext)) {
|
||||
queryDriverOperationStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val mReceivedMsgListener: IReceivedMsgListener =
|
||||
object : IReceivedMsgListener{
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
override fun onReceivedMsg(type: Int, byteArray: ByteArray) {//接收司机端发来的信息
|
||||
if (OchCommonConst.BUSINESS_STRING == type){
|
||||
val msg = GsonUtils.fromJson(String(byteArray),AppConnectMsg::class.java) as AppConnectMsg
|
||||
Logger.d(SceneConstant.M_BUS_P+TAG,"onReceivedMsg = "+GsonUtils.toJson(msg))
|
||||
if (msg.isPlay){ //播报
|
||||
speakTTS(msg.msg)
|
||||
}
|
||||
if (msg.isViewShow){ //消息盒子显示内容
|
||||
OCHSocketMessageManager.pushAppOperationalMsgBox(
|
||||
DateTimeUtil.getCurrentTimeStamp(),msg.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun speakTTS(msg: String) {
|
||||
|
||||
var mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
var mAudioAttributes = AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_MEDIA) //设置声音的用途
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) //设置声音的类型
|
||||
.build()
|
||||
var mAudioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) //设置焦点类型
|
||||
.setAudioAttributes(mAudioAttributes) //设置声音属性
|
||||
.setAcceptsDelayedFocusGain(false) //设置接受延迟获取焦点,需要设置OnAudioFocusChangeListener来监听焦点的获取
|
||||
.build()
|
||||
mAudioManager.requestAudioFocus(mAudioFocusRequest) //抢占焦点
|
||||
|
||||
AIAssist.getInstance(mContext).speakTTSVoiceWithLevel(msg,AIAssist.LEVEL0,object : IMogoVoiceCmdCallBack{
|
||||
override fun onSpeakEnd(speakText: String?) {
|
||||
mAudioManager.abandonAudioFocusRequest(mAudioFocusRequest)
|
||||
}
|
||||
|
||||
override fun onSpeakError(speakText: String?, errorMsg: String?) {
|
||||
mAudioManager.abandonAudioFocusRequest(mAudioFocusRequest)
|
||||
}
|
||||
|
||||
override fun onSpeakSelectTimeOut(speakText: String?) {
|
||||
mAudioManager.abandonAudioFocusRequest(mAudioFocusRequest)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
|
||||
object : IMoGoChassisLocationGCJ02Listener{
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
if (null == mogoLocation) return
|
||||
mLocation = mogoLocation
|
||||
updateSpeed(mogoLocation)
|
||||
}
|
||||
}
|
||||
|
||||
private val moGoAutopilotPlanningListener = object : IMoGoPlanningRottingListener{
|
||||
override fun onAutopilotRotting(globalPathResp: MessagePad.GlobalPathResp?) {
|
||||
d(SceneConstant.M_BUS_P + TAG, "och-rotting==globalPathResp = " + GsonUtils.toJson(globalPathResp))
|
||||
globalPathResp?.let {
|
||||
d(SceneConstant.M_BUS_P + TAG, "och-rotting==wayPointsSize = " + it.wayPointsList.size)
|
||||
updateRoutePoints(it.wayPointsList)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun updateRoutePoints(routePoints: List<MessagePad.Location>?) {
|
||||
mRoutePoints.clear()
|
||||
val latLngModels = CoordinateCalculateRouteUtil
|
||||
.coordinateConverterWgsToGcjLocations(mContext, routePoints)
|
||||
d(SceneConstant.M_BUS_P + TAG, "och-rotting==latLngModels = " + latLngModels.size)
|
||||
mRoutePoints.addAll(latLngModels)
|
||||
calculateTwoStationsRoute()
|
||||
}
|
||||
|
||||
private fun updateSpeed(mogoLocation: MogoLocation) {
|
||||
// km/h
|
||||
val speedKM = (abs(mogoLocation.gnssSpeed) * 3.6f).toInt()
|
||||
|
||||
mDrivingInfoCallback?.updateSpeed(speedKM)
|
||||
}
|
||||
|
||||
private val mAutoPilotStatusListener: IMoGoAutopilotStatusListener =
|
||||
object : IMoGoAutopilotStatusListener {
|
||||
|
||||
override fun onAutopilotArriveAtStation(arrivalNotification: MessagePad.ArrivalNotification?) {
|
||||
super.onAutopilotArriveAtStation(arrivalNotification)
|
||||
}
|
||||
|
||||
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
|
||||
super.onAutopilotStatusResponse(autoPilotStatusInfo)
|
||||
val status = autoPilotStatusInfo.state
|
||||
if (mCurrentAutoStatus == status) return
|
||||
d(SceneConstant.M_BUS_P+TAG, "onAutopilotStatusResponse ===== $status")
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != status){
|
||||
//美化模式下且行程中
|
||||
if (FunctionBuildConfig.isDemoMode &&
|
||||
mNextStationIndex>= 0 && mNextStationIndex <= mStations.size - 1
|
||||
&& isGoingToNextStation){
|
||||
mAutoStatusCallback?.updateAutoStatus(true)
|
||||
}else{//非美化模式下
|
||||
mAutoStatusCallback?.updateAutoStatus(false)
|
||||
}
|
||||
|
||||
}else{//自驾状态 2
|
||||
mAutoStatusCallback?.updateAutoStatus(true)
|
||||
}
|
||||
mCurrentAutoStatus = status
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun queryDriverOperationDelay() {
|
||||
handler.sendEmptyMessageDelayed(MSG_QUERY_BUS_P_STATION,
|
||||
BusPassengerConst.QUERY_BUS_P_STATION_DELAY
|
||||
)
|
||||
}
|
||||
|
||||
private fun queryDriverOperationStatus() {
|
||||
mContext?.let {
|
||||
PM2ServiceManager.queryDriverOperationStatus(
|
||||
it,
|
||||
object : OchCommonServiceCallback<PM2OperationStatusResponse> {
|
||||
override fun onSuccess(data: PM2OperationStatusResponse?) {
|
||||
if (data?.data == null) return
|
||||
if (data.data.driverStatus != operationStatus?.driverStatus
|
||||
|| data.data.plateNumber != operationStatus?.plateNumber){
|
||||
d(SceneConstant.M_BUS_P+TAG, "queryDriverOperationStatus ===== 车牌或者登陆状态有变更")
|
||||
mDrivingInfoCallback?.changeOperationStatus(data.data.driverStatus == 1)
|
||||
}
|
||||
operationStatus = data.data as PM2OperationStatusResponse.Result
|
||||
// mDrivingInfoCallback?.updatePlateNumber(data.data.plateNumber)
|
||||
}
|
||||
|
||||
override fun 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 fun onFail(code: Int, msg: String) {
|
||||
//延迟3s再次查询
|
||||
queryDriverOperationDelay()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun queryDriverSiteByCoordinate(){
|
||||
mContext?.let {
|
||||
PM2ServiceManager.queryDriverSiteByCoordinate(it,
|
||||
object : OchCommonServiceCallback<PM2RoutesResponse>{
|
||||
override fun onSuccess(data: PM2RoutesResponse?) {
|
||||
|
||||
if (data == null || data.result == null){
|
||||
if (routesResult != null) {
|
||||
routesResult == null
|
||||
updateLocalOrder()
|
||||
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate= result is null")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
if (data.result != null && data.result.equals(routesResult)){
|
||||
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate= not update")
|
||||
return
|
||||
}
|
||||
|
||||
routesResult = data.result
|
||||
updatePassengerRouteInfo(data.result)
|
||||
}
|
||||
|
||||
override fun onFail(code: Int, msg: String?) {
|
||||
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate = %s", msg)
|
||||
if (code == 1003){
|
||||
queryDriverOperationDelay()
|
||||
}
|
||||
if (PM2ServiceManager.driverAppSn.isEmpty()){
|
||||
return
|
||||
}
|
||||
if (code == 1003) {
|
||||
routesResult = null
|
||||
isGoingToNextStation = false
|
||||
startOrStopCalculateRouteInfo(false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLocalOrder(){
|
||||
routesResult = null
|
||||
mNextStationIndex = 0
|
||||
isGoingToNextStation = false
|
||||
startOrStopCalculateRouteInfo(false)
|
||||
mDrivingInfoCallback?.showNoTaskView(true)
|
||||
}
|
||||
|
||||
private fun updatePassengerRouteInfo(result: PM2RoutesResult) {
|
||||
mDrivingInfoCallback?.updateLine(result.name, result.runningDur)
|
||||
if (result.sites != null) {
|
||||
mDrivingInfoCallback?.showNoTaskView(false)
|
||||
val stations: List<PM2Station> = result.sites
|
||||
mStations.clear()
|
||||
mStations.addAll(stations)
|
||||
mDrivingInfoCallback?.updateLineStations(mStations)
|
||||
for (i in stations.indices) {
|
||||
val station: PM2Station = stations[i]
|
||||
if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED
|
||||
&& station.isLeaving && i + 1 < stations.size) {
|
||||
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<PM2Station>, i + 1, false)
|
||||
if (mNextStationIndex != i + 1) {
|
||||
d(SceneConstant.M_BUS_P+TAG,"och-rotting--start ")
|
||||
mTwoStationsRouts.clear()
|
||||
startRemainRouteInfo()
|
||||
}
|
||||
isGoingToNextStation = true
|
||||
mNextStationIndex = i + 1
|
||||
return
|
||||
} else if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !station.isLeaving) {
|
||||
mPreRouteIndex = 0
|
||||
isGoingToNextStation = false
|
||||
startOrStopCalculateRouteInfo(false)
|
||||
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<PM2Station>, i, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun loopRouteAndWipe(){
|
||||
if (mRoutePoints != null && mRoutePoints.size > 0 && mLocation != null) {
|
||||
val haveArrivedIndex = CoordinateCalculateRouteUtil
|
||||
.getArrivedPointIndexNew(
|
||||
mWipePreIndex,
|
||||
mRoutePoints,
|
||||
mLocation
|
||||
)
|
||||
mWipePreIndex = haveArrivedIndex
|
||||
d(SceneConstant.M_BUS_P + TAG,
|
||||
"thread = " + Thread.currentThread().name + " haveArrivedIndex== " + haveArrivedIndex
|
||||
)
|
||||
// if (mAutopilotPlanningCallback != null) {
|
||||
// val routePoints = CoordinateCalculateRouteUtil
|
||||
// .coordinateConverterLocationToLatLng(mContext, mRoutePoints)
|
||||
// mAutopilotPlanningCallback.routeResult(routePoints, haveArrivedIndex)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
private fun startRemainRouteInfo() {
|
||||
//开启实时计算剩余距离,剩余时间,预计时间
|
||||
startOrStopCalculateRouteInfo(true)
|
||||
}
|
||||
|
||||
fun dynamicCalculateRouteInfo(){
|
||||
//计算当前位置和下一站的剩余点集合
|
||||
//计算剩余点总里程和时间
|
||||
|
||||
//计算当前位置和下一站的剩余点集合
|
||||
//计算剩余点总里程和时间
|
||||
if (mTwoStationsRouts.size == 0) {
|
||||
calculateTwoStationsRoute()
|
||||
}
|
||||
|
||||
if (mTwoStationsRouts.size > 0 && mLocation != null) {
|
||||
val lastPointsMap = CoordinateCalculateRouteUtil
|
||||
.getRemainPointListByCompareNew(mPreRouteIndex, mTwoStationsRouts, mLocation)
|
||||
for (index in lastPointsMap.keys) {
|
||||
mPreRouteIndex = index
|
||||
break
|
||||
}
|
||||
for (lastPoints in lastPointsMap.values) {
|
||||
d(SceneConstant.M_BUS_P + TAG, "och-rotting==lastPoints.size() = " + lastPoints.size)
|
||||
var lastSumLength = 0f
|
||||
lastSumLength = if (lastPoints.size == 1) { //只是最后一个点,计算当前位置和最后一个点的距离
|
||||
if (mNextStationIndex <= mStations.size - 1 && mNextStationIndex >= 0) {
|
||||
val stationNext: PM2Station = mStations[mNextStationIndex]
|
||||
CoordinateUtils.calculateLineDistance(
|
||||
stationNext.gcjLon, stationNext.gcjLat,
|
||||
mLocation!!.longitude, mLocation!!.latitude
|
||||
)
|
||||
} else {
|
||||
CoordinateUtils.calculateLineDistance(
|
||||
lastPoints[0].longitude, lastPoints[0].latitude,
|
||||
mLocation!!.longitude, mLocation!!.latitude
|
||||
)
|
||||
}
|
||||
} else {
|
||||
CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints)
|
||||
}
|
||||
val lastTime = lastSumLength / BusPassengerConst.SHUTTLE_AVERAGE_SPEED * 3.6 //秒
|
||||
d(SceneConstant.M_BUS_P + TAG, "och-rotting==lastSumLength = $lastSumLength")
|
||||
mDrivingInfoCallback?.updateRemainMT(
|
||||
lastSumLength.toLong(),
|
||||
lastTime.toLong()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateTwoStationsRoute() {
|
||||
//找出前往站对应的轨迹点,拿出两站点的集合
|
||||
d(SceneConstant.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()
|
||||
val stationNext: PM2Station = mStations[mNextStationIndex]
|
||||
val stationCur: PM2Station = mStations[mNextStationIndex - 1]
|
||||
//当前站在轨迹中对应的点
|
||||
val currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(
|
||||
0, mRoutePoints, stationCur.gcjLon, stationCur.gcjLat
|
||||
)
|
||||
//要前往的站在轨迹中对应的点
|
||||
val nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(
|
||||
currentRouteIndex,
|
||||
mRoutePoints,
|
||||
stationNext.gcjLon,
|
||||
stationNext.gcjLat
|
||||
)
|
||||
|
||||
d(SceneConstant.M_BUS_P + TAG, "och-rotting==currentRouteIndex = " + currentRouteIndex
|
||||
+ ", nextRouteIndex = " + nextRouteIndex)
|
||||
|
||||
if (currentRouteIndex < nextRouteIndex) { //如果找到的next在起点的轨迹前面,直接舍弃这个轨迹,不显示
|
||||
mTwoStationsRouts.addAll(
|
||||
mRoutePoints.subList(
|
||||
currentRouteIndex,
|
||||
nextRouteIndex + 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始轮询计算剩余里程和时间
|
||||
* @param isStart
|
||||
*/
|
||||
fun startOrStopCalculateRouteInfo(isStart: Boolean) {
|
||||
d(SceneConstant.M_BUS_P+TAG, "startOrStopCalculateRouteInfo() $isStart")
|
||||
if (isStart) {
|
||||
PM2ModelLoopManager.startCalculateRouteInfoLoop()
|
||||
} else {
|
||||
mTwoStationsRouts.clear()
|
||||
PM2ModelLoopManager.stopCalculateRouteInfLoop()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实时轨迹擦除
|
||||
* @param isStart
|
||||
*/
|
||||
private fun startOrStopRouteAndWipe(isStart: Boolean) {
|
||||
if (isStart) {
|
||||
PM2ModelLoopManager.startOrStopRouteAndWipe()
|
||||
} else {
|
||||
mWipePreIndex = 0
|
||||
PM2ModelLoopManager.stopOrStopRouteAndWipe()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startOrStopOrderLoop(start: Boolean) {
|
||||
d(SceneConstant.M_BUS_P + TAG, "startOrStopOrderLoop() $start")
|
||||
if (start) {
|
||||
PM2ModelLoopManager.startQueryDriverLineLoop()
|
||||
} else {
|
||||
PM2ModelLoopManager.stopQueryDriverLineLoop()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.mogo.och.bus.passenger.model
|
||||
|
||||
import android.content.Context
|
||||
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager.getServerToken
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.mogo.och.bus.passenger.bean.PM2OperationStatusResponse
|
||||
import com.mogo.och.bus.passenger.bean.PM2QueryLineRequest
|
||||
import com.mogo.och.bus.passenger.bean.PM2RoutesResponse
|
||||
import com.mogo.och.bus.passenger.network.PM2ServiceApi
|
||||
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 PM2ServiceManager {
|
||||
|
||||
private var mBusPassengerServiceApi =
|
||||
MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(PM2ServiceApi::class.java)
|
||||
|
||||
private var driverSnCache = ""
|
||||
/**
|
||||
* 获取Bus司机端的sn
|
||||
* @return
|
||||
*/
|
||||
public 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<PM2RoutesResponse>?
|
||||
) {
|
||||
mBusPassengerServiceApi.queryDriverSiteByCoordinate(
|
||||
MoGoAiCloudClientConfig.getInstance().serviceAppId,
|
||||
MoGoAiCloudClientConfig.getInstance().token,
|
||||
PM2QueryLineRequest(
|
||||
driverAppSn
|
||||
)
|
||||
).transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate=sn =$driverAppSn"))
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询司机端出车收车状态,以及车牌号
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
@JvmStatic
|
||||
fun queryDriverOperationStatus(
|
||||
context: Context,
|
||||
callback: OchCommonServiceCallback<PM2OperationStatusResponse>?
|
||||
) {
|
||||
mBusPassengerServiceApi.queryDriverOperationStatus(
|
||||
MoGoAiCloudClientConfig.getInstance().serviceAppId,
|
||||
MoGoAiCloudClientConfig.getInstance().token,
|
||||
driverAppSn
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus=sn =$driverAppSn"))
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.mogo.och.bus.passenger.network
|
||||
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.och.bus.passenger.constant.BusPassengerConst
|
||||
import com.mogo.och.bus.passenger.model.PM2DrivingModel
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.ObservableOnSubscribe
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2023/2/1
|
||||
*/
|
||||
object PM2ModelLoopManager {
|
||||
|
||||
private val TAG: String = PM2ModelLoopManager::class.java.getSimpleName()
|
||||
|
||||
private var mQueryLineDisposable: Disposable? = null //心跳轮询
|
||||
private var mRouteWipeDisposable: CompositeDisposable? = null //估计擦除
|
||||
private var mCalculateRouteDisposable: CompositeDisposable? = null //每隔2s计算一次剩余里程和时间
|
||||
|
||||
|
||||
fun startOrStopRouteAndWipe() {
|
||||
i(SceneConstant.M_BUS_P + TAG, "startOrStopRouteWipe()")
|
||||
if (mRouteWipeDisposable != null) return
|
||||
if (mRouteWipeDisposable == null) {
|
||||
mRouteWipeDisposable = CompositeDisposable()
|
||||
}
|
||||
val disposable = startLoopRouteAndWipe()
|
||||
.doOnSubscribe { }
|
||||
.doOnError { }
|
||||
.delay(
|
||||
BusPassengerConst.LOOP_LINE_1S,
|
||||
TimeUnit.MILLISECONDS,
|
||||
true
|
||||
) // 设置delayError为true,表示出现错误的时候也需要延迟5s进行通知,达到无论是请求正常还是请求失败,都是5s后重新订阅,即重新请求。
|
||||
.subscribeOn(Schedulers.io())
|
||||
.repeat() // repeat保证请求成功后能够重新订阅。
|
||||
.retry() // retry保证请求失败后能重新订阅
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { }
|
||||
mRouteWipeDisposable!!.add(disposable)
|
||||
}
|
||||
|
||||
fun stopOrStopRouteAndWipe() {
|
||||
if (mRouteWipeDisposable != null) {
|
||||
mRouteWipeDisposable!!.dispose()
|
||||
mRouteWipeDisposable = null
|
||||
}
|
||||
}
|
||||
|
||||
fun startQueryDriverLineLoop() {
|
||||
if (mQueryLineDisposable != null && !mQueryLineDisposable!!.isDisposed) {
|
||||
return
|
||||
}
|
||||
i(SceneConstant.M_BUS_P + TAG, "startQueryDriverLineLoop()")
|
||||
mQueryLineDisposable = Observable.interval(
|
||||
BusPassengerConst.LOOP_DELAY,
|
||||
BusPassengerConst.LOOP_LINE_2S, TimeUnit.MILLISECONDS
|
||||
)
|
||||
.map { aLong: Long -> aLong + 1 }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { aLong: Long? ->
|
||||
PM2DrivingModel.INSTANCE.queryDriverSiteByCoordinate()
|
||||
}
|
||||
}
|
||||
|
||||
fun stopQueryDriverLineLoop() {
|
||||
if (mQueryLineDisposable != null) {
|
||||
i(SceneConstant.M_BUS_P + TAG, "stopQueryDriverLineLoop()")
|
||||
mQueryLineDisposable!!.dispose()
|
||||
mQueryLineDisposable = null
|
||||
}
|
||||
}
|
||||
|
||||
fun startCalculateRouteInfoLoop() {
|
||||
i(SceneConstant.M_BUS_P + TAG, "startCalculateRouteInfoLoop()")
|
||||
if (mCalculateRouteDisposable != null) return
|
||||
if (mCalculateRouteDisposable == null) {
|
||||
mCalculateRouteDisposable = CompositeDisposable()
|
||||
}
|
||||
val disposable = startLoopCalculateRouteInfo()
|
||||
.doOnSubscribe { }
|
||||
.doOnError { }
|
||||
.delay(
|
||||
BusPassengerConst.LOOP_LINE_2S,
|
||||
TimeUnit.MILLISECONDS,
|
||||
true
|
||||
) // 设置delayError为true,表示出现错误的时候也需要延迟5s进行通知,达到无论是请求正常还是请求失败,都是5s后重新订阅,即重新请求。
|
||||
.subscribeOn(Schedulers.io())
|
||||
.repeat() // repeat保证请求成功后能够重新订阅。
|
||||
.retry() // retry保证请求失败后能重新订阅
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { }
|
||||
mCalculateRouteDisposable!!.add(disposable)
|
||||
}
|
||||
|
||||
fun stopCalculateRouteInfLoop() {
|
||||
if (mCalculateRouteDisposable != null) {
|
||||
i(SceneConstant.M_BUS_P + TAG, "stopCalculateRouteInfLoop()")
|
||||
mCalculateRouteDisposable!!.dispose()
|
||||
mCalculateRouteDisposable = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun startLoopRouteAndWipe(): Observable<Int?> {
|
||||
return Observable.create(ObservableOnSubscribe { emitter ->
|
||||
if (emitter.isDisposed) return@ObservableOnSubscribe
|
||||
PM2DrivingModel.INSTANCE.loopRouteAndWipe()
|
||||
emitter.onComplete()
|
||||
})
|
||||
}
|
||||
|
||||
private fun startLoopCalculateRouteInfo(): Observable<Int?> {
|
||||
return Observable.create(ObservableOnSubscribe { emitter ->
|
||||
if (emitter.isDisposed) return@ObservableOnSubscribe
|
||||
PM2DrivingModel.INSTANCE.dynamicCalculateRouteInfo()
|
||||
emitter.onComplete()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mogo.och.bus.passenger.network;
|
||||
|
||||
import com.mogo.och.bus.passenger.bean.PM2OperationStatusResponse;
|
||||
import com.mogo.och.bus.passenger.bean.PM2QueryLineRequest;
|
||||
import com.mogo.och.bus.passenger.bean.PM2RoutesResponse;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
/**
|
||||
* Created on 2022/3/31
|
||||
*
|
||||
* Bus乘客端接口定义
|
||||
*/
|
||||
public interface PM2ServiceApi {
|
||||
/**
|
||||
* 查询bus司机端绑定路线
|
||||
* @return 接口返回数据
|
||||
*/
|
||||
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
|
||||
@POST( "/och-shuttle-cabin/api/business/v1/passenger/lineDataWithDriver/query" )
|
||||
Observable<PM2RoutesResponse> queryDriverSiteByCoordinate(@Header("appId") String appId, @Header("ticket") String ticket, @Body PM2QueryLineRequest request);
|
||||
|
||||
/**
|
||||
* 查询司机端的登陆状态
|
||||
* @param sn
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
// @GET("/autopilot-car-hailing/car/v2/driver/bus/passenger/takeOrderStatus/query")
|
||||
@GET("/och-shuttle-cabin/api/business/v1/passenger/loginStatus")
|
||||
Observable<PM2OperationStatusResponse> queryDriverOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.mogo.och.bus.passenger.presenter
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.och.bus.passenger.callback.ADASCallback
|
||||
import com.mogo.och.bus.passenger.constant.M2Const.Companion.M2_MAP_STATION_MAKER
|
||||
import com.mogo.och.bus.passenger.model.PM2ADASModel
|
||||
import com.mogo.och.bus.passenger.ui.PM2HPMapFragment
|
||||
|
||||
class PM2ADASPresenter(view: PM2HPMapFragment?) :
|
||||
Presenter<PM2HPMapFragment?>(view), ADASCallback {
|
||||
|
||||
init {
|
||||
PM2ADASModel.INSTANCE.init(context)
|
||||
initListener()
|
||||
}
|
||||
|
||||
private fun initListener() {
|
||||
PM2ADASModel.INSTANCE.setAdasCallback(this)
|
||||
}
|
||||
|
||||
private fun removeListener() {
|
||||
PM2ADASModel.INSTANCE.setAdasCallback(null)
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
removeListener()
|
||||
}
|
||||
|
||||
override fun updateHDMapStations(stations: MutableList<MutableList<Double>>) {
|
||||
for (i in stations.indices){
|
||||
mView?.setMapMaker(M2_MAP_STATION_MAKER,stations[i])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun removeHDMapStations() {
|
||||
mView?.removeMapMaker(M2_MAP_STATION_MAKER)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.mogo.och.bus.passenger.presenter
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.bus.passenger.bean.PM2Station
|
||||
import com.mogo.och.bus.passenger.callback.AutoPilotStatusCallback
|
||||
import com.mogo.och.bus.passenger.callback.DrivingInfoCallback
|
||||
import com.mogo.och.bus.passenger.model.PM2ADASModel
|
||||
import com.mogo.och.bus.passenger.model.PM2DrivingModel
|
||||
import com.mogo.och.bus.passenger.ui.PM2DrivingInfoFragment
|
||||
|
||||
class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
|
||||
Presenter<PM2DrivingInfoFragment?>(view), DrivingInfoCallback, AutoPilotStatusCallback {
|
||||
|
||||
init {
|
||||
PM2DrivingModel.INSTANCE.init(context)
|
||||
PM2ADASModel.INSTANCE.init(context)
|
||||
initListener()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
destroyListener()
|
||||
PM2DrivingModel.INSTANCE.releaseListener()
|
||||
}
|
||||
|
||||
private fun initListener(){
|
||||
PM2DrivingModel.INSTANCE.setDrivingInfoCallback(this)
|
||||
PM2DrivingModel.INSTANCE.setAutoStatusCallback(this)
|
||||
}
|
||||
|
||||
private fun destroyListener(){
|
||||
PM2DrivingModel.INSTANCE.setDrivingInfoCallback(null)
|
||||
PM2DrivingModel.INSTANCE.setAutoStatusCallback(null)
|
||||
}
|
||||
|
||||
override fun updateSpeed(speed: Int) {
|
||||
// CallerLogger.d(
|
||||
// SceneConstant.M_BUS_P + "speed = ",speed.toString()
|
||||
// )
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateSpeed(speed)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updatePlateNumber(carNum: String) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateCarPlateNum(carNum)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateLine(lineName: String, lineDuring: String) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateTaskName(lineName)
|
||||
mView?.updateTaskDuringTime(lineDuring)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateRemainMT(meters: Long, timeInSecond: Long) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateRemainMT(meters, timeInSecond) //米,秒
|
||||
}
|
||||
}
|
||||
|
||||
override fun changeOperationStatus(loginStatus: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.changeOperationStatus(loginStatus)
|
||||
}
|
||||
}
|
||||
|
||||
override fun showNoTaskView(isTrue: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.showNoTaskView(!isTrue)
|
||||
}
|
||||
if (isTrue){
|
||||
PM2ADASModel.INSTANCE.removeHDMapStations()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateLineStations(stations: MutableList<PM2Station>) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateLineStations(stations)
|
||||
}
|
||||
PM2ADASModel.INSTANCE.updateHDMapStations(stations)
|
||||
}
|
||||
|
||||
override fun updateStationsInfo(stations: MutableList<PM2Station>, i: Int, isArrived: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateStationsInfo(stations,i,isArrived)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateAutoStatus(isOpen: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateAutoStatus(isOpen)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateAutoStatus(status: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.mogo.och.bus.passenger.presenter
|
||||
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.och.bus.passenger.ui.PM2BaseFragment
|
||||
|
||||
class PM2Presenter(view: PM2BaseFragment?) :
|
||||
Presenter<PM2BaseFragment?>(view)
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.mogo.och.bus.passenger.presenter
|
||||
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.och.bus.passenger.ui.video.PM2VideoFragment
|
||||
|
||||
class PM2VideoPresenter(view: PM2VideoFragment?) :
|
||||
Presenter<PM2VideoFragment?>(view)
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mogo.och.bus.passenger.provider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import com.mogo.och.bus.passenger.ui.widget.M2StatusBarView;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths;
|
||||
import com.mogo.eagle.core.function.api.hmi.view.IStatusViewLayout;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-06
|
||||
* <p>
|
||||
* 根据优先级控制显示 window view.
|
||||
*/
|
||||
@Route( path = MogoServicePaths.PATH_STATUS_VIEW_MANAGER )
|
||||
public class M2StatusViewManager implements IStatusViewLayout {
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getStatusView(Context context) {
|
||||
return new M2StatusBarView(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.mogo.och.bus.passenger.ui
|
||||
|
||||
import android.provider.Settings
|
||||
import android.view.Surface
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.och.bus.passenger.R
|
||||
import com.mogo.och.bus.passenger.presenter.PM2Presenter
|
||||
import com.mogo.och.bus.passenger.ui.video.PM2VideoFragment
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2BaseFragment :
|
||||
MvpFragment<PM2BaseFragment?, PM2Presenter?>() {
|
||||
|
||||
private var drivingFragment : PM2DrivingInfoFragment? = null
|
||||
private var hdMapFragment : PM2HPMapFragment? = null
|
||||
private var videoFragment : PM2VideoFragment? = null
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.p_m2_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
//横竖屏
|
||||
// setScreenDirection()
|
||||
|
||||
//隐藏小地图
|
||||
initFragment()
|
||||
}
|
||||
|
||||
// private fun setScreenDirection() {
|
||||
// var ro = Settings.System.getInt(context?.contentResolver,
|
||||
// Settings.System.USER_ROTATION,Surface.ROTATION_270)
|
||||
// if (ro != Surface.ROTATION_270){
|
||||
// ro = Surface.ROTATION_270
|
||||
// }
|
||||
// Settings.System.putInt(context?.contentResolver,
|
||||
// Settings.System.USER_ROTATION,ro)
|
||||
// }
|
||||
|
||||
/**
|
||||
* 初始化行程信息,高静地图,宣传 三个fragment
|
||||
*/
|
||||
private fun initFragment() {
|
||||
|
||||
if (drivingFragment == null) drivingFragment = PM2DrivingInfoFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.driving_fragment, drivingFragment!!)
|
||||
.show(drivingFragment!!).commitAllowingStateLoss()
|
||||
|
||||
if (hdMapFragment == null) hdMapFragment = PM2HPMapFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.hd_map_fragment, hdMapFragment!!)
|
||||
.show(hdMapFragment!!).commitAllowingStateLoss()
|
||||
|
||||
if (videoFragment == null) videoFragment = PM2VideoFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.video_fragment, videoFragment!!)
|
||||
.show(videoFragment!!).commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2Presenter {
|
||||
return PM2Presenter(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = PM2BaseFragment::class.java.simpleName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
package com.mogo.och.bus.passenger.ui
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
import com.mogo.eagle.core.utilcode.util.DateTimeUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import com.mogo.och.bus.passenger.R
|
||||
import com.mogo.och.bus.passenger.bean.PM2Station
|
||||
import com.mogo.och.bus.passenger.presenter.PM2DrivingPresenter
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil.*
|
||||
import com.mogo.och.common.module.utils.NumberFormatUtil
|
||||
import kotlinx.android.synthetic.m2.p_m2_driving_info_fragment.*
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2DrivingInfoFragment :
|
||||
MvpFragment<PM2DrivingInfoFragment?, PM2DrivingPresenter?>() {
|
||||
|
||||
// private var timeHandler: TimeHandler? = null
|
||||
|
||||
/**
|
||||
* 改变自动驾驶状态
|
||||
*
|
||||
* @param status 2 - running 1 - enable 2 - disable
|
||||
*/
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.p_m2_driving_info_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
speed_tv.setOnLongClickListener {
|
||||
context?.let { ToggleDebugView.toggleDebugView.toggle(it) }
|
||||
true
|
||||
}
|
||||
|
||||
line_name_tv.setTextColor(resources.getColor(R.color.m2_line_name_tv_color))
|
||||
station_name_tv.setTextColor(resources.getColor(R.color.m2_line_name_tv_color))
|
||||
|
||||
// current_time_tv.onClick {
|
||||
|
||||
// //测试V2X消息
|
||||
// CallerMsgBoxManager.saveMsgBox(
|
||||
// MsgBoxBean(
|
||||
// MsgBoxType.V2X,
|
||||
// V2XMsg(
|
||||
// "6666",
|
||||
// "超速行驶",
|
||||
// ""
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// val noticeTrafficStylePushData = NoticeTrafficStylePushData()
|
||||
// noticeTrafficStylePushData.content= "测试公告布局"
|
||||
// val noticeFromCloudMsg = NoticeFrCloudMsg(null, noticeTrafficStylePushData, 1)
|
||||
// CallerMsgBoxManager.saveMsgBox(
|
||||
// MsgBoxBean(
|
||||
// MsgBoxType.NOTICE, noticeFromCloudMsg)
|
||||
// )
|
||||
// BPRouteDataTestUtils.converToRouteData()
|
||||
// }
|
||||
updateCurrentTime()
|
||||
}
|
||||
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
overMapView?.let {
|
||||
it.onCreateView(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
overMapView?.let{
|
||||
it.onResume()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
overMapView?.let{
|
||||
it.onPause()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
// timeHandler?.removeCallbacksAndMessages(null)
|
||||
super.onDestroy()
|
||||
overMapView?.let{
|
||||
it.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSpeed(speed: Int){
|
||||
speed_tv.text = speed.toString()
|
||||
}
|
||||
|
||||
fun updateCarPlateNum(plateNum : String){
|
||||
|
||||
}
|
||||
|
||||
fun updateTaskName(name: String){
|
||||
line_name_tv.text = name
|
||||
}
|
||||
|
||||
fun updateTaskDuringTime(time : String){
|
||||
line_during_tv.text = time
|
||||
}
|
||||
|
||||
private fun updateCurrentTime(){
|
||||
current_time_tv.text = formatCalendarToString(
|
||||
DateTimeUtils.getCurrentDateTime(),HH_mm)
|
||||
|
||||
val date = formatCalendarToString(
|
||||
DateTimeUtils.getCurrentDateTime(), yy_MM_dd)
|
||||
val weekDay = DateTimeUtils.getWeekDayFromCalendar1(DateTimeUtils.getCurrentDateTime())
|
||||
"$date $weekDay".also { current_weekday_tv.text = it }
|
||||
|
||||
sendUpdateTimeTask() // 每10s更新一次
|
||||
}
|
||||
|
||||
fun changeOperationStatus(status:Boolean){
|
||||
if (!status){
|
||||
updateNoOrderUI()
|
||||
}
|
||||
}
|
||||
|
||||
fun showNoTaskView(haveTask: Boolean){
|
||||
setLineInfoView(haveTask)
|
||||
}
|
||||
|
||||
private fun setLineInfoView(isShow: Boolean){
|
||||
if (isShow){
|
||||
line_name_tv.visibility = View.VISIBLE
|
||||
line_during_tv.visibility = View.VISIBLE
|
||||
no_line_tv.visibility = View.GONE
|
||||
}else{
|
||||
updateNoOrderUI()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNoOrderUI() {
|
||||
line_name_tv.visibility = View.GONE
|
||||
line_during_tv.visibility = View.GONE
|
||||
no_line_tv.visibility = View.VISIBLE
|
||||
updateNoStationView()
|
||||
overMapView?.let {
|
||||
it.clearSiteMarkers()
|
||||
}
|
||||
overMapView?.let {
|
||||
it.clearCustomPolyline()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNoStationView(){
|
||||
station_name_tv.setTextColor(resources.getColor(R.color.m2_next_tv_color))
|
||||
station_name_title_tv.text = resources.getString(R.string.m2_p_station_title_tv)
|
||||
station_name_tv.text = resources.getString(R.string.m2_p_empty_tv)
|
||||
remain_mt.text = resources.getString(R.string.m2_p_empty_remain_km_minute)
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2DrivingPresenter {
|
||||
return PM2DrivingPresenter(this)
|
||||
}
|
||||
|
||||
fun updateAutoStatus(isAutoPilot: Boolean) {
|
||||
if (isAutoPilot){
|
||||
context?.let { auto_tv.setTextColor(ContextCompat.getColor(it,R.color.m2_p_white_color)) }
|
||||
context?.let { auto_tv.background = ContextCompat.getDrawable(it,R.drawable.auto_button_bg) }
|
||||
}else{
|
||||
context?.let { auto_tv.setTextColor(ContextCompat.getColor(it,R.color.m2_button_auto_tv_color)) }
|
||||
context?.let { auto_tv.background = ContextCompat.getDrawable(it,R.drawable.bg_p_m2_auto) }
|
||||
}
|
||||
}
|
||||
|
||||
fun updateLineStations(stations: MutableList<PM2Station>){
|
||||
var stationsList = mutableListOf<LatLng>()
|
||||
for (i in stations.indices){
|
||||
val station = stations[i]
|
||||
var latLng = LatLng(station.gcjLat,station.gcjLon)
|
||||
stationsList.add(latLng)
|
||||
}
|
||||
overMapView?.let {
|
||||
it.drawSiteMarkers(stationsList,
|
||||
BitmapFactory.decodeResource(resources,R.drawable.m2_map_staton_icon),0.5f,0.9f)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateStationsInfo(stations: MutableList<PM2Station>, i: Int, isArrived: Boolean){
|
||||
if (stations.size == 0) return
|
||||
if (0<= i && i<stations.size){
|
||||
station_name_tv.setTextColor(resources.getColor(R.color.m2_next_tv_color))
|
||||
station_name_tv.text = stations[i].name
|
||||
}
|
||||
if (isArrived){//到站
|
||||
station_name_title_tv.text = resources.getString(R.string.m2_p_station_title_arrived_tv)
|
||||
remain_mt.text = resources.getString(R.string.m2_p_empty_remain_km_minute)
|
||||
}else{ //前往目的地中
|
||||
station_name_title_tv.text = resources.getString(R.string.m2_p_station_title_tv)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 剩余里程和时间
|
||||
*/
|
||||
fun updateRemainMT(meters: Long, timeInSecond: Long) { //米。秒
|
||||
var disUnit = "公里"
|
||||
var remainDis: String? = "0"
|
||||
|
||||
if (meters > 0) {
|
||||
if (meters / 1000 < 1) {
|
||||
disUnit = "米"
|
||||
remainDis = meters.toFloat().roundToInt().toString()
|
||||
} else {
|
||||
disUnit = "公里"
|
||||
remainDis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
|
||||
}
|
||||
}
|
||||
|
||||
val time = ceil(timeInSecond / 60f).toInt()
|
||||
|
||||
"$remainDis$disUnit | $time 分钟".also { remain_mt.text = it }
|
||||
}
|
||||
|
||||
private fun sendUpdateTimeTask() {
|
||||
UiThreadHandler.postDelayed({
|
||||
updateCurrentTime()
|
||||
},LOOP_TIME_TEXT)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = PM2DrivingInfoFragment::class.java.simpleName
|
||||
const val LOOP_TIME_TEXT = 10 * 1000L
|
||||
}
|
||||
}
|
||||