[TaxiPassengerV1.0.0]OCH: 导入Taxi乘客app首版code

This commit is contained in:
pangfan
2022-01-26 16:56:15 +08:00
parent 5002b28ef7
commit 8a4887947c
334 changed files with 9294 additions and 10 deletions

View File

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

View File

@@ -0,0 +1,75 @@
apply plugin: 'com.android.library'
apply plugin: 'com.alibaba.arouter'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
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"
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
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'
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.arouter
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.1'
annotationProcessor rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.amapnavi3dmap
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogoutils
implementation rootProject.ext.dependencies.mogocommons
implementation rootProject.ext.dependencies.modulecommon
implementation rootProject.ext.dependencies.mogo_core_data
implementation rootProject.ext.dependencies.mogo_core_function_call
implementation rootProject.ext.dependencies.mogo_core_function_smp
implementation rootProject.ext.dependencies.mogo_core_function_v2x
}else {
implementation project(":core:mogo-core-utils")
implementation project(":foudations:mogo-commons")
implementation project(':modules:mogo-module-common')
implementation project(':core:mogo-core-data')
implementation project(':core:mogo-core-function-call')
implementation project(':core:function-impl:mogo-core-function-smp')
implementation project(':core:function-impl:mogo-core-function-v2x')
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

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

Binary file not shown.

View File

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

View File

@@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.och.taxi.passenger">
/
</manifest>

View File

@@ -0,0 +1,24 @@
package com.mogo.och.taxi.passenger;
import androidx.annotation.IdRes;
import androidx.fragment.app.FragmentActivity;
import com.mogo.eagle.core.function.api.base.IMoGoFunctionProvider;
public
/**
* @author congtaowang
* @since 2021/1/15
*
* 网约车抽象接口
*/
interface IMogoOCH extends IMoGoFunctionProvider {
/**
* 初始化网约车容器
*
* @param activity
* @param containerId 容器ID
*/
void createCoverage(FragmentActivity activity, @IdRes int containerId);
}

View File

@@ -0,0 +1,106 @@
package com.mogo.och.taxi.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.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.taxi.passenger.constant.OCHTaxiConst;
import com.mogo.och.taxi.passenger.ui.OCHTaxiFragment;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public
/**
* @author congtaowang
* @since 2021/1/15
* <p>
* 网约车-出租车
*/
@Route( path = OCHTaxiConst.PATH )
class MogoOCHTaxi implements IMogoOCH, IMogoStatusChangedListener {
private static final String TAG = "MogoOCHTaxi";
private OCHTaxiFragment ochTaxiFragment;
private FragmentActivity mActivity;
private int mContainerId;
@Override
public void init( Context context ) {
Logger.d( TAG, "init" );
MogoApisHandler.getInstance().getApis().getStatusManagerApi().registerStatusChangedListener("ochTaxi", StatusDescriptor.VR_MODE,this);
MogoApisHandler.getInstance().getApis().getStatusManagerApi().registerStatusChangedListener("ochTaxi", StatusDescriptor.TOP_VIEW,this);
}
/**
* 进入鹰眼模式,设置手势缩放地图失效
*/
private void stepIntoVrMode() {
Logger.d( TAG, "进入vr模式" );
MogoApisHandler.getInstance()
.getApis()
.getMapServiceApi()
.getMapUIController()
.openVrMode( false );
}
private void showFragment() {
if (ochTaxiFragment == null) {
Logger.d(TAG, "准备add fragment======");
ochTaxiFragment = new OCHTaxiFragment();
mActivity.getSupportFragmentManager().beginTransaction().add(mContainerId, ochTaxiFragment).commitAllowingStateLoss();
return;
}
Logger.d(TAG, "准备show fragment");
mActivity.getSupportFragmentManager().beginTransaction().show(ochTaxiFragment).commitAllowingStateLoss();
}
private void hideFragment(){
if (ochTaxiFragment != null){
mActivity.getSupportFragmentManager().beginTransaction().hide(ochTaxiFragment).commitAllowingStateLoss();
}
}
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (descriptor == StatusDescriptor.VR_MODE){
if (isTrue){
showFragment();
}else {
hideFragment();
}
}
}
@Override
public void createCoverage(FragmentActivity activity, int containerId) {
}
@NotNull
@Override
public String getFunctionName() {
return null;
}
@Nullable
@Override
public Fragment createCoverage(@Nullable FragmentActivity fragmentActivity, @Nullable Integer integer) {
this.mActivity = fragmentActivity;
this.mContainerId = integer;
UiThreadHandler.postDelayed(() -> stepIntoVrMode(), 5_000L);
return null;
}
@Override
public void onDestroy() {
}
}

View File

@@ -0,0 +1,71 @@
package com.mogo.och.taxi.passenger;
import android.content.Context;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.v2x.events.utils.LocationUtils;
import com.mogo.eagle.core.utilcode.util.ColorUtils;
import com.mogo.map.overlay.IMogoOverlayManager;
import com.mogo.map.overlay.IMogoPolyline;
import com.mogo.map.overlay.MogoPolylineOptions;
import com.mogo.module.common.MogoApisHandler;
import java.util.ArrayList;
import java.util.List;
public class OCHTaxiOverlayManager {
private IMogoPolyline mMoGoPolyline;
// 连接线参数
private MogoPolylineOptions mPolylineOptions;
// 线路径集合
private List<MogoLatLng> mPolylinePointList;
// 渐变色
private List<Integer> mPolylineColors;
private Context mContext;
IMogoOverlayManager mogoOverlayManager;
public OCHTaxiOverlayManager(Context context) {
mPolylineOptions = new MogoPolylineOptions();
// 绘制路径集合
mPolylinePointList = new ArrayList<>();
// 引导线颜色
mPolylineColors = new ArrayList<>();
mContext = context;
mogoOverlayManager = MogoApisHandler.getInstance().getApis().getMapServiceApi().getOverlayManager(mContext);
}
/**
* 绘制最优路线
*
* @param polylinePoint 要绘制的经纬度度集合
*/
public IMogoPolyline draw(MogoLocation carLocal, List<MogoLatLng> polylinePoint) {
if (mMoGoPolyline != null) {
mMoGoPolyline.remove();
mPolylinePointList.clear();
mPolylineColors.clear();
}
if (polylinePoint != null) {
// 将当前车辆位置放进去
mPolylinePointList.add(new MogoLatLng(carLocal.getLatitude(), carLocal.getLongitude()));
// 过滤后台推送的推荐路线集合
for (MogoLatLng polyline : polylinePoint) {
//需要剔除已经行驶过的经纬度,这里需要比对推荐路线集合中的点是否在当前车辆行驶方向前面如果不在则抛弃
if (LocationUtils.isPointOnCarFront(carLocal, polyline)) {
mPolylinePointList.add(polyline);
}
}
mPolylineColors.addAll(ColorUtils.getGradientAlpha("#002965ED", "#FF2965ED", "#002965ED", mPolylinePointList.size()));
// 替换路径集合
mPolylineOptions.points(mPolylinePointList);
// 线条粗细,渐变,渐变色值
mPolylineOptions.width(25).useGradient(true).colorValues(mPolylineColors);
// 绘制线
mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions);
}
return mMoGoPolyline;
}
}

View File

@@ -0,0 +1,26 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.och.taxi.passenger.constant.OCHTaxiConst;
import java.util.UUID;
/**
* Created on 2021/9/16
*
* 上传车机心跳信息请求数据
*/
public class CarHeartbeatReqBean {
public String sn;
public double lon; //经度
public double lat; //纬度
public String msgId; //心跳信息唯一标识
public int interval; //上报间隔单位秒非必传默认60秒
public CarHeartbeatReqBean(String sn, double lon, double lat) {
this.sn = sn;
this.lon = lon;
this.lat = lat;
this.msgId = UUID.randomUUID().toString();
this.interval = (int) (OCHTaxiConst.LOOP_PERIOD_60S / 1000);
}
}

View File

@@ -0,0 +1,21 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* Created on 2021/9/17
*
* 司机运营数据返回数据结构
*/
public class DriverServiceDataRespBean extends BaseData {
public Result data;
public static class Result {
public Immediate immediate; //daily数据
}
public static class Immediate {
public long timeDuration; //当日在线时长,单位秒
public long orderNum; //当日完成订单数
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* Created by pangfan on 2021/8/19
*
* 收车/出车状态查询返回数据结构
*/
public class DriverStatusQueryRespBean extends BaseData {
public Result data;
public static class Result {
public int serviceStatus; //0收车1出车
public long serviceOrderId;
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created by pangfan on 2021/8/19
*
* 收车/出车状态更新请求数据结构
*/
public class DriverStatusUpdateReqBean {
public String sn;
public int status; //0收车1出车
public DriverStatusUpdateReqBean(String sn, int status) {
this.sn = sn;
this.status = status;
}
}

View File

@@ -0,0 +1,20 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created by pangfan on 2021/8/19
*
* 司机取消订单请求的数据结构
*/
public class OrderCancelReqBean {
public String sn;
public long order_id; //订单号(必须)
public int cancel_type; //取消类型(必须)
public String cancel_reason; //取消原因(必须)
public OrderCancelReqBean(String sn, long order_id, int cancel_type, String cancel_reason) {
this.sn = sn;
this.order_id = order_id;
this.cancel_type = cancel_type;
this.cancel_reason = cancel_reason;
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created on 2021/9/7
*
* (预约单)抢单动作的请求数据结构
*/
public class OrderGrabReqBean {
public String sn;
public long orderId;
public OrderGrabReqBean(String sn, long orderId) {
this.sn = sn;
this.orderId = orderId;
}
}

View File

@@ -0,0 +1,12 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* Created on 2021/9/7
*
* (预约单)抢单动作的返回数据结构
*/
public class OrderGrabRespBean extends BaseData {
public long data; // 暂不使用
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* Created on 2021/9/7
*
* (预约单)查询抢单结果的返回数据结构
*/
public class OrderGrabStatusQueryRespBean extends BaseData {
public Result data;
public static class Result {
public int grabStatus; //0:抢单中; 1:抢单结束,匹配; 2:抢单结束匹配到其他司机3:订单已取消4:非法,不是选择的自己
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created by pangfan on 2021/8/19
*
* 查询订单信息请求数据结构
*/
public class OrderQueryReqBean {
public String sn;
public long orderId;
public OrderQueryReqBean(String sn, long orderId) {
this.sn = sn;
this.orderId = orderId;
}
}

View File

@@ -0,0 +1,88 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
import java.util.Objects;
/**
* Created by pangfan on 2021/8/19
*
* 查询订单返回数据结构
*/
public class OrderQueryRespBean extends BaseData {
public Result data;
public static class Result implements Comparable<Result>{
// 订单id
public long orderId;
// 订单类型
public int orderType; //1即时单 2预约单
// 订单状态
public int orderStatus;
// 订单运营类型 9出租车10小巴
public int businessType;
// 起始站点id
public int startSiteId;
// 起始站点名称
public String startSiteAddr;
// 起始站点坐标
public List<Double> startSitePoint; //wgs坐标用于自动驾驶 [lon,lat]
public List<Double> startSiteGcjPoint; //高德坐标,用于本地计算距离 [lon,lat]
// 终点站点id
public int endSiteId;
// 终点站点名称
public String endSiteAddr;
// 终点站点坐标
public List<Double> endSitePoint; //wgs坐标用于自动驾驶 [lon,lat]
public List<Double> endSiteGcjPoint; //高德坐标,用于计算距离 [lon,lat]
// 车牌号
public String carNumber;
//订单创建时间戳
public long createTime;
//开始服务时间戳:司机点击'开始服务'后订单状态更新成功的时间
public long startTime;
//预计用车时间:预约单=下单时的预约用车时间;即时单=派单成功的时间+预估的达到上车点的时间
public long bookingTime;
// !!!接口中暂无此字段仅用于本地实现逻辑使用起始站目的站距离km
public double travelDistance;
/**
* @param distance
*/
public void decreaseTravelDistance( double distance ) {
travelDistance = ( ( float ) distance / 1000f );
if ( travelDistance < 0 ) {
travelDistance = 0;
}
}
@Override
public int compareTo(Result o) {
long result = this.orderId - o.orderId;
return result == 0 ? 0 : (result > 0 ? 1 : -1);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Result result = (Result) o;
return orderId == result.orderId &&
orderType == result.orderType &&
orderStatus == result.orderStatus &&
businessType == result.businessType;
}
@Override
public int hashCode() {
return Objects.hash(orderId, orderType, orderStatus, businessType, startSiteId,
startSiteAddr, startSitePoint, startSiteGcjPoint, endSiteId, endSiteAddr,
endSitePoint, endSiteGcjPoint, carNumber, createTime, startTime, travelDistance);
}
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created on 2021/9/7
*
* 查询订单路径信息(起始点里程、预估时间等)请求数据结构
*/
public class OrderQueryRouteInfoReqBean {
public String sn;
public long orderId;
public OrderQueryRouteInfoReqBean(String sn, long orderId) {
this.sn = sn;
this.orderId = orderId;
}
}

View File

@@ -0,0 +1,22 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* Created on 2021/9/7
*
* 查询订单路径信息(起始点里程、预估时间等)返回数据结构
*/
public class OrderQueryRouteInfoRespBean extends BaseData {
public Result data;
public static class Result {
// 到上车点
public long durationToStart; //司机绑定时的位置距离上车点时长,单位:秒
public long distanceToStart; //司机绑定时的位置距离上车点距离,单位:米
// 起点至终点
public long durationToEnd; //订单上车点到目的地的时长,单位:秒
public long distanceToEnd; //订单上车点到目的地的距离,单位:米
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created by pangfan on 2021/8/19
*
* 订单状态更新请求数据结构
*/
public class OrderStatusUpdateReqBean {
public String sn;
public long orderId;
public int orderStatus;
public OrderStatusUpdateReqBean(String sn, long orderId, int orderStatus) {
this.sn = sn;
this.orderId = orderId;
this.orderStatus = orderStatus;
}
}

View File

@@ -0,0 +1,19 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* Created on 2021/9/8
*
* 查询全部服务中/待服务订单的返回数据
*/
public class OrdersInServiceQueryRespBean extends BaseData {
public Result data;
public static class Result {
public List<OrderQueryRespBean.Result> servicing; //服务中订单
public List<OrderQueryRespBean.Result> waitService; //待服务订单
}
}

View File

@@ -0,0 +1,19 @@
package com.mogo.och.taxi.passenger.bean;
/**
* Created by pangfan on 2021/8/19
*
* 查询订单列表请求数据结构
*/
public class OrdersListQueryReqBean {
public String sn;
public int page; //页码从0开始
public int size; //每页条数
public OrdersListQueryReqBean(String sn, int page, int size) {
this.sn = sn;
this.page = page;
this.size = size;
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* Created by pangfan on 2021/8/19
*/
public class OrdersListQueryRespBean extends BaseData {
public Result data;
public static class Result {
public List<OrderQueryRespBean.Result> orders;
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.taxi.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* Created on 2021/9/8
*
* 查询新到的预约单的返回数据结构
*/
public class OrdersNewBookingQueryRespBean extends BaseData {
public Result data;
public static class Result {
public List<Long> orders;
}
}

View File

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

View File

@@ -0,0 +1,13 @@
package com.mogo.och.taxi.passenger.callback;
import com.mogo.eagle.core.data.autopilot.AutopilotRouteInfo;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2021/11/1
*/
public interface IOCHTaxiAutopilotPlanningCallback {
void routeResult(List<AutopilotRouteInfo.RouteModels> models);
}

View File

@@ -0,0 +1,12 @@
package com.mogo.och.taxi.passenger.callback;
/**
* Created on 2021/9/8
*
* Model->Presenter回调出车/收车状态变更
*/
public interface IOCHTaxiCarStatusCallback {
void onCarStatusChanged(boolean inOperation);
void onServiceDataUpdate(long dailyTimeDuration, long dailyOrderNum);
}

View File

@@ -0,0 +1,15 @@
package com.mogo.och.taxi.passenger.callback;
import android.location.Location;
/**
* Created on 2021/9/10
*
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface IOCHTaxiControllerStatusCallback {
// 是否vr map模式
void onVRModeChanged(boolean isVRMode);
// 自车定位
void onCarLocationChanged(Location location);
}

View File

@@ -0,0 +1,11 @@
package com.mogo.och.taxi.passenger.callback;
/**
* @author: wangmingjun
* @date: 2021/12/3
*/
public interface IOCHTaxiNaviChangedCallback {
// 当前位置距离上车点的距离(米)、预估时间(秒)
void onCurrentNaviDistAndTimeChanged(int meters, int timeInSecond);
void reInitNaviAmap(boolean isPlay,boolean isRestart);
}

View File

@@ -0,0 +1,48 @@
package com.mogo.och.taxi.passenger.callback;
import androidx.annotation.NonNull;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import java.util.List;
/**
* Created on 2021/9/8
*
* Model->Presenter回调订单相关进行中/待服务单变更,当前进行单状态变更,新到预约单,抢单,抢单结果状态等等)
*/
public interface IOCHTaxiOrderStatusCallback {
// 进行中单变更:暂未用到
void onOrdersInServiceChanged(@NonNull List<OrderQueryRespBean.Result> inServiceList);
// 待服务单变更
void onOrdersWaitServiceChanged(@NonNull List<OrderQueryRespBean.Result> waitServiceList);
// 当前进行单状态变更:新到进行中订单、进行中单状态变更
void onCurrentOrderStatusChanged(OrderQueryRespBean.Result order);
// 当前订单取消完成:用于司机主动取消订单的结果反馈
void onCurrentOrderCancelDone();
// 待服务单被取消
void onOrderCancelDone(long orderId);
// 当前订单route信息查询反馈
void onCurrentOrderRouteInfoGot(OrderQueryRouteInfoRespBean.Result routeInfo);
// 当前位置距离上车点的距离(米)、预估时间(秒)
void onCurrentOrderDistToStartChanged(long meters, long timeInSecond);
// 当前位置距离上车点的距离(米)、预估时间(秒)
void onCurrentOrderDistToEndChanged(long meters, long timeInSecond);
// 获取全部订单列表(含已完成、已取消)的反馈
void onOrdersListPageRefresh(List<OrderQueryRespBean.Result> ordersList);
// 新到预约单
void onNewBookingOrderGot(OrderQueryRespBean.Result order);
// 执行抢单动作完成:可进入抢单中状态
void onGrabOrderExecuteDone();
// 抢到预约单
void onGrabOrderSuccess(OrderQueryRespBean.Result order);
// 未抢到预约单
void onGrabOrderFailed(OrderQueryRespBean.Result order);
}

View File

@@ -0,0 +1,65 @@
package com.mogo.och.taxi.passenger.callback
import androidx.annotation.ColorRes
/**
* @author: wangmingjun
* @date: 2022/1/21
*/
interface Shadow {
//设置阴影半径
fun setShadowRadius(radius:Float): Shadow
//添加单位设置
fun setShadowRadius(unit:Int,radius: Float): Shadow
//设置应用颜色
fun setShadowColor(color:Int): Shadow
//设置阴影颜色资源文件id
fun setShadowColorRes(@ColorRes color: Int): Shadow
/**
* 设置模糊半径
* @param radius
*/
fun setBlurRadius(radius:Float): Shadow
/**
*
* @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
* @param radius 模糊半径
*/
fun setBlurRadius(unit:Int,radius:Float): Shadow
/**
* 设置水平方向的偏移量
* @param offset x轴偏移
*/
fun setXOffset(offset:Float): Shadow
/**
* 设置x方向的偏移量,设置单位
* @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
* @param offset x轴偏移
*/
fun setXOffset(unit:Int,offset:Float): Shadow
/**
* 设置竖直方向的偏移量
* @param offset y轴偏移
*/
fun setYOffset(offset:Float): Shadow
/**
* 设置竖直方向的偏移量,带单位
* @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
* @param offset y轴偏移
*/
fun setYOffset(unit:Int,offset:Float): Shadow
/**
* 更新绘制
*/
fun commit();
}

View File

@@ -0,0 +1,43 @@
package com.mogo.och.taxi.passenger.constant
import com.mogo.commons.debug.DebugConfig
/**
* Created on 2021/12/6
*/
class OCHTaxiConst {
companion object {
private const val BASE_URL_OCH_DEV = "http://tech-dev.zhidaohulian.com"
private const val BASE_URL_OCH_QA = "https://tech-qa.zhidaohulian.com"
private const val BASE_URL_OCH_RELEASE = "https://tech.zhidaohulian.com"
@JvmStatic
fun getBaseUrl(): String {
return when (DebugConfig.getNetMode()) {
DebugConfig.NET_MODE_DEV, DebugConfig.NET_MODE_DEMO -> BASE_URL_OCH_DEV
DebugConfig.NET_MODE_QA -> BASE_URL_OCH_QA
DebugConfig.NET_MODE_RELEASE -> BASE_URL_OCH_RELEASE
else -> BASE_URL_OCH_RELEASE
}
}
// OCH arouter 路由path
const val PATH = "/och/api"
// 到达起始点围栏
const val ARRIVE_AT_START_STATION_DISTANCE = 50 //围栏由20m改为50m
// 上报心跳轮询ms
const val LOOP_PERIOD_60S = 60 * 1000L
// 轮询查询进行中/待服务订单的间隔时间 2秒
const val LOOP_PERIOD_2S = 2 * 1000L
// 轮询查询新到预约单 1秒
const val LOOP_PERIOD_1S = 1 * 1000L
const val LOOP_DELAY = 100L
// 订单信息
const val SP_KEY_OCH_TAXI_ORDER = "SP_KEY_OCH_TAXI_ORDER"
}
}

View File

@@ -0,0 +1,48 @@
package com.mogo.och.taxi.passenger.constant
/**
* 司机端取消订单的原因定义
* Created on 2021/12/7
*
* * String int
* 进行中订单:
* 车况异常 0
* 设备异常 1
* 电量不足 2
* 身体不适 3
* 乘客未到 4
* 乘客中途下车 5
*
* 待服务订单:
* 2000 车辆故障
* 2001 乘客联系取消
* 2002 行程冲突
* 2003 车电量不足
* 2004 其他
*/
enum class OrderCancelReasons(val type: Int, val msg: String) {
CarBroken(1000, "车况异常"),
DeviceBroken(1001, "设备异常"),
BatteryLow(1002, "电量不足"),
DriverIsIll(1003, "身体不适"),
PassengerNotArrive(1004, "乘客未到"),
PassengerStopOver(1005, "乘客中途下车"),
BookCarBroken(2000, "车辆故障"),
BookPassengerCancel(2001, "乘客联系取消"),
BookJourneyConflict(2002, "行程冲突"),
BookBatteryLow(2003, "车电量不足"),
BookOther(2004, "其他");
companion object {
@JvmStatic
fun getType(msg: String): Int {
for (value in values()) {
if (value.msg == msg) {
return value.type
}
}
return 0
}
}
}

View File

@@ -0,0 +1,47 @@
package com.mogo.och.taxi.passenger.constant
/**
* Created on 2021/12/7
*
* * Old codeSTART
* 未派单 0
* 去往上车站点 1
* 车辆已到达上车站点 2
* 乘客已到达上车站点 3
* 去往下车站点 4
* 到达下车站点 5
* 已完成 6
* 已取消 7
* Old codeEND
*
* 0 订单创建(为派单),
* 10 已派上司机(司机去往上车点),
* 20 司机到达上车点,
* 30 乘客到达上车点,
* 40 服务中(去往目的地),
* 50 到达目的地,
* 60 已完成,
* 70 已取消
*/
enum class OrderStatusEnum(val code: Int) {
None( 0 ),
OnTheWayToStartStation( 10),
ArriveAtStartStation( 20),
UserArriveAtStartStation( 30),
OnTheWayToEndStation( 40),
ArriveAtEndStation( 50),
JourneyCompleted(60),//行程完成
Cancel( 70);
companion object {
@JvmStatic
fun valueOf(code: Int): OrderStatusEnum? {
for (value in values()) {
if (value.code == code) {
return value
}
}
return None
}
}
}

View File

@@ -0,0 +1,11 @@
package com.mogo.och.taxi.passenger.constant
/**
* RoboTaxi订单类型声明
*
* Created on 2021/12/6
*/
enum class OrderTypeEnum(val type: Int) {
Instant(1), // 即时单
Reserved(2) // 预约单
}

View File

@@ -0,0 +1,991 @@
package com.mogo.och.taxi.passenger.model;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.ConnectivityManager;
import androidx.annotation.Nullable;
import com.elegant.network.utils.GsonUtil;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.eagle.core.data.autopilot.ADASTrajectoryInfo;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.data.autopilot.AutopilotGuardianStatusInfo;
import com.mogo.eagle.core.data.autopilot.AutopilotRouteInfo;
import com.mogo.eagle.core.data.autopilot.AutopilotStationInfo;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiAutopilotPlanningCallback;
import com.mogo.och.taxi.passenger.constant.OCHTaxiConst;
import com.mogo.och.taxi.passenger.constant.OrderStatusEnum;
import com.mogo.och.taxi.passenger.constant.OrderTypeEnum;
import com.mogo.och.taxi.passenger.network.OCHTaxiServiceCallback;
import com.mogo.och.taxi.passenger.bean.DriverServiceDataRespBean;
import com.mogo.och.taxi.passenger.bean.DriverStatusQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabRespBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabStatusQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersInServiceQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersListQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersNewBookingQueryRespBean;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiADASStatusCallback;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiCarStatusCallback;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiControllerStatusCallback;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiOrderStatusCallback;
import com.mogo.och.taxi.passenger.network.OCHTaxiServiceManagerNew;
import com.mogo.och.taxi.passenger.utils.OrderUtil;
import com.mogo.och.taxi.passenger.utils.PinYinUtil;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.cloud.socket.IMogoLifecycleListener;
import com.mogo.service.intent.IMogoIntentListener;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by pangfan on 2021/8/19
*
* 网约车 - 出租车业务逻辑处理
*/
public class MogoOCHTaxiModelNew {
private static final String TAG = MogoOCHTaxiModelNew.class.getSimpleName();
private static final class SingletonHolder {
private static final MogoOCHTaxiModelNew INSTANCE = new MogoOCHTaxiModelNew();
}
public static MogoOCHTaxiModelNew getInstance() {
return SingletonHolder.INSTANCE;
}
private Context mContext;
private volatile int mPrevAPStatus = -1; //前一次自动驾驶状态值
private volatile int mOCHCarStatus = -1; //出车/收车状态1 出车0 收车
private volatile long mPrevOrderId = -1; //前一次的新到单id当次和前一次orderId相同时本次不再弹出
private volatile OrderQueryRespBean.Result mNewBookingOrder; //新到待抢预约单
private volatile OrderQueryRespBean.Result mCurrentOCHOrder; //当前订单
private volatile List<OrderQueryRespBean.Result> mInServiceList = Collections.emptyList(); //进行中订单
private volatile List<OrderQueryRespBean.Result> mWaitServiceList = Collections.emptyList(); //待服务订单
private IOCHTaxiADASStatusCallback mADASStatusCallback; //Model->Presenter自动驾驶状态相关
private IOCHTaxiCarStatusCallback mCarStatusCallback; //Model->Presenter出车/收车状态
private IOCHTaxiControllerStatusCallback mControllerStatusCallback; //Model->PresenterVR mode等
private IOCHTaxiOrderStatusCallback mOrderStatusCallback; //Model->Presenter订单变更
private IOCHTaxiAutopilotPlanningCallback mAutopilotPlanningCallback; //Model->Presenter自动驾驶线路规划
private double mLongitude, mLatitude;
private MogoOCHTaxiModelNew() {
}
public void setMoGoAutopilotPlanningListener(IOCHTaxiAutopilotPlanningCallback
moGoAutopilotPlanningCallback) {
this.mAutopilotPlanningCallback = moGoAutopilotPlanningCallback;
}
public void setADASStatusCallback(IOCHTaxiADASStatusCallback callback) {
this.mADASStatusCallback = callback;
}
public void setCarStatusCallback(IOCHTaxiCarStatusCallback callback) {
this.mCarStatusCallback = callback;
}
public void setControllerStatusCallback(IOCHTaxiControllerStatusCallback callback) {
this.mControllerStatusCallback = callback;
}
public void setOrderStatusCallback(IOCHTaxiOrderStatusCallback callback) {
this.mOrderStatusCallback = callback;
}
public void init( Context context ) {
mContext = context.getApplicationContext();
initListeners();
IMogoServiceApis apis = MogoApisHandler.getInstance().getApis();
apis.getSocketManagerApi(mContext).init(mContext, DebugConfig.getSocketAppId());
// TODO: 2021/8/27 因需要通过此回调的location进行坐标上传暂改为全程监听退出后再反注册
// 待后续整体调整location获取来源
if (DebugConfig.getCarMachineType() != DebugConfig.CAR_MACHINE_TYPE_SELF_INNOVATE) {
apis.getLocationInfoApi().start();
}
if (NetworkUtils.isConnected(mContext)) {
// startOrStopOrderLoop(mOCHCarStatus == 1);
if (FunctionBuildConfig.appIdentityMode == 0) {
queryCarStatus();
}
}
}
public void startOrStopOrderLoop(){
startOrStopOrderLoop(mOCHCarStatus == 1);
}
public void release() {
startOrStopOrderLoop(false);
releaseListeners();
}
private void initListeners() {
MogoApisHandler.getInstance()
.getApis()
.getSocketManagerApi(mContext)
.registerLifecycleListener(10010,mSocketLifeCycleLisnter);
// 2021.11.1重构自动驾驶 实现接口 IMoGoAutopilotStatusListener 注册监听 替换IMogoAdasOCHCallback接口
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener);
MogoApisHandler.getInstance()
.getApis()
.getIntentManagerApi()
.registerIntentListener( ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener );
MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.registerStatusChangedListener( TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener );
// 达到起始站围栏监听
MogoApisHandler.getInstance()
.getApis()
.getRegisterCenterApi()
.registerCarLocationChangedListener( TAG, mCarLocationChangedListener2);
//2021.11.1 自动驾驶路线规划接口
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG,moGoAutopilotPlanningListener);
}
private void releaseListeners() {
MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.unregisterStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
// 注销到达起始站围栏监听
MogoApisHandler.getInstance()
.getApis()
.getRegisterCenterApi()
.unregisterCarLocationChangedListener(TAG, mCarLocationChangedListener2);
MogoApisHandler.getInstance()
.getApis()
.getSocketManagerApi(mContext)
.unregisterLifecycleListener(10010);
CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(mGoAutopilotStatusListener);
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
}
private void startOrStopOrderLoop(boolean start) {
Logger.d(TAG, "startOrStopOrderLoop() " + start);
if (start) {
OCHTaxiModelLoopManager.getInstance().startInAndWaitOrdersLoop();
OCHTaxiModelLoopManager.getInstance().startNewBookingOrderLoop();
OCHTaxiModelLoopManager.getInstance().startHeartbeatLoop();
} else {
OCHTaxiModelLoopManager.getInstance().stopInAndWaitOrdersLoop();
OCHTaxiModelLoopManager.getInstance().stopNewBookingOrderLoop();
OCHTaxiModelLoopManager.getInstance().stopHeartbeatLoop();
}
}
//查询出车/收车状态
public void queryCarStatus() {
OCHTaxiServiceManagerNew.getInstance().queryDriverServiceStatus(mContext,
new OCHTaxiServiceCallback<DriverStatusQueryRespBean>() {
@Override
public void onSuccess(DriverStatusQueryRespBean data) {
if (null != data && 0 == data.code) {
mOCHCarStatus = data.data.serviceStatus == 1 ? 1 : 0;
//更新view
startOrStopOrderLoop(mOCHCarStatus == 1);
if (mCarStatusCallback != null) {
mCarStatusCallback.onCarStatusChanged(mOCHCarStatus == 1);
}
}
}
@Override
public void onError() {
if (!NetworkUtils.isConnected(mContext)) {
TipToast.shortTip("网络异常,请稍后重试");
}
}
@Override
public void onFail(int code, String msg) { }
});
}
//更新出车收车状态
public void updateCarStatus() {
if ( mOCHCarStatus == -1){
queryCarStatus();
return;
}
final int status = mOCHCarStatus == 1 ? 0 : 1;
OCHTaxiServiceManagerNew.getInstance().updateDriverServiceStatus(mContext, status,
new OCHTaxiServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData data) {
if (null != data && 0 == data.code) {
mOCHCarStatus = status;
startOrStopOrderLoop(mOCHCarStatus == 1);
if (mCarStatusCallback != null) {
mCarStatusCallback.onCarStatusChanged(mOCHCarStatus == 1);
}
Logger.d(TAG, "changeCarStatus:" + status);
}
}
@Override
public void onError() {
if (!NetworkUtils.isConnected(mContext)) {
TipToast.shortTip("网络异常,请稍后重试");
}
}
@Override
public void onFail(int code, String msg) {
TipToast.shortTip(code + "," + msg);
}
});
}
/**
* 查询订单状态:进行中/待服务轮询防止因crash导致应用重启、断网没收到推送等
*
* 注只有在本地缓存mCurrentOCHOrder为null时已完成or已取消有明确结果或id相同且status不同时
* 才更新最新进行中单到本地
*/
public void queryInAndWaitOrders() {
OCHTaxiServiceManagerNew.getInstance().queryOrdersInAndWaitService(mContext,
new OCHTaxiServiceCallback<OrdersInServiceQueryRespBean>() {
@Override
public void onSuccess(OrdersInServiceQueryRespBean data) {
if (data == null || data.data == null) {
return;
}
//1. 处理进行中订单
mInServiceList = data.data.servicing;
if (data.data.servicing != null && !data.data.servicing.isEmpty()) {
// 1.1. 当存在进行中单时对本地currentOrder进行更新
if (mCurrentOCHOrder == null) {
//1.1.1. 当本地无currentOrder已经完成or取消则更新currentOrder并通知ui更新
updateNativeCurrentOrder(data.data.servicing.get(0));
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onCurrentOrderStatusChanged(mCurrentOCHOrder);
}
} else {
//1.1.2. 当本地有currentOrder
//orderId不一致时通过currentOrder.orderId查询订单状态并通知ui更新
//orderId一致且orderStatus不一致时则更新currentOrder并通知ui更新
if (mCurrentOCHOrder.orderId != data.data.servicing.get(0).orderId) {
queryCurOrderStatus();
} else if (mCurrentOCHOrder.orderStatus != data.data.servicing.get(0).orderStatus) {
updateNativeCurrentOrder(data.data.servicing.get(0));
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onCurrentOrderStatusChanged(mCurrentOCHOrder);
}
}
}
} else {
// 1.2. 当无进行中订单时如果本地也无则跳过如果本地仍存在currentOrder查询此单完成or取消并通知ui更新
if (mCurrentOCHOrder != null) {
queryCurOrderStatus();
}
}
//2. 处理待服务订单列表
if (data.data.waitService != null && !data.data.waitService.isEmpty()) {
//2.1. 当存在待服务订单列表:跟本地待服务列表比较
if (mWaitServiceList.isEmpty()
|| (mWaitServiceList.size() != data.data.waitService.size())
|| !OrderUtil.haveSameOrders(mWaitServiceList, data.data.waitService)) {
// 2.1.1. 当本地无待服务单或数量和内容不一致更新本地待服务列表并通知ui更新
mWaitServiceList = data.data.waitService;
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onOrdersWaitServiceChanged(mWaitServiceList);
}
}
} else {
//2.2. 当无待服务单时如果本地也无则跳过如果本地有则清除并通知ui更新
if (!mWaitServiceList.isEmpty()) {
mWaitServiceList.clear();
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onOrdersWaitServiceChanged(mWaitServiceList);
}
}
}
}
@Override
public void onFail(int code, String msg) {
}
});
}
//仅用于轮询时查到本地有mCurrentOCHOrder但请求结果无进行中单or orderId不一致是复查本地currentOrder
private void queryCurOrderStatus() {
if (mCurrentOCHOrder == null) {
return;
}
final long orderId = mCurrentOCHOrder.orderId;
OCHTaxiServiceManagerNew.getInstance().queryOrderById(mContext, orderId,
new OCHTaxiServiceCallback<OrderQueryRespBean>() {
@Override
public void onSuccess(OrderQueryRespBean data) {
if (data != null && data.data != null
&& mCurrentOCHOrder != null && mCurrentOCHOrder.orderId == data.data.orderId) {
if (data.data.orderStatus == OrderStatusEnum.Cancel.getCode()
|| data.data.orderStatus == OrderStatusEnum.JourneyCompleted.getCode()
|| data.data.orderStatus == OrderStatusEnum.None.getCode()) {
clearCurrentOCHOrder();
cancelAutopilot();
} else {
updateNativeCurrentOrder(data.data);
}
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onCurrentOrderStatusChanged(data.data);
}
}
}
@Override
public void onFail(int code, String msg) {
}
});
}
//更新当前订单状态
public void updateOCHOrderStatus(final OrderStatusEnum orderStatus) {
if ( mCurrentOCHOrder == null ) {
return;
}
final long orderId = mCurrentOCHOrder.orderId;
OCHTaxiServiceManagerNew.getInstance().updateOrderStatus(mContext, orderId,
orderStatus.getCode(), new OCHTaxiServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData data) {
if (null != data && 0 == data.code
&& mCurrentOCHOrder != null && mCurrentOCHOrder.orderId == orderId) {
mCurrentOCHOrder.orderStatus = orderStatus.getCode();
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onCurrentOrderStatusChanged(mCurrentOCHOrder);
}
}
}
@Override
public void onError() {
if (!NetworkUtils.isConnected(mContext)) {
TipToast.shortTip("网络异常,请稍后重试");
}
}
@Override
public void onFail(int code, String msg) {
// TipToast.shortTip(code + "," + msg);
}
});
}
// 取消当前订单
public void cancelCurrentOrder(int reasonType, String reason) {
if (mCurrentOCHOrder == null) {
mOrderStatusCallback.onCurrentOrderCancelDone();
return;
}
final long orderId = mCurrentOCHOrder.orderId;
OCHTaxiServiceManagerNew.getInstance().cancelOrder(mContext, orderId, reasonType, reason,
new OCHTaxiServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData data) {
if (null != data && 0 == data.code
&& mCurrentOCHOrder != null && mCurrentOCHOrder.orderId == orderId) {
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onCurrentOrderCancelDone();
}
clearCurrentOCHOrder();
cancelAutopilot();
}
}
@Override
public void onFail(int code, String msg) {
// TipToast.shortTip(code + "," + msg);
}
});
}
// 取消待服务中订单
public void cancelOrderById(final long orderId, int reasonType, String reason) {
OCHTaxiServiceManagerNew.getInstance().cancelOrder(mContext, orderId, reasonType, reason,
new OCHTaxiServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData data) {
if (null != data && 0 == data.code) {
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onOrderCancelDone(orderId);
}
}
}
@Override
public void onFail(int code, String msg) {
// TipToast.shortTip(code + "," + msg);
}
});
}
// 查询当前订单route信息预估时间、里程等
public void queryCurOrderRouteInfo() {
if (mCurrentOCHOrder == null) {
return;
}
final long orderId = mCurrentOCHOrder.orderId;
OCHTaxiServiceManagerNew.getInstance().queryOrderRouteInfo(mContext, orderId,
new OCHTaxiServiceCallback<OrderQueryRouteInfoRespBean>() {
@Override
public void onSuccess(OrderQueryRouteInfoRespBean data) {
if (null != data && 0 == data.code
&& mCurrentOCHOrder != null && mCurrentOCHOrder.orderId == orderId) {
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onCurrentOrderRouteInfoGot(data.data);
}
}
}
@Override
public void onFail(int code, String msg) {
// TipToast.shortTip(code + "," + msg);
}
});
}
// 获取全部订单列表
public void queryOrdersList(int page, int size) {
OCHTaxiServiceManagerNew.getInstance().queryOrdersList(mContext, page, size,
new OCHTaxiServiceCallback<OrdersListQueryRespBean>() {
@Override
public void onSuccess(OrdersListQueryRespBean data) {
if (null != data && 0 == data.code) {
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onOrdersListPageRefresh(data.data.orders);
}
}
}
@Override
public void onFail(int code, String msg) {
TipToast.shortTip("请求异常,请稍后重试");
}
});
}
/**
* 查询新到预约单
*
* 注只有在本地缓存mNewBookingOrder为null时执行完抢单or司机关闭改单才更新新到待抢单
*/
public void queryNewBookingOrder() {
OCHTaxiServiceManagerNew.getInstance().queryNewBookingOrder(mContext,
new OCHTaxiServiceCallback<OrdersNewBookingQueryRespBean>() {
@Override
public void onSuccess(OrdersNewBookingQueryRespBean data) {
if (data != null && data.code == 0
&& data.data != null && data.data.orders.size() > 0) {
// 本地无新到单且本次新到单id与上次收到的新单id不同时显示本次新到单
if (mNewBookingOrder == null ) {
for (Long orderId : data.data.orders) {
if (mPrevOrderId != orderId.longValue()) {
queryNewBookingContent(orderId.longValue());
break;
}
}
}
}
}
@Override
public void onFail(int code, String msg) {
}
});
}
// 仅限于获取到新待抢单且需要展示时查询该单信息queryOrderById接口可以查询属于该车的单、未派的单
private void queryNewBookingContent(final long orderId) {
OCHTaxiServiceManagerNew.getInstance().queryOrderById(mContext, orderId,
new OCHTaxiServiceCallback<OrderQueryRespBean>() {
@Override
public void onSuccess(OrderQueryRespBean data) {
if (data != null && data.code == 0
&& data.data != null && data.data.orderId == orderId
&& data.data.orderType == OrderTypeEnum.Reserved.getType()) {
mNewBookingOrder = data.data;
mPrevOrderId = data.data.orderId;
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onNewBookingOrderGot(mNewBookingOrder);
}
}
}
@Override
public void onFail(int code, String msg) {
}
});
}
// 执行抢单动作
public void grabOrder() {
if (mNewBookingOrder == null) {
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onGrabOrderFailed(null);
}
return;
}
final long orderId = mNewBookingOrder.orderId;
OCHTaxiServiceManagerNew.getInstance().grabOrder(mContext, orderId,
new OCHTaxiServiceCallback<OrderGrabRespBean>() {
@Override
public void onSuccess(OrderGrabRespBean data) {
if (data != null && data.code == 0
&& mNewBookingOrder != null && mNewBookingOrder.orderId == orderId) {
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onGrabOrderExecuteDone();
OCHTaxiModelLoopManager.getInstance().startGrabResultLoop();
}
}
}
@Override
public void onFail(int code, String msg) {
TipToast.shortTip("请求异常,请稍后重试");
}
});
}
// 查询抢单结果
public void queryOrderGrabStatus() {
if (mNewBookingOrder == null) {
OCHTaxiModelLoopManager.getInstance().stopGrabResultLoop();
if (mOrderStatusCallback != null) {
mOrderStatusCallback.onGrabOrderFailed(null);
}
return;
}
final long orderId = mNewBookingOrder.orderId;
OCHTaxiServiceManagerNew.getInstance().queryOrderGrabStatus(mContext, orderId,
new OCHTaxiServiceCallback<OrderGrabStatusQueryRespBean>() {
@Override
public void onSuccess(OrderGrabStatusQueryRespBean data) {
//OCHTaxiModelLoopManager.getInstance().stopGrabResultLoop();
if (data != null && data.code == 0
&& mNewBookingOrder != null && mNewBookingOrder.orderId == orderId) {
if (data.data.grabStatus == 0) {
return; //抢单中,不处理继续轮询结果
}
if (mOrderStatusCallback != null) {
if (data.data.grabStatus == 1) {
mOrderStatusCallback.onGrabOrderSuccess(mNewBookingOrder);
} else if (data.data.grabStatus == 2) {
mOrderStatusCallback.onGrabOrderFailed(mNewBookingOrder);
} else {
// TODO: 2021/9/22 需根据具体内容给予提示,如订单已取消
mOrderStatusCallback.onGrabOrderFailed(mNewBookingOrder);
}
}
} else {
if (mOrderStatusCallback != null) {
// TODO: 2021/9/22 如果用户已取消单抢单失败时暂返回nullUI当前直接恢复原页面内容后续优化
mOrderStatusCallback.onGrabOrderFailed(null);
}
}
OCHTaxiModelLoopManager.getInstance().stopGrabResultLoop();
cancelNewBookingOrder();
}
@Override
public void onFail(int code, String msg) {
}
});
}
// 车机端上传心跳数据(只在出车状态时上传)
public void runCarHeartbeat() {
OCHTaxiServiceManagerNew.getInstance().runCarHeartbeat(mContext, mLongitude, mLatitude,
new OCHTaxiServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData data) {
}
@Override
public void onFail(int code, String msg) {
}
});
}
// 查询司机服务数据
public void queryDriverServiceData() {
OCHTaxiServiceManagerNew.getInstance().queryDriverServiceData(mContext,
new OCHTaxiServiceCallback<DriverServiceDataRespBean>() {
@Override
public void onSuccess(DriverServiceDataRespBean data) {
if (data != null && data.code == 0
&& data.data != null && data.data.immediate != null) {
if (mCarStatusCallback != null) {
mCarStatusCallback.onServiceDataUpdate(
data.data.immediate.timeDuration, data.data.immediate.orderNum);
}
}
}
@Override
public void onFail(int code, String msg) {
}
});
}
// 取消当前新到预约单
public void cancelNewBookingOrder() {
mNewBookingOrder = null;
}
// 获取当前订单
public OrderQueryRespBean.Result getCurrentOCHOrder() {
return mCurrentOCHOrder;
}
// 获取当前订单状态
public OrderStatusEnum getCurOrderStatus() {
OrderQueryRespBean.Result order = MogoOCHTaxiModelNew.getInstance().getCurrentOCHOrder();
if (order == null) {
return OrderStatusEnum.None;
}
return OrderStatusEnum.valueOf(order.orderStatus);
}
//更新本地currentOrder信息并保存订单到本地避免车机重启丢失数据
private void updateNativeCurrentOrder(OrderQueryRespBean.Result data) {
if (data == null) {
return;
}
mCurrentOCHOrder = data;
SharedPrefsMgr.getInstance(mContext).putString(OCHTaxiConst.SP_KEY_OCH_TAXI_ORDER,
GsonUtil.jsonFromObject(data));
}
//清除订单信息
public void clearCurrentOCHOrder() {
mCurrentOCHOrder = null;
SharedPrefsMgr.getInstance(mContext).remove(OCHTaxiConst.SP_KEY_OCH_TAXI_ORDER);
}
//检测当前订单
public boolean checkCurrentOCHOrder() {
if ( mCurrentOCHOrder != null
&& mCurrentOCHOrder.startSiteGcjPoint != null
&& mCurrentOCHOrder.endSiteGcjPoint != null) {
return true;
}
return false;
}
//以当前订单为基础,开启自动驾驶
public void startAutoPilot() {
if (!checkCurrentOCHOrder()) {
Logger.e( TAG, "no order or order is empty." );
TipToast.shortTip("当前订单不存在或异常!");
return;
}
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
== Integer.parseInt(DebugConfig.getAutoPilotStatus())) {
// TODO: 2021/11/28 工控机存在刚开始状态为0但是可以开启变为2工控机解决前不显示此toast
// TipToast.shortTip("自动驾驶状态为不可用!");
}
double startWgsLon = mCurrentOCHOrder.startSitePoint.get(0);
double startWgsLat = mCurrentOCHOrder.startSitePoint.get(1);
double endWgsLon = mCurrentOCHOrder.endSitePoint.get(0);
double endWgsLat = mCurrentOCHOrder.endSitePoint.get(1);
AutopilotControlParameters parameters = new AutopilotControlParameters();
parameters.vehicleType = mCurrentOCHOrder.businessType;
parameters.startName = PinYinUtil.getPinYinHeadChar(mCurrentOCHOrder.startSiteAddr); // 起点名称拼音首字母大写科学城B区2号门KXCBQ2HM
parameters.endName = PinYinUtil.getPinYinHeadChar(mCurrentOCHOrder.endSiteAddr); // 终点名称拼音首字母大写科学城C区三号门KXCCQSHM
parameters.startLatLon = new AutopilotControlParameters.AutoPilotLonLat(startWgsLat, startWgsLon);
parameters.endLatLon = new AutopilotControlParameters.AutoPilotLonLat(endWgsLat, endWgsLon);
CallerAutoPilotManager.INSTANCE.startAutoPilot(parameters);
Logger.d(TAG, "start autopilot with parameter: %s", GsonUtil.jsonFromObject(parameters)
+" ,startSiteName="+ mCurrentOCHOrder.startSiteAddr+" ,endSiteName="+mCurrentOCHOrder.endSiteAddr);
if (DebugConfig.isDebug()) {
// TipToast.shortTip("Start autopilot!");
}
// TODO: 2021/8/20 无工控机环境, 手动调起自动驾驶开启返回结果,有工控机环境要删除
// OCHTaxiUiController.getInstance().onAutoPilotStatusChanged( IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING, "开启自动驾驶" );
}
//结束自动驾驶
public void cancelAutopilot() {
try {
CallerAutoPilotManager.INSTANCE.cancelAutoPilot();
Logger.d(TAG, "结束自动驾驶");
} catch ( Exception e ) {
e.printStackTrace();
}
}
//根据围栏判断,是否到达起点
private void judgeStartStation(Location location) {
if (mCurrentOCHOrder == null || mCurrentOCHOrder.startSiteGcjPoint == null
|| mCurrentOCHOrder.startSiteGcjPoint.size() < 2) {
return;
}
double startLon = mCurrentOCHOrder.startSiteGcjPoint.get(0);
double startLat = mCurrentOCHOrder.startSiteGcjPoint.get(1);
double distance = CoordinateUtils.calculateLineDistance(
startLon, startLat,
location.getLongitude(), location.getLatitude() );
if (DebugConfig.isDebug() && mCurrentOCHOrder.orderStatus == OrderStatusEnum.OnTheWayToStartStation.getCode()) {
// TipToast.shortTip("距离上车点:" + Double.valueOf(distance).intValue());
}
Logger.i(TAG, "judgeStartStation() distance = " + distance);
// if (mOrderStatusCallback != null && distance >= 0) {
// mOrderStatusCallback.onCurrentOrderDistToStartChanged((long) distance, 0);
// }
if ( distance > OCHTaxiConst.ARRIVE_AT_START_STATION_DISTANCE ) {
distance = CoordinateUtils.calculateLineDistance(startLon, startLat,
MogoApisHandler.getInstance().getApis().getAdasControllerApi().getLastLon(),
MogoApisHandler.getInstance().getApis().getAdasControllerApi().getLastLat() );
}
if ( distance <= OCHTaxiConst.ARRIVE_AT_START_STATION_DISTANCE ) {
updateOCHOrderStatus( OrderStatusEnum.ArriveAtStartStation);
return;
}
}
// TODO: 2021/9/12
public void calculateTravelDistance(Location carLocation){
if (checkCurrentOCHOrder() && mCurrentOCHOrder.endSiteGcjPoint.size()>0) {
double endLon = mCurrentOCHOrder.endSiteGcjPoint.get(0);
double endLat = mCurrentOCHOrder.endSiteGcjPoint.get(1);
double distance = CoordinateUtils.calculateLineDistance(
endLon, endLat,
carLocation.getLongitude(), carLocation.getLatitude());
mCurrentOCHOrder.decreaseTravelDistance(distance);
if (mOrderStatusCallback != null && distance >= 0) {
mOrderStatusCallback.onCurrentOrderDistToEndChanged((long) distance, 0);
}
}
}
//监听网络变化,避免启动机器时无网导致无法更新订单信息
private IMogoIntentListener mNetWorkIntentListener = new IMogoIntentListener() {
@Override
public void onIntentReceived( String intentStr, Intent intent ) {
Logger.d( TAG, "onIntentReceived = %s", intentStr );
if ( ConnectivityManager.CONNECTIVITY_ACTION.equals( intentStr ) ) {
if ( NetworkUtils.isConnected( mContext ) ) {
if (FunctionBuildConfig.appIdentityMode == 0) {
startOrStopOrderLoop(mOCHCarStatus == 1);
queryCarStatus();
}
}
}
}
};
private IMogoStatusChangedListener mMogoStatusChangedListener = new IMogoStatusChangedListener() {
// VR mode变更回调
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (StatusDescriptor.VR_MODE == descriptor) {
if (mControllerStatusCallback != null) {
mControllerStatusCallback.onVRModeChanged(isTrue);
}
}
}
};
private IMogoLifecycleListener mSocketLifeCycleLisnter = new IMogoLifecycleListener() {
@Override
public void onConnectFailure() { Logger.e(TAG,"socket onConnectFailure"); }
@Override
public void onConnectSuccess() { Logger.e(TAG,"socket onConnectSuccess"); }
@Override
public void onConnectLost() { Logger.e(TAG,"socket onConnectLost"); }
};
// 自车定位
private IMogoCarLocationChangedListener2 mCarLocationChangedListener2 = new IMogoCarLocationChangedListener2() {
@Override
public void onCarLocationChanged(MogoLatLng latLng) {
}
@Override
public void onCarLocationChanged2( Location location ) {
IMogoServiceApis apis = MogoApisHandler.getInstance().getApis();
MogoLocation mogoLocation = new MogoLocation();
mogoLocation.setAccuracy(location.getAccuracy());
mogoLocation.setProvider(location.getProvider());
mogoLocation.setLongitude(location.getLongitude());
mogoLocation.setLatitude(location.getLatitude());
mogoLocation.setSpeed(location.getSpeed());
mogoLocation.setBearing(location.getBearing());
// TODO: 2021/9/2 因0830新版server后台只能过滤locType=1&&satellites>=4的定位数据暂固话值后续优化
mogoLocation.setLocType(1);
mogoLocation.setSatellite(4);
apis.getLocationInfoApi().provideLocation(mogoLocation);
//位置变化时通过围栏判断是否到达x点
if (location != null && checkCurrentOCHOrder()) {
if (getCurOrderStatus() == OrderStatusEnum.OnTheWayToStartStation) {
judgeStartStation(location);
} else if (getCurOrderStatus() == OrderStatusEnum.OnTheWayToEndStation) {
calculateTravelDistance(location);
}
}
mLongitude = location.getLongitude();
mLatitude = location.getLatitude();
if (mControllerStatusCallback != null) {
mControllerStatusCallback.onCarLocationChanged(location);
}
}
};
/**
* 订单流转debug START
*/
public void setArriveAtStartStation() {
if (mCurrentOCHOrder == null
|| mCurrentOCHOrder.orderStatus != OrderStatusEnum.OnTheWayToStartStation.getCode()) {
TipToast.shortTip("订单状态不匹配该操作!");
return;
}
updateOCHOrderStatus(OrderStatusEnum.ArriveAtStartStation);
}
public void setArriveAtEndStation() {
if (mCurrentOCHOrder == null
|| mCurrentOCHOrder.orderStatus != OrderStatusEnum.OnTheWayToEndStation.getCode()) {
TipToast.shortTip("订单状态不匹配该操作!");
return;
}
updateOCHOrderStatus(OrderStatusEnum.ArriveAtEndStation);
}
/**
* 测试开始服务
*/
public void setOnTheWayToEndStation() {
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotRunning();
if (mCurrentOCHOrder == null
|| mCurrentOCHOrder.orderStatus != OrderStatusEnum.ArriveAtStartStation.getCode()) {
TipToast.shortTip("订单状态不匹配该操作!");
}
updateOCHOrderStatus(OrderStatusEnum.OnTheWayToEndStation);
}
private IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener(){
@Override
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autopilotStatusInfo) {
if (autopilotStatusInfo == null) return;
int state = autopilotStatusInfo.getState();
Logger.d( TAG, "state = %s", state );
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotRunning();
if (mCurrentOCHOrder != null
&& getCurOrderStatus() == OrderStatusEnum.ArriveAtStartStation
&& state != mPrevAPStatus) {
// 当高频返回autopilot 2时不重复调用订单状态变更
mPrevAPStatus = state; // 每个状态单独赋值解决无订单时已经是2的状态导致的新订单来时无法进入此逻辑更新状态
updateOCHOrderStatus(OrderStatusEnum.OnTheWayToEndStation);
}
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
mPrevAPStatus = state;
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotEnable();
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
mPrevAPStatus = state;
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotDisable();
}
}
@Override
public void onAutopilotSNRequest() {
}
@Override
public void onAutopilotGuardian(@Nullable AutopilotGuardianStatusInfo autopilotGuardianStatusInfo) {
}
@Override
public void onAutopilotArriveAtStation(@Nullable AutopilotStationInfo data) {
if (data == null || !checkCurrentOCHOrder()
|| (getCurOrderStatus() == OrderStatusEnum.ArriveAtEndStation)) {
return;
}
if (DebugConfig.isDebug()) {
// TipToast.shortTip("到达目的地");
}
updateOCHOrderStatus(OrderStatusEnum.ArriveAtEndStation);
}
};
private IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener(){
@Override
public void onAutopilotTrajectory(ArrayList<ADASTrajectoryInfo> trajectoryInfos) {
}
@Override
public void onAutopilotRotting(AutopilotRouteInfo routeList) {
if (null != routeList && routeList.getModels() != null){
mAutopilotPlanningCallback.routeResult(routeList.getModels());
}
}
};
/**
* END
*/
}

View File

@@ -0,0 +1,433 @@
package com.mogo.och.taxi.passenger.model;
import android.Manifest;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.AMapCalcRouteResult;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapModelCross;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviRouteNotifyData;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiNaviChangedCallback;
import com.mogo.och.taxi.passenger.utils.PermissionUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author: wangmingjun
* @date: 2021/12/6
*/
public class NaviToDestinationModel implements AMapNaviListener {
private static Context mContext;
private AMapNavi mAMapNavi = null;
protected final List<NaviLatLng> sList = new ArrayList<NaviLatLng>();
protected final List<NaviLatLng> eList = new ArrayList<NaviLatLng>();
protected List<NaviLatLng> mWayPointList = new ArrayList<NaviLatLng>();
private IOCHTaxiNaviChangedCallback mNaviChangedCallback;
private AtomicInteger errorCount = new AtomicInteger(0);
private boolean isPlay;
public static NaviToDestinationModel getInstance(Context context) {
mContext = context;
return SingletonHolder.INSTANCE;
}
private static final class SingletonHolder {
private static final NaviToDestinationModel INSTANCE = new NaviToDestinationModel();
}
private NaviToDestinationModel(){
}
public void initAMapNavi(NaviLatLng startLatLng,NaviLatLng endLatLng) {
try {
mAMapNavi = AMapNavi.getInstance(mContext);
mAMapNavi.addAMapNaviListener(this);
mAMapNavi.setUseInnerVoice(true, true);
sList.add(startLatLng);
eList.add(endLatLng);
}catch (Exception e) {
e.printStackTrace();
}
}
public void setVoiceIsMute(boolean isPlay){
if (mAMapNavi == null) return;
this.isPlay = isPlay;
if (isPlay){
mAMapNavi.startSpeak();
}else {
mAMapNavi.stopSpeak();
}
}
public AMapNavi getmAMapNavi() {
return mAMapNavi;
}
public void destroyAmaNavi(){
if (mAMapNavi != null){
isPlay = false;
mAMapNavi.stopNavi();
mAMapNavi.destroy();
mAMapNavi = null;
mNaviChangedCallback = null;
}
}
public void setOCHTaciNaviChangedCallback(IOCHTaxiNaviChangedCallback callback){
this.mNaviChangedCallback = callback;
}
@Override
public void onInitNaviFailure() {
Toast.makeText(mContext, "init navi Failed", Toast.LENGTH_SHORT).show();
}
@Override
public void onInitNaviSuccess() {
//初始化成功
/**
* 方法: int strategy=mAMapNavi.strategyConvert(congestion, avoidhightspeed, cost, hightspeed, multipleroute); 参数:
*
* @congestion 躲避拥堵
* @avoidhightspeed 不走高速
* @cost 避免收费
* @hightspeed 高速优先
* @multipleroute 多路径
*
* 说明: 以上参数都是boolean类型其中multipleroute参数表示是否多条路线如果为true则此策略会算出多条路线。
* 注意: 不走高速与高速优先不能同时为true 高速优先与避免收费不能同时为true
*/
int strategy = 0;
try {
//再次强调最后一个参数为true时代表多路径否则代表单路径
strategy = mAMapNavi.strategyConvert(true, false, false, false, false);
} catch (Exception e) {
e.printStackTrace();
}
mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy);
}
@Override
public void onCalculateRouteSuccess(int[] ints) {
//多路径算路成功回调
mAMapNavi.startNavi(NaviType.GPS);
}
@Override
public void onNaviInfoUpdate(NaviInfo naviinfo) {
//导航过程中的信息更新请看NaviInfo的具体说明
if (null != mNaviChangedCallback){
mNaviChangedCallback.onCurrentNaviDistAndTimeChanged(naviinfo.getPathRetainDistance(),naviinfo.getPathRetainTime());// 米、秒
}
}
@Override
public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
errorCount.set(0);
}
@Override
public void onCalculateRouteFailure(AMapCalcRouteResult result) {
//路线计算失败
//多路径算路成功回调
if (errorCount.get() < 5){
errorCount.getAndIncrement();
if (mNaviChangedCallback != null){
mNaviChangedCallback.reInitNaviAmap(isPlay,true);
}
}
if (!NetworkUtils.isConnected(mContext) || result.getErrorCode() == 2){
TipToast.longTip("网络异常,请重试");
if (mNaviChangedCallback != null){
mNaviChangedCallback.reInitNaviAmap(isPlay,false);
}
return;
}
if (!PermissionUtil.isLocServiceEnable(mContext) || !PermissionUtil.checkPermission(mContext,new String[]{Manifest.permission.ACCESS_FINE_LOCATION})){
TipToast.longTip("请开启车机定位后重试");
if (mNaviChangedCallback != null){
mNaviChangedCallback.reInitNaviAmap(isPlay,false);
}
return;
}
// if (result.getErrorCode() == 3){
// TipToast.longTip("车辆当前坐标错误");
// }else if (result.getErrorCode() == 6){
// TipToast.longTip("终点坐标错误");
// }
Log.i("dm", "路线计算失败:错误码=" + result.getErrorCode() + ",Error Message= " + result.getErrorDetail());
Log.i("dm", "错误码详细链接见http://lbs.amap.com/api/android-navi-sdk/guide/tools/errorcode/");
}
@Override
public void onStartNavi(int type) {
//开始导航回调
}
@Override
public void onTrafficStatusUpdate() {
//
}
@Override
public void onLocationChange(AMapNaviLocation location) {
//当前位置回调
}
@Override
public void onGetNavigationText(int type, String text) {
//播报类型和播报文字回调
}
@Override
public void onGetNavigationText(String s) {
}
@Override
public void onEndEmulatorNavi() {
//结束模拟导航
}
@Override
public void onArriveDestination() {
//到达目的地
}
@Override
public void onCalculateRouteFailure(int errorInfo) {
}
@Override
public void onReCalculateRouteForYaw() {
//偏航后重新计算路线回调
}
@Override
public void onReCalculateRouteForTrafficJam() {
//拥堵后重新计算路线回调
}
@Override
public void onArrivedWayPoint(int wayID) {
//到达途径点
}
@Override
public void onGpsOpenStatus(boolean enabled) {
//GPS开关状态回调
}
@Override
public void showModeCross(AMapModelCross aMapModelCross) {
}
@Override
public void hideModeCross() {
}
@Override
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {
}
@Override
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
//显示车道信息
// StringBuffer sb = new StringBuffer();
// sb.append("共" + aMapLaneInfo.frontLane.length + "车道");
// for (int i = 0; i < aMapLaneInfo.frontLane.length; i++) {
// //当前车道可以选择的动作
// int background = aMapLaneInfo.backgroundLane[i];
// //当前用户要执行的动作
// int recommend = aMapLaneInfo.frontLane[i];
//
// Log.e("ggb", "---->>> background is " + background + " ; recommend is " + recommend);
// //根据文档中每个动作对应的枚举类型,显示对应的图片
// try {
// sb.append(",第" + (i + 1) + "车道为" + array[background]);
// if (recommend != 255) {
// sb.append(",当前车道可 " + actions[recommend]);
// }
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// Log.e("showLaneInfo", sb.toString());
}
@Override
public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) {
}
@Override
public void updateCameraInfo(AMapNaviCameraInfo[] aMapCameraInfos) {
}
@Override
public void onServiceAreaUpdate(AMapServiceAreaInfo[] amapServiceAreaInfos) {
}
@Override
public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
//已过时
}
@Override
public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
}
@Override
public void showCross(AMapNaviCross aMapNaviCross) {
//显示放大图回调
}
@Override
public void hideCross() {
//隐藏放大图回调
}
@Override
public void showLaneInfo(AMapLaneInfo[] laneInfos, byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) {
//过时
}
@Override
public void hideLaneInfo() {
//隐藏车道信息
}
@Override
public void notifyParallelRoad(int i) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
//更新交通设施信息
}
@Override
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
//更新巡航模式的统计信息
}
@Override
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
//更新巡航模式的拥堵信息
}
@Override
public void onPlayRing(int i) {
}
/**
* 车道信息说明:
* <p>
* 0xFF, 无对应车道
* 0, 直行
* 1, 左转
* 2, 直行+左转
* 3, 右转
* 4, 直行+右转
* 5, 左掉头
* 6, 左转+右转
* 7, 直行+左转+右转
* 8, 右掉头
* 9, 直行+左掉头
* 10, 直行+右掉头
* 11, 左转+左掉头
* 12, 右转+右掉头
* 13, 直行+扩展
* 14, 左转+左掉头+扩展
* 15, 保留
* 16, 直行+左转+左掉头
* 17, 右转+左掉头
* 18, 左转+右转+左掉头
* 19, 直行+右转+左掉头
* 20, 左转+右掉头
* 21, 公交车道
* 22, 空车道
* 23 可变车道
*/
String[] array = {
"直行车道"
, "左转车道"
, "左转或直行车道"
, "右转车道"
, "右转或直行车道"
, "左掉头车道"
, "左转或者右转车道"
, " 左转或右转或直行车道"
, "右转掉头车道"
, "直行或左转掉头车道"
, "直行或右转掉头车道"
, "左转或左掉头车道"
, "右转或右掉头车道"
, "直行并且车道扩展"
, "左转+左掉头+扩展"
, "不可以选择该车道"
, "直行+左转+左掉头车道"
, "右转+左掉头"
, "左转+右转+左掉头"
, "直行+右转+左掉头"
, "左转+右掉头"
, "公交车道"
, "空车道"
, "可变车道"
};
String[] actions = {
"直行"
, "左转"
, "左转或直行"
, "右转"
, "右转或这行"
, "左掉头"
, "左转或者右转"
, " 左转或右转或直行"
, "右转掉头"
, "直行或左转掉头"
, "直行或右转掉头"
, "左转或左掉头"
, "右转或右掉头"
, "直行并且车道扩展"
, "左转+左掉头+扩展"
, "不可以选择"
, "直行+左转+左掉头"
, "右转+左掉头"
, "左转+右转+左掉头"
, "直行+右转+左掉头"
, "左转+右掉头"
, "公交车道"
, "空车道"
, "可变车道"
};
}

View File

@@ -0,0 +1,118 @@
package com.mogo.och.taxi.passenger.model;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.och.taxi.passenger.constant.OCHTaxiConst;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Created on 2021/9/10
*
* 管理轮询逻辑(订单轮询、新单轮询、新单抢单结果轮询等等)
*/
public class OCHTaxiModelLoopManager {
private static final String TAG = OCHTaxiModelLoopManager.class.getSimpleName();
private static final class SingletonHolder {
private static final OCHTaxiModelLoopManager INSTANCE = new OCHTaxiModelLoopManager();
}
public static OCHTaxiModelLoopManager getInstance() {
return SingletonHolder.INSTANCE;
}
private Disposable mInAndWaitServiceDisposable; //进行中、待服务订单列表轮询
private Disposable mNewBookingOrderDisposable; //新到待抢预约单轮询
private Disposable mGrabResultDisposable; //抢单结果轮询
private Disposable mHeartbeatDisposable; //心跳轮询
public void startInAndWaitOrdersLoop() {
if (mInAndWaitServiceDisposable != null && !mInAndWaitServiceDisposable.isDisposed()) {
return;
}
Logger.i(TAG, "startInAndWaitOrdersLoop()");
mInAndWaitServiceDisposable = Observable.interval(OCHTaxiConst.LOOP_DELAY,
OCHTaxiConst.LOOP_PERIOD_2S, TimeUnit.MILLISECONDS,Schedulers.trampoline())
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> MogoOCHTaxiModelNew.getInstance().queryInAndWaitOrders());
}
public void stopInAndWaitOrdersLoop() {
if (mInAndWaitServiceDisposable != null) {
Logger.i(TAG, "stopInAndWaitOrdersLoop()");
mInAndWaitServiceDisposable.dispose();
mInAndWaitServiceDisposable = null;
}
}
public void startNewBookingOrderLoop() {
if (mNewBookingOrderDisposable != null && !mNewBookingOrderDisposable.isDisposed()) {
return;
}
Logger.i(TAG, "startNewBookingOrderLoop()");
mNewBookingOrderDisposable = Observable.interval(OCHTaxiConst.LOOP_DELAY,
OCHTaxiConst.LOOP_PERIOD_1S, TimeUnit.MILLISECONDS,Schedulers.trampoline())
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> MogoOCHTaxiModelNew.getInstance().queryNewBookingOrder());
}
public void stopNewBookingOrderLoop() {
if (mNewBookingOrderDisposable != null) {
Logger.i(TAG, "stopNewBookingOrderLoop()");
mNewBookingOrderDisposable.dispose();
mNewBookingOrderDisposable = null;
}
}
public void startGrabResultLoop() {
if (mGrabResultDisposable != null && !mGrabResultDisposable.isDisposed()) {
return;
}
Logger.i(TAG, "startGrabResultLoop()");
mGrabResultDisposable = Observable.interval(OCHTaxiConst.LOOP_DELAY,
OCHTaxiConst.LOOP_PERIOD_1S, TimeUnit.MILLISECONDS,Schedulers.trampoline())
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> MogoOCHTaxiModelNew.getInstance().queryOrderGrabStatus());
}
public void stopGrabResultLoop() {
if (mGrabResultDisposable != null) {
Logger.i(TAG, "stopGrabResultLoop()");
mGrabResultDisposable.dispose();
mGrabResultDisposable = null;
}
}
public void startHeartbeatLoop() {
if (mHeartbeatDisposable != null && !mHeartbeatDisposable.isDisposed()) {
return;
}
Logger.i(TAG, "startHeartbeatLoop()");
mHeartbeatDisposable = Observable.interval(OCHTaxiConst.LOOP_DELAY,
OCHTaxiConst.LOOP_PERIOD_60S, TimeUnit.MILLISECONDS,Schedulers.trampoline())
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> MogoOCHTaxiModelNew.getInstance().runCarHeartbeat());
}
public void stopHeartbeatLoop() {
if (mHeartbeatDisposable != null) {
Logger.i(TAG, "stopHeartbeatLoop()");
mHeartbeatDisposable.dispose();
mHeartbeatDisposable = null;
}
}
}

View File

@@ -0,0 +1,161 @@
package com.mogo.och.taxi.passenger.network;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.taxi.passenger.bean.CarHeartbeatReqBean;
import com.mogo.och.taxi.passenger.bean.DriverServiceDataRespBean;
import com.mogo.och.taxi.passenger.bean.DriverStatusQueryRespBean;
import com.mogo.och.taxi.passenger.bean.DriverStatusUpdateReqBean;
import com.mogo.och.taxi.passenger.bean.OrderCancelReqBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabReqBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabRespBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabStatusQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryReqBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoReqBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import com.mogo.och.taxi.passenger.bean.OrderStatusUpdateReqBean;
import com.mogo.och.taxi.passenger.bean.OrdersInServiceQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersListQueryReqBean;
import com.mogo.och.taxi.passenger.bean.OrdersListQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersNewBookingQueryRespBean;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* Created by pangfan on 2021/8/19
*
* 网约车-出租车接口定义
*/
interface OCHTaxiServiceApiNew {
/**
* 查询全部服务中/待服务订单没有的时候返回code 0空列表
* @param sn
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET("/autopilot-car-hailing/api/v1/driver/orderInService/query")
Observable<OrdersInServiceQueryRespBean> queryOrdersInAndWaitService(@Query("sn") String sn);
/**
* 查询新到的预约单
* @param sn
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET( "/autopilot-car-hailing/api/v1/driver/newBookingOrder/query" )
Observable<OrdersNewBookingQueryRespBean> queryNewBookingOrder(@Query("sn") String sn);
/**
* (预约单)执行抢单动作
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/grabOrder" )
Observable<OrderGrabRespBean> grabOrder(@Body OrderGrabReqBean data);
/**
* (预约单)查询抢单结果
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/grabStatus/query" )
Observable<OrderGrabStatusQueryRespBean> queryOrderGrabStatus(@Body OrderGrabReqBean data);
/**
* 查询订单路径规划信息(到上车点、起始点间的距离和预估时间)
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/routeInfo/query" )
Observable<OrderQueryRouteInfoRespBean> queryOrderRouteInfo(@Body OrderQueryRouteInfoReqBean data);
/**
* 通过orderId查询订单信息用于本地已经有orderId时
* @param data
* @return
* @deprecated v2.1_0930需求中暂不再使用此接口
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/queryOrderById" )
Observable<OrderQueryRespBean> queryOrderById(@Body OrderQueryReqBean data);
/**
* 查询服务中订单信息用于本地无orderId时
* 如果有多条,只会返回时间最近的一条
* @param sn
* @return
* @deprecated v2.1_0930需求中暂不再使用此接口
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET( "/autopilot-car-hailing/api/v1/driver/queryOrderInService" )
Observable<OrderQueryRespBean> queryOrderInService(@Query("sn") String sn);
/**
* 取消订单
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/autopilot-car-hailing/api/v1/driver/cancelOrder")
Observable<BaseData> cancelOrder(@Body OrderCancelReqBean data);
/**
* 订单列表获取
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/queryOrders" )
Observable<OrdersListQueryRespBean> queryOrdersList(@Body OrdersListQueryReqBean data);
/**
* 订单状态更新
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/order/updateStatus" )
Observable<BaseData> updateOrderStatus(@Body OrderStatusUpdateReqBean data);
/**
* 收车/出车状态更新
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/serviceStatus/update" )
Observable<BaseData> updateDriverServiceStatus(@Body DriverStatusUpdateReqBean data);
/**
* 收车/出车状态查询
* @param sn
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET( "/autopilot-car-hailing/api/v1/driver/serviceStatus/query" )
Observable<DriverStatusQueryRespBean> queryDriverServiceStatus(@Query("sn") String sn);
/**
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/api/v1/driver/heartbeat" )
Observable<BaseData> runCarHeartbeat(@Body CarHeartbeatReqBean data);
/**
* 查询司机服务数据
* @param sn
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET( "/autopilot-car-hailing/api/v1/driver/serviceData/query" )
Observable<DriverServiceDataRespBean> queryServiceData(@Query("sn") String sn);
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.taxi.passenger.network;
/**
* @author congtaowang
* @since 2021/1/15
*
* 修改订单状态回调接口
*/
public interface OCHTaxiServiceCallback< T > {
void onSuccess(T data);
void onFail(int code, String msg);
default void onError() {
}
}

View File

@@ -0,0 +1,352 @@
package com.mogo.och.taxi.passenger.network;
import android.content.Context;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.eagle.core.network.RequestOptions;
import com.mogo.eagle.core.network.SubscribeImpl;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.taxi.passenger.bean.CarHeartbeatReqBean;
import com.mogo.och.taxi.passenger.bean.DriverServiceDataRespBean;
import com.mogo.och.taxi.passenger.bean.DriverStatusQueryRespBean;
import com.mogo.och.taxi.passenger.bean.DriverStatusUpdateReqBean;
import com.mogo.och.taxi.passenger.bean.OrderCancelReqBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabReqBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabRespBean;
import com.mogo.och.taxi.passenger.bean.OrderGrabStatusQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryReqBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoReqBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import com.mogo.och.taxi.passenger.bean.OrderStatusUpdateReqBean;
import com.mogo.och.taxi.passenger.bean.OrdersInServiceQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersListQueryReqBean;
import com.mogo.och.taxi.passenger.bean.OrdersListQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrdersNewBookingQueryRespBean;
import com.mogo.och.taxi.passenger.constant.OCHTaxiConst;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by pangfan on 2021/8/19
*/
public class OCHTaxiServiceManagerNew {
private static final String TAG = OCHTaxiServiceManagerNew.class.getSimpleName();
private static final class SingletonHolder {
private static final OCHTaxiServiceManagerNew INSTANCE = new OCHTaxiServiceManagerNew();
}
public static OCHTaxiServiceManagerNew getInstance() {
return SingletonHolder.INSTANCE;
}
private String baseUrl = OCHTaxiConst.getBaseUrl();
private OCHTaxiServiceApiNew mOCHTaxiServiceApi;
private OCHTaxiServiceManagerNew() {
if (mOCHTaxiServiceApi == null){
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
}
/**
* 查询全部服务中/待服务订单列表
* @param context
* @param callback
*/
public void queryOrdersInAndWaitService(Context context,
OCHTaxiServiceCallback<OrdersInServiceQueryRespBean> callback) {
if (mOCHTaxiServiceApi == null) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryOrdersInAndWaitService(MoGoAiCloudClientConfig.getInstance().getSn())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryOrdersInAndWaitService"));
}
/**
* 查询新到的预约单
* @param context
* @param callback
*/
public void queryNewBookingOrder(Context context,
OCHTaxiServiceCallback<OrdersNewBookingQueryRespBean> callback) {
if (mOCHTaxiServiceApi == null) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryNewBookingOrder(MoGoAiCloudClientConfig.getInstance().getSn())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryNewBookingOrder"));
}
/**
* (预约单)执行抢单动作
* @param context
* @param orderId
* @param callback
*/
public void grabOrder(Context context, long orderId,
OCHTaxiServiceCallback<OrderGrabRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.grabOrder(new OrderGrabReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), orderId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "grabOrder"));
}
/**
* (预约单)查询抢单结果
* @param context
* @param orderId
* @param callback
*/
public void queryOrderGrabStatus(Context context, long orderId,
OCHTaxiServiceCallback<OrderGrabStatusQueryRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryOrderGrabStatus(new OrderGrabReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), orderId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryOrderGrabStatus"));
}
/**
* 查询订单路径规划信息(到上车点、起始点间的距离和预估时间)
* @param context
* @param orderId
* @param callback
*/
public void queryOrderRouteInfo(Context context, long orderId,
OCHTaxiServiceCallback<OrderQueryRouteInfoRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryOrderRouteInfo(new OrderQueryRouteInfoReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), orderId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryOrderRouteInfo"));
}
/**
* 通过orderId查询订单信息用于本地已经有orderId时
* @param context
* @param orderId
* @param callback
* @deprecated v2.1_0930需求中暂不再使用此接口
*/
public void queryOrderById(Context context, long orderId,
OCHTaxiServiceCallback<OrderQueryRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryOrderById(new OrderQueryReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), orderId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryOrderById"));
}
/**
* 查询未完成态订单信息用于本地无orderId时
* 如果有多条,只会返回时间最近的一条
* @param context
* @param callback
* @deprecated v2.1_0930需求中暂不再使用此接口
*/
public void queryOrderInService(Context context,
OCHTaxiServiceCallback<OrderQueryRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryOrderInService(MoGoAiCloudClientConfig.getInstance().getSn())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryOrderInService"));
}
/**
* 司机取消订单
* @param context
* @param orderId
* @param cancelType
* @param cancelReason
* @param callback
*/
public void cancelOrder(Context context, long orderId, int cancelType, String cancelReason,
OCHTaxiServiceCallback<BaseData> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.cancelOrder(new OrderCancelReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), orderId, cancelType, cancelReason))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "cancelOrder"));
}
/**
* 订单列表获取
* @param context
* @param page
* @param size
* @param callback
*/
public void queryOrdersList(Context context, int page, int size,
OCHTaxiServiceCallback<OrdersListQueryRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryOrdersList(new OrdersListQueryReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), page, size))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryOrdersList"));
}
/**
* 订单状态更新
* @param context
* @param orderId
* @param orderStatus
* @param callback
*/
public void updateOrderStatus(Context context, long orderId, int orderStatus,
OCHTaxiServiceCallback<BaseData> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.updateOrderStatus(new OrderStatusUpdateReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), orderId, orderStatus))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "updateOrderStatus"));
}
/**
* 收车/出车状态更新
* @param context
* @param status
* @param callback
*/
public void updateDriverServiceStatus(Context context, int status,
OCHTaxiServiceCallback<BaseData> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.updateDriverServiceStatus(new DriverStatusUpdateReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), status))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "updateDriverServiceStatus"));
}
/**
* 收车/出车状态查询
* @param context
* @param callback
*/
public void queryDriverServiceStatus(Context context,
OCHTaxiServiceCallback<DriverStatusQueryRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryDriverServiceStatus(MoGoAiCloudClientConfig.getInstance().getSn())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryDriverServiceStatus"));
}
/**
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
* @param context
* @param lon
* @param lat
* @param callback
*/
public void runCarHeartbeat(Context context, double lon, double lat,
OCHTaxiServiceCallback<BaseData> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.runCarHeartbeat(new CarHeartbeatReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), lon, lat))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "runCarHeartbeat"));
}
/**
* 查询司机服务数据
* @param context
* @param callback
*/
public void queryDriverServiceData(Context context,
OCHTaxiServiceCallback<DriverServiceDataRespBean> callback) {
if ( mOCHTaxiServiceApi == null ) {
mOCHTaxiServiceApi = MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(OCHTaxiServiceApiNew.class, baseUrl);
}
mOCHTaxiServiceApi.queryServiceData(MoGoAiCloudClientConfig.getInstance().getSn())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "queryDriverServiceData"));
}
private <T extends BaseData> SubscribeImpl getSubscribeImpl(
Context context, OCHTaxiServiceCallback<T> callback, String apiName) {
return new SubscribeImpl<T>(RequestOptions.create(context)) {
@Override
public void onSuccess(T o) {
super.onSuccess(o);
Logger.e(TAG,apiName + ": onSuccess() " + o.msg);
if (callback != null) {
callback.onSuccess(o);
}
}
@Override
public void onError(Throwable e) {
super.onError(e);
Logger.e(TAG,apiName + ": onError() " + e.getMessage());
if (callback != null) {
callback.onError();
}
}
@Override
public void onError(String message, int code) {
super.onError(message, code);
Logger.e(TAG,String.format(apiName + ": onError() code = %d; message = %s;", code, message));
if (callback != null) {
callback.onFail(code, message);
}
}
};
}
}

View File

@@ -0,0 +1,259 @@
package com.mogo.och.taxi.passenger.presenter;
import android.location.Location;
import android.os.Build;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.lifecycle.LifecycleOwner;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.autopilot.AutopilotRouteInfo;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiAutopilotPlanningCallback;
import com.mogo.och.taxi.passenger.constant.OrderStatusEnum;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiADASStatusCallback;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiCarStatusCallback;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiControllerStatusCallback;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiOrderStatusCallback;
import com.mogo.och.taxi.passenger.model.MogoOCHTaxiModelNew;
import com.mogo.och.taxi.passenger.ui.OCHTaxiFragment;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author congtaowang
* @since 2021/1/18
*
* 描述
*/
public class OCHTaxiPresenter extends Presenter<OCHTaxiFragment> implements IOCHTaxiADASStatusCallback,
IOCHTaxiCarStatusCallback, IOCHTaxiOrderStatusCallback, IOCHTaxiControllerStatusCallback, IOCHTaxiAutopilotPlanningCallback {
private static final String TAG = OCHTaxiPresenter.class.getSimpleName();
public OCHTaxiPresenter(OCHTaxiFragment view) {
super(view);
MogoOCHTaxiModelNew.getInstance().init(AbsMogoApplication.getApp());
initListeners();
}
@Override
public void onCreate( @NonNull LifecycleOwner owner ) {
super.onCreate( owner );
Logger.d( TAG, "网约车-出租车拿到订单" );
}
@Override
public void onDestroy( @NonNull LifecycleOwner owner ) {
super.onDestroy( owner );
releaseListeners();
MogoOCHTaxiModelNew.getInstance().release();
}
private void initListeners() {
MogoOCHTaxiModelNew.getInstance().setADASStatusCallback(this);
MogoOCHTaxiModelNew.getInstance().setCarStatusCallback(this);
MogoOCHTaxiModelNew.getInstance().setControllerStatusCallback(this);
MogoOCHTaxiModelNew.getInstance().setOrderStatusCallback(this);
MogoOCHTaxiModelNew.getInstance().setMoGoAutopilotPlanningListener(this);
}
private void releaseListeners() {
MogoOCHTaxiModelNew.getInstance().setADASStatusCallback(null);
MogoOCHTaxiModelNew.getInstance().setCarStatusCallback(null);
MogoOCHTaxiModelNew.getInstance().setControllerStatusCallback(null);
MogoOCHTaxiModelNew.getInstance().setOrderStatusCallback(null);
MogoOCHTaxiModelNew.getInstance().setMoGoAutopilotPlanningListener(null);
}
private void runOnUIThread( Runnable executor ) {
if ( executor == null ) {
return;
}
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( executor );
} else {
executor.run();
}
}
// 开启自动驾驶
public void startAutoPilot() {
MogoOCHTaxiModelNew.getInstance().startAutoPilot();
}
// 更新出车/收车状态
public void updateCarStatus() {
MogoOCHTaxiModelNew.getInstance().updateCarStatus();
}
// 更新当前订单状态(当前订单状态流转)
public void updateCurOrderStatus(OrderStatusEnum status) {
MogoOCHTaxiModelNew.getInstance().updateOCHOrderStatus(status);
}
// 获取当前订单状态
public OrderStatusEnum getCurOrderStatus() {
return MogoOCHTaxiModelNew.getInstance().getCurOrderStatus();
}
// 取消当前订单
public void cancelCurOrder(int reasonType, String reason) {
MogoOCHTaxiModelNew.getInstance().cancelCurrentOrder(reasonType, reason);
}
// 取消待服务中订单
public void cancelOrderById(long orderId, int reasonType, String reason) {
MogoOCHTaxiModelNew.getInstance().cancelOrderById(orderId, reasonType, reason);
}
// 查询当前订单route信息预估时间、里程等
public void queryCurOrderRouteInfo() {
MogoOCHTaxiModelNew.getInstance().queryCurOrderRouteInfo();
}
// 获取全部订单列表
public void queryOrdersList(int page, int size) {
MogoOCHTaxiModelNew.getInstance().queryOrdersList(page, size);
}
// 执行抢单动作
public void grabOrder() {
MogoOCHTaxiModelNew.getInstance().grabOrder();
}
// 关闭新到预约单
public void cancelNewBookingOrder() {
MogoOCHTaxiModelNew.getInstance().cancelNewBookingOrder();
}
// 查询司机服务数据
public void queryDriverServiceData() {
MogoOCHTaxiModelNew.getInstance().queryDriverServiceData();
}
@Override
public void onAutopilotArriveEnd() {
}
@Override
public void onAutopilotEnable() {
mView.updateAutopilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE);
}
@Override
public void onAutopilotDisable() {
mView.updateAutopilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE);
}
@Override
public void onAutopilotRunning() {
mView.updateAutopilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING);
}
@Override
public void onCarStatusChanged(boolean inOperation) {
mView.updateOperationStatus(inOperation);
}
@Override
public void onServiceDataUpdate(long dailyTimeDuration, long dailyOrderNum) {
mView.onServiceDataUpdate(dailyTimeDuration,dailyOrderNum);
}
@Override
public void onOrdersInServiceChanged(@NonNull @NotNull List<OrderQueryRespBean.Result> inServiceList) {
}
@Override
public void onOrdersWaitServiceChanged(@NonNull @NotNull List<OrderQueryRespBean.Result> waitServiceList) {
mView.onOrdersWaitServiceChanged(waitServiceList);
}
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
public void onCurrentOrderStatusChanged(OrderQueryRespBean.Result order) {
Log.d(TAG,"order = "+order.toString());
mView.updateCurrentOrderStatusChanged(order);
}
@Override
public void onCurrentOrderCancelDone() {
mView.onCurrentOrderCancelDone();
}
@Override
public void onOrderCancelDone(long orderId) {
mView.onOrderCancelDone(orderId);
}
@Override
public void onCurrentOrderRouteInfoGot(OrderQueryRouteInfoRespBean.Result routeInfo) {
mView.onCurrentOrderRouteInfoGot(routeInfo);
}
@Override
public void onCurrentOrderDistToStartChanged(long meters, long timeInSecond) {
mView.onCurrentOrderDistToStartChanged(meters,timeInSecond);
}
@Override
public void onCurrentOrderDistToEndChanged(long meters, long timeInSecond) {
mView.onCurrentOrderDistToEndChanged(meters,timeInSecond);
}
@Override
public void onOrdersListPageRefresh(List<OrderQueryRespBean.Result> ordersList) {
mView.onOrdersListPageRefresh(ordersList);
}
@Override
public void onNewBookingOrderGot(OrderQueryRespBean.Result order) {
mView.onNewBookingOrderGot(order);
}
@Override
public void onGrabOrderExecuteDone() {
mView.onGrabOrderExecuteDone();
}
@Override
public void onGrabOrderSuccess(OrderQueryRespBean.Result order) {
mView.onGrabOrderSuccess(order);
}
@Override
public void onGrabOrderFailed(OrderQueryRespBean.Result order) {
mView.onGrabOrderFailed(order);
}
@Override
public void onVRModeChanged(boolean isVRMode) {
runOnUIThread(() -> mView.switchVRFlatMode(isVRMode));
}
@Override
public void onCarLocationChanged(Location location) {
if (null != location){
runOnUIThread(() -> mView.updateSpeedView(location.getSpeed()));
mView.updateLocation(location.getLatitude(),location.getLongitude());
}
}
@Override
public void routeResult(List<AutopilotRouteInfo.RouteModels> models) {
if (models != null && models.size() > 0) mView.routeResult(models);
}
}

View File

@@ -0,0 +1,475 @@
package com.mogo.och.taxi.passenger.ui;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.constraintlayout.widget.Group;
import androidx.fragment.app.FragmentTransaction;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.mvp.IView;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.commons.mvp.Presenter;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.call.map.CallerSmpManager;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.uicontroller.VisualAngleMode;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.constants.DataTypes;
import com.mogo.module.common.view.OnPreventFastClickListener;
import com.mogo.och.taxi.passenger.R;
/**
* 网约车基础Fragment主要负责布局通用界面处理站点面板和通话面板互斥情况
* <p>
* 部分业务放在了此处处理
*
* @author tongchenfei
*/
public abstract class BaseOchTaxiTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener {
private static final String TAG = "BaseOchFragment";
private LinearLayout ctvAutopilotStatus;
protected TextView tvOperationStatus;
public boolean isOperationStatus;//false-收车true-出车
protected FrameLayout flStationPanelContainer;
private FrameLayout flNaviPanelContainer;
private Group groupTestPanel;
private TextView mSpeedView;
private ImageView mAutopilotImage;
private TextView mAutopilotTv;
private LinearLayout mMapswitchBtn;
private ImageView mCloseNaviIcon;
protected LinearLayout mPersonalBtn;
protected LinearLayout mSettingBtn;
protected OCHNaviFragment ochNaviFragment = null;
private Handler mHandler = new Handler(Looper.getMainLooper());
@Override
protected int getLayoutId() {
return R.layout.taxi_base_fragment;
}
private View panelView;
@Override
protected void initViews() {
groupTestPanel = findViewById(R.id.groupTestPanel);
ctvAutopilotStatus = findViewById(R.id.module_mogo_och_autopilot_status);
ctvAutopilotStatus.setBackground(getResources().getDrawable(R.drawable.taxi_autopilot_bg_selector));
mAutopilotImage = findViewById(R.id.module_och_autopilot_iv);
mAutopilotTv = findViewById(R.id.module_och_autopilot_tv);
flStationPanelContainer = findViewById(R.id.module_mogo_och_station_panel_container);
mPersonalBtn = findViewById(R.id.module_och_taxi_personal_layout);
mSpeedView = findViewById(R.id.module_mogo_och_speed_tv);
mCloseNaviIcon = findViewById(R.id.taxi_close_navi_icon);
flNaviPanelContainer = findViewById(R.id.module_mogo_och_navi_panel_container);
if (DebugConfig.isDebug()) {
mSpeedView.setLongClickable(true);
// TODO: 2021/11/27 暂去除此调试功能
// mSpeedView.setOnClickListener(v -> {
// onAutopilotStatusChanged(false);
// });
mSpeedView.setOnLongClickListener(v -> {
Log.d(TAG,"长按显示状态工具栏");
Intent intent = new Intent();
intent.putExtra("oper", 52);
MogoApisHandler.getInstance().getApis().getIntentManagerApi().invoke("com.mogo.mock", intent);
return true;
});
}
tvOperationStatus = findViewById(R.id.module_mogo_och_operation_status);
mMapswitchBtn = findViewById(R.id.module_och_taxi_swich_map_layout);
mMapswitchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//视角切换
if (MogoApisHandler.getInstance().getApis().getMapServiceApi().getMapUIController().getCurrentMapVisualAngle().isLongSight()) {
MogoApisHandler.getInstance().getApis().getMapServiceApi().getMarkerManager(AbsMogoApplication.getApp()).visibleAllMarkers();
MogoApisHandler.getInstance().getApis().getMapServiceApi()
.getMapUIController().changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null);
} else if (MogoApisHandler.getInstance().getApis().getMapServiceApi().getMapUIController().getCurrentMapVisualAngle().isMediumSight()) {
MogoApisHandler.getInstance().getApis().getMapServiceApi().getMarkerManager(AbsMogoApplication.getApp()).inVisibleWithoutMarkers(DataTypes.TYPE_MARKER_ADAS);
MogoApisHandler.getInstance().getApis().getMapServiceApi()
.getMapUIController().changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null);
}
}
});
mPersonalBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onGoToTaxiOrders();
}
});
mSettingBtn = findViewById(R.id.module_och_taxi_setting_layout);
mSettingBtn.setOnClickListener(v -> {
// TODO: 2021/12/9
CallerHmiManager.INSTANCE.showToolsView();
});
panelView = LayoutInflater.from(getContext()).inflate(getStationPanelViewId(), flStationPanelContainer);
ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
@Override
public void onClickImpl(View v) {
// 如果能自动驾驶,就自动驾驶,不能就提示
if (FunctionBuildConfig.appIdentityMode == 0) {
restartAutopilot();
}
// TODO: 2021/11/27 通过开启结果更新ui
// onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING);
}
});
// debug下调用测试面板
// if (DebugConfig.isDebug()) {
// ctvAutopilotStatus.setOnLongClickListener(v -> {
// if (groupTestPanel.getVisibility() == View.VISIBLE) {
groupTestPanel.setVisibility(View.GONE);
// } else {
// groupTestPanel.setVisibility(View.VISIBLE);
// }
// return false;
// });
// }
onAutopilotStatusChanged(MogoApisHandler.getInstance().getApis().getAdasControllerApi().getAutopilotStatus());
// 模拟 不可自动驾驶目前场景是刚开机adas还未和工控机连接
// findViewById(R.id.btnAutopilotDisable).setOnClickListener(view ->
// {
// MogoApisHandler.getInstance().getApis()
// .getAdasControllerApi()
// .mockOchStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE, "不能使用");
//// Logger.d("lianglihui","模拟 不可自动驾驶");
// }
// );
// 模拟 可自动驾驶,工控机连接正常,且处于人工干预状态
// findViewById(R.id.btnAutopilotEnable).setOnClickListener(view ->
// {
// MogoApisHandler.getInstance().getApis()
// .getAdasControllerApi()
// .mockOchStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE, "能使用");
//
//// Logger.d("lianglihui","模拟 可自动驾驶");
// }
// );
// 模拟 自动驾驶能力,自动驾驶中,可能是停车,可能是行进,但是是机器在处理车的前进后退,不是人
// findViewById(R.id.btnAutopilotRunning).setOnClickListener(view ->
// {
// MogoApisHandler.getInstance().getApis()
// .getAdasControllerApi()
// .mockOchStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING, "Running");
//// Logger.d("lianglihui","模拟 自动驾驶能力");
// }
// );
// 模拟 自动驾驶站
// findViewById(R.id.btnAutopilotArrive).setOnClickListener(view ->
// {
// MogoApisHandler.getInstance().getApis()
// .getAdasControllerApi().mockOchStatus(-1, "Arrived");
//
//// Logger.d("lianglihui","模拟 自动驾驶站");
// }
// );
// 模拟 站点下发工控
findViewById(R.id.btnAutopilotControl).setOnClickListener(view ->
{
// Logger.d("lianglihui","模拟 站点下发工控");
AutopilotControlParameters currentAutopilot = new AutopilotControlParameters();
currentAutopilot.isSpeakVoice = true;
// 万集东门站
currentAutopilot.startLatLon = new AutopilotControlParameters.AutoPilotLonLat(40.194795425,116.724476409);
// 市政府前街18号
currentAutopilot.endLatLon = new AutopilotControlParameters.AutoPilotLonLat(40.1939540844,116.720067);
// 订单运营类型 9出租车10小巴
currentAutopilot.vehicleType = 10;
Logger.d(TAG, "模拟 订单站点下发:" + currentAutopilot);
CallerAutoPilotManager.INSTANCE.startAutoPilot(currentAutopilot);
}
);
tvOperationStatus.setOnClickListener(view -> {
onChangeOperationStatus();
});
mCloseNaviIcon.setOnClickListener(v -> {
showNaviToStartStationFragment(false);
});
if (FunctionBuildConfig.appIdentityMode == 1) {
flStationPanelContainer.setVisibility(View.GONE);
tvOperationStatus.setVisibility(View.GONE);
mSettingBtn.setVisibility(View.GONE);
}
}
protected void onChangeOperationStatus() {
}
protected void onGoToTaxiOrders(){
}
public void showNotice(String notice) {
getActivity().runOnUiThread(() -> {
AIAssist.getInstance(getContext()).speakTTSVoice(notice);
});
}
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
private int mPrevAPStatus = -1;
public void onAutopilotStatusChanged(int status) {
getActivity().runOnUiThread(() -> {
if (isStarting && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != status) {
// 1. 主动开启自动驾驶中不为2为0、1则继续loading
return;
}
if (isStarting && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status
&& mPrevAPStatus != status) {
// 2. 主动开启自动驾驶中为2则停止loading并isStarting = false
startAutopilotDone(true);
return;
}
// 3. 其他过程直接更新
startOrStopLoadingAnim(false);
AutopilotStatusAnimchanged(status);
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == mPrevAPStatus) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == status) {
// 2->1
// AIAssist.getInstance(getContext()).speakTTSVoice("已进入人工驾驶模式");
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE == status) {
// 2->0
// AIAssist.getInstance(getContext()).speakTTSVoice("自动驾驶已停止,请人工接管");
}
}
mPrevAPStatus = status;
});
}
private AnimationDrawable animationDrawable;
public void AutopilotStatusAnimchanged(int status) {
// mAutopilotTv.setText(isInAutopilot?"自动驾驶":"开启自动驾驶");
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status) {
ctvAutopilotStatus.setClickable(true);
mAutopilotTv.setText("自动驾驶");
mAutopilotTv.setTextColor(getResources().getColor(R.color.taxi_autopilot_text_color_normal));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot);
if (animationDrawable == null) {
ctvAutopilotStatus.setBackground(getResources().getDrawable(R.drawable.anmi_flow));
animationDrawable = (AnimationDrawable) ctvAutopilotStatus.getBackground();
}
if (animationDrawable.isRunning()) {
return;
}
animationDrawable.selectDrawable(0);
animationDrawable.start();
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == status){
ctvAutopilotStatus.setClickable(true);
mAutopilotTv.setText("自动驾驶");
mAutopilotTv.setTextColor(getResources().getColor(R.color.taxi_autopilot_text_color_normal));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot);
if (animationDrawable != null){
animationDrawable.selectDrawable(0);
animationDrawable.stop();
}
ctvAutopilotStatus.setBackground(getResources().getDrawable(R.drawable.taxi_autopilot_bg_selector));
animationDrawable = null;
} else {
ctvAutopilotStatus.setClickable(false);
mAutopilotTv.setText("自动驾驶");
mAutopilotTv.setTextColor(getResources().getColor(R.color.taxi_autopilot_text_color_disable));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot_disable);
if (animationDrawable != null){
animationDrawable.selectDrawable(0);
animationDrawable.stop();
}
ctvAutopilotStatus.setBackground(getResources().getDrawable(R.drawable.taxi_ic_autopilot_bg));
animationDrawable = null;
}
}
private void startAutopilotDone(boolean success) {
if (autopilotLoadingAnimator != null) {
autopilotLoadingAnimator.end();
mAutopilotImage.clearAnimation();
autopilotLoadingAnimator = null;
}
if (success) {
mAutopilotTv.setText("成功");
mAutopilotTv.setTextColor(getResources().getColor(R.color.taxi_autopilot_text_color_normal));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot_success);
} else {
mAutopilotTv.setText("失败");
mAutopilotTv.setTextColor(getResources().getColor(R.color.taxi_autopilot_text_color_normal));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot_failed);
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
startOrStopLoadingAnim(false);
onAutopilotStatusChanged(MogoApisHandler.getInstance().getApis().getAdasControllerApi().getAutopilotStatus());
}
}, 1000L);
}
private boolean isStarting = false;
private ObjectAnimator autopilotLoadingAnimator;
public void startOrStopLoadingAnim(boolean start) {
if (start) {
isStarting = true;
mAutopilotTv.setText("启动中");
mAutopilotTv.setTextColor(getResources().getColor(R.color.taxi_autopilot_text_color_normal));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot_loading);
if (autopilotLoadingAnimator == null) {
autopilotLoadingAnimator = ObjectAnimator.ofFloat(mAutopilotImage,
"rotation", 0f, 360f);
}
autopilotLoadingAnimator.setInterpolator(new LinearInterpolator());
autopilotLoadingAnimator.setRepeatCount(-1);//无限循环
autopilotLoadingAnimator.setStartDelay(100);
autopilotLoadingAnimator.setDuration(1000);//设置持续时间
autopilotLoadingAnimator.start();//动画开始
} else {
isStarting = false;
if (autopilotLoadingAnimator != null) {
autopilotLoadingAnimator.end();
mAutopilotImage.clearAnimation();
autopilotLoadingAnimator = null;
}
}
}
/**
* 隐藏【自动驾驶】按钮
*/
public void hideAutopilotBiz() {
getActivity().runOnUiThread(() -> {
// ctvAutopilotStatus.setVisibility(View.GONE);
// slidePanelView.setVisibility(View.GONE);
});
}
/**
* 展示【自动驾驶】按钮
*/
public void showAutopilotBiz() {
getActivity().runOnUiThread(() -> {
ctvAutopilotStatus.setVisibility(View.VISIBLE);
});
}
public void hidPanel() {
getActivity().runOnUiThread(() -> {
flStationPanelContainer.setVisibility(View.GONE);
});
}
public void showPanel() {
getActivity().runOnUiThread(() -> {
flStationPanelContainer.setVisibility(View.VISIBLE);
});
}
public View getPanelView() {
return panelView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
/**
* 获取站点面板view在{@link #initViews()}时候添加到container中
*
* @return 站点面板view
*/
public abstract int getStationPanelViewId();
/**
* 重新开启自动驾驶
*/
public abstract void restartAutopilot();
public void changeOperationViewVisible(int visible){
getActivity().runOnUiThread(() -> {
tvOperationStatus.setVisibility(visible);
});
}
public void updateSpeedView(float newSpeed){
int speed = (int) (newSpeed * 3.6F);
mSpeedView.setText(String.valueOf(speed));
}
@Override
public void onMapVisualAngleChanged(VisualAngleMode visualAngleMode) {
//todo ui 切换
}
// private void hideHMI() {
// // 控制 脉速表 显示状态
// CallerHmiManager.INSTANCE.setSpeedChartViewVisibility(View.GONE);
// // 控制 自动驾驶按钮 显示状态
// CallerHmiManager.INSTANCE.setAutopilotStatusViewVisibility(View.GONE);
// // 控制 切换视角按钮 显示状态
// CallerHmiManager.INSTANCE.setPerspectiveSwitchViewVisibility(View.GONE);
// // 控制 车辆检检测按钮 示状态
// CallerHmiManager.INSTANCE.setCheckStatusViewVisibility(View.GONE);
// }
protected void showNaviToStartStationFragment(boolean isShow){
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (isShow){
// if (ochNaviFragment == null){
ochNaviFragment = OCHNaviFragment.newInstance();
// }
if (ochNaviFragment.isAdded()){
return;
}
transaction.add(R.id.module_mogo_och_navi_panel_container,ochNaviFragment).show(ochNaviFragment);
transaction.commitAllowingStateLoss();
mCloseNaviIcon.setVisibility(View.VISIBLE);
flNaviPanelContainer.setVisibility(View.VISIBLE);
CallerSmpManager.hidePanel();//隐藏小地图
}else {
if (ochNaviFragment != null){
ochNaviFragment.onDestroy();
transaction.remove(ochNaviFragment);
transaction.commitAllowingStateLoss();
ochNaviFragment = null;
}
mCloseNaviIcon.setVisibility(View.GONE);
flNaviPanelContainer.setVisibility(View.GONE);
CallerSmpManager.showPanel();//显示小地图
}
}
}

View File

@@ -0,0 +1,50 @@
package com.mogo.och.taxi.passenger.ui;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/**
* @author: wangmingjun
* @date: 2021/9/9
*/
public abstract class BaseTaxiUIFragment extends Fragment {
private View mRootView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = inflater.inflate(getLayoutId(), container, false);
} else {
ViewGroup viewGroup = (ViewGroup) mRootView.getParent();
if (viewGroup != null) {
viewGroup.removeView(mRootView);
}
}
initViews(mRootView);
initViews(savedInstanceState);
return mRootView;
}
/**
* 布局资源
*
* @return
*/
protected abstract int getLayoutId();
protected abstract void initViews(View view);
protected void initViews(Bundle savedInstanceState) {
}
@Override
public void onDestroy() {
super.onDestroy();
mRootView = null;
}
}

View File

@@ -0,0 +1,360 @@
package com.mogo.och.taxi.passenger.ui;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.LinearLayout;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.callback.Shadow;
import com.mogo.och.taxi.passenger.utils.DimenUtil;
/**
* @author: wangmingjun
* @date: 2022/1/21
* 边框阴影
*/
public class BorderShadowLayout extends LinearLayout {
private static final String TAG = "ShadowLayout";
//默认阴影半径
public static final float SHADOW_DEFAULT_RADIUS = DimenUtil.INSTANCE.dp2px(5);
//阴影最大偏移量
public static final float SHADOW_MAX_OFFSET = DimenUtil.INSTANCE.dp2px(20);
//阴影最大模糊半径
public static final float SHADOW_MAX_BLUR = DimenUtil.INSTANCE.dp2px(20);
//默认模糊半径
public static final float SHADOW_DEFAULT_BLUR_RADIUS = DimenUtil.INSTANCE.dp2px(5);
//阴影颜色
private int shadowColor = Color.parseColor("#333333");
//阴影类型,0:默认为单边 1:单边 2:邻边 3:四边所有
private int shadowType;
//阴影半径
private float shadowRadius = 0f;
//模糊度半径
private float blurRadius = SHADOW_DEFAULT_BLUR_RADIUS ;
//水平位移
private float xOffset = DimenUtil.INSTANCE.dp2px(10);
//竖直方向位移
private float yOffset = DimenUtil.INSTANCE.dp2px(10);
//背景色
private int bgColor = Color.WHITE;
//是否有点击效果
private boolean hasEffect = false ;
int left =0 ,right =0,top = 0,bottom = 0 ;
//代理方式
private Shadow shadow = new BorderShadowLayout.ShadowConfig(this);
private float mWidthMode;
private float mHeightMode;
private Paint mPaint = new Paint();
private Paint locationPaint = new Paint();
public BorderShadowLayout(Context context) {
super(context,null);
}
public BorderShadowLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public BorderShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout);
shadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor, Color.BLUE);
blurRadius = typedArray.getDimension(R.styleable.ShadowLayout_blurRadius, SHADOW_DEFAULT_BLUR_RADIUS);
shadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius,0);
hasEffect = typedArray.getBoolean(R.styleable.ShadowLayout_hasEffect, false);
xOffset = typedArray.getDimension(R.styleable.ShadowLayout_xOffset,DimenUtil.INSTANCE.dp2px(10));
yOffset = typedArray.getDimension(R.styleable.ShadowLayout_yOffset,DimenUtil.INSTANCE.dp2px(10));
bgColor = typedArray.getColor(R.styleable.ShadowLayout_bgColor,Color.WHITE);
typedArray.recycle();
if (shadowRadius<0){
shadowRadius = -shadowRadius;
}
if (blurRadius < 0) {
blurRadius = -blurRadius;
}
blurRadius = Math.min(SHADOW_MAX_BLUR,blurRadius);
if (Math.abs(xOffset)> SHADOW_MAX_OFFSET){
xOffset = xOffset/Math.abs(xOffset) * SHADOW_MAX_OFFSET;
}
if (Math.abs(yOffset) > SHADOW_MAX_OFFSET){
yOffset = yOffset/Math.abs(yOffset) * SHADOW_MAX_OFFSET;
}
init();
}
private void init(){
setBackgroundColor(Color.parseColor("#00ffffff"));
if (xOffset>0){
//水平偏移量为正数右侧有阴影阴影长度为blurRadius+|xOffset|
right = (int)(blurRadius + Math.abs(xOffset));
}else if (xOffset==0){
//水平偏移为0,水平间距为blurRadius
left = (int)blurRadius;
right = (int)blurRadius;
}else {
//水平偏移为负数,左侧有阴影阴影长度为blurRadius+|xOffset|
left = (int)(blurRadius + Math.abs(xOffset));
}
if (yOffset>0){
//竖直偏移量为正数底部有阴影阴影长度为blurRadius+|yOffset|
bottom = (int)(blurRadius + Math.abs(yOffset));
}else if (yOffset==0){
//竖直偏移量为0竖直间距为blurRadius
top = (int)blurRadius;
bottom = (int)blurRadius;
}else {
//竖直偏移量为负数顶部有阴影阴影长度为blurRadius+|yOffset|
top = (int)(blurRadius + Math.abs(yOffset));
}
setPadding(left,top,right,bottom);
}
/**
* 获取阴影设置
* @return 返回阴影设置配置
*/
public Shadow getShadowConfig(){
return shadow;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed,l,t,r,b);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
drawBackground(canvas);//放在super前是后景相反是前景前景会覆盖子布局
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//绘制背景色(在子view底部)
private void drawBackground(Canvas canvas){
mWidthMode = getMeasuredWidth();
mHeightMode = getMeasuredHeight();
float startX = 0;
float startY = 0;
float endX = 0;
float endY = 0;
if (xOffset==0){
startX = right;
endX = mWidthMode-blurRadius;
}else {
startX = right+blurRadius;
endX = mWidthMode-left-blurRadius;
}
if (yOffset==0){
startY = bottom;
endY = mHeightMode-blurRadius;
}else {
startY = bottom+blurRadius;
endY = mHeightMode-top-blurRadius;
}
// mPaint.setShadowLayer(blurRadius,0,0,shadowColor);
if (blurRadius>0){
mPaint.setMaskFilter(new BlurMaskFilter(blurRadius,BlurMaskFilter.Blur.NORMAL));
}
mPaint.setColor(shadowColor);
mPaint.setAntiAlias(true);
RectF shadowRect = new RectF(startX,startY,endX,endY);
RectF locationRectF = new RectF(left,top,mWidthMode-right,mHeightMode-bottom);
if (shadowRadius==0){
//不是圆角
canvas.drawRect(shadowRect,mPaint);
}else {
//圆角角度为shadowRadius
canvas.drawRoundRect(shadowRect,shadowRadius,shadowRadius,mPaint);
}
locationPaint.setColor(bgColor);
locationPaint.setAntiAlias(true);
if (shadowRadius==0){
//不是圆角
canvas.drawRect(locationRectF,locationPaint);
}else {
//圆角角度为shadowRadius
canvas.drawRoundRect(locationRectF,shadowRadius,shadowRadius,locationPaint);
}
}
/**
* 阴影配置
*/
class ShadowConfig implements Shadow{
//代理
private BorderShadowLayout shadow;
private ShadowConfig(BorderShadowLayout shadow) {
this.shadow = shadow;
}
@Override
public Shadow setShadowRadius(float radius) {
return setShadowRadius(TypedValue.COMPLEX_UNIT_DIP,radius);
}
@Override
public Shadow setShadowRadius(int unit, float radius) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
shadow.shadowRadius = Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics()));
return this;
}
@Override
public Shadow setShadowColor(int color) {
shadow.shadowColor = color;
return this;
}
@Override
public Shadow setShadowColorRes(int colorRes) {
shadow.shadowColor = shadow.getResources().getColor(colorRes);
return this;
}
@Override
public Shadow setBlurRadius(float radius) {
return setBlurRadius(TypedValue.COMPLEX_UNIT_DIP,radius);
}
@Override
public Shadow setBlurRadius(int unit, float radius) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
shadow.blurRadius = Math.min(SHADOW_MAX_BLUR,Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics())));
return this;
}
@Override
public Shadow setXOffset(float offset) {
return setXOffset(TypedValue.COMPLEX_UNIT_DIP,offset);
}
@Override
public Shadow setXOffset(int unit, float offset) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
float x = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics());
if (Math.abs(x)> SHADOW_MAX_OFFSET){
x = x/Math.abs(x) * SHADOW_MAX_OFFSET;
}
shadow.xOffset = x;
return this;
}
@Override
public Shadow setYOffset(float offset) {
return setYOffset(TypedValue.COMPLEX_UNIT_DIP,offset);
}
@Override
public Shadow setYOffset(int unit, float offset) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
float y = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics());
if (Math.abs(y)> SHADOW_MAX_OFFSET){
y = y/Math.abs(y) * SHADOW_MAX_OFFSET;
}
shadow.yOffset = y;
return this;
}
@Override
public void commit() {
shadow.init();
shadow.requestLayout();
shadow.postInvalidate();
}
}
}

View File

@@ -0,0 +1,304 @@
package com.mogo.och.taxi.passenger.ui;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.CustomMapStyleOptions;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewListener;
import com.amap.api.navi.AMapNaviViewOptions;
import com.amap.api.navi.model.RouteOverlayOptions;
import com.mogo.eagle.core.function.smp.utils.MapAssetStyleUtils;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiNaviChangedCallback;
import com.mogo.och.taxi.passenger.model.NaviToDestinationModel;
/**
* @author: wangmingjun
* @date: 2021/11/30
*/
public class OCHNaviFragment extends BaseTaxiUIFragment implements AMapNaviViewListener, View.OnClickListener {
private AMapNaviView mAMapNaviView;
// private OverviewButtonView mOverviewButtonView;
// private NextTurnTipView mNextTurnTipView;
private AMap aMap;
private IOCHTaxiNaviChangedCallback mNaviToStartInfoCallback; // 前往乘客上车点
public static OCHNaviFragment newInstance() {
Bundle args = new Bundle();
OCHNaviFragment fragment = new OCHNaviFragment();
fragment.setArguments(args);
return fragment;
}
@Override
protected int getLayoutId() {
return R.layout.taxi_navi_view;
}
@Override
protected void initViews(View view) {
view.bringToFront();
initMapView(view);
}
private void initMapView(View view) {
// mOverviewButtonView = view.findViewById(R.id.navi_overviewbuttonview);
// mAMapNaviView.setLazyOverviewButtonView(mOverviewButtonView);
// mOverviewButtonView.setOnClickListener(this);
// DriveWayView mDriveWayView = view.findViewById(R.id.navi_drivewayview);
// mAMapNaviView.setLazyDriveWayView(mDriveWayView);
// mNextTurnTipView = view.findViewById(R.id.navi_nextturntipview);
// mAMapNaviView.setLazyNextTurnTipView(mNextTurnTipView);
mAMapNaviView = view.findViewById(R.id.navi_view);
mAMapNaviView.setAMapNaviViewListener(this);
//车头向上模式
mAMapNaviView.setNaviMode(AMapNaviView.CAR_UP_MODE);
aMap = mAMapNaviView.getMap();
//关闭地图文字显示
aMap.showMapText(false);
// 设置导航地图模式aMap是地图控制器对象。
aMap.setMapType(AMap.MAP_TYPE_NIGHT);
// 关闭显示实时路况图层aMap是地图控制器对象。
aMap.setTrafficEnabled(false);
setMapViewOptions();
new Thread(() -> {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (null == getContext()){
return;
}
aMap.setCustomMapStyle(
new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext()))
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext()))
);
//设置希望展示的地图缩放级别
}).start();
}
private void setMapViewOptions() {
AMapNaviViewOptions options = new AMapNaviViewOptions();
options.setTilt(0);//设置 2D 模式
options.setLayoutVisible(false);//设置导航界面UI是否显示。
options.setTrafficBarEnabled(false);//设置路况光柱条是否显示(只适用于驾车导航,需要联网)。
options.setAutoLockCar(true);//设置6秒后是否自动锁车
options.setAutoDisplayOverview(true);//设置是否自动全览模式,即在算路成功后自动进入全览模式
options.setTrafficLine(false);
options.setModeCrossDisplayShow(true);//设置是否显示路口放大图(路口模型图)
options.setAutoChangeZoom(true);//自动缩放级别
options.setCarBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.taxi_navi_arrow_icon));
options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.taxi_navi_direction_icon));
options.setAutoChangeZoom(true);//设置是否开启动态比例尺 (锁车态下自动进行地图缩放变化)
// options.setZoom(18);//14-18
// options.setTrafficInfoUpdateEnabled(false);
// options.setTrafficLayerEnabled(false);//设置[实时交通图层开关按钮]是否显示(只适用于驾车导航,需要联网)。
// options.setCameraInfoUpdateEnabled(false);
// options.setCompassEnabled(false);//设置指南针图标否在导航界面显示,默认显示。
// options.setLaneInfoShow(false);// 设置是否显示道路信息view
// options.setNaviArrowVisible(false);//设置路线转向箭头隐藏和显示
// options.setRealCrossDisplayShow(false);//设置是否显示路口放大图(实景图)
// options.setRouteListButtonShow(true);//设置导航界面是否显示路线全览按钮。
// options.setSettingMenuEnabled(false);//设置菜单按钮是否在导航界面显示。
RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions();
// routeOverlayOptions.setArrowOnTrafficRoute(BitmapFactory.decodeResource(getResources(),R.drawable.custtexture_aolr));
routeOverlayOptions.setNormalRoute(BitmapFactory.decodeResource(getResources(), R.drawable.taxi_navi_line_icon));
options.setRouteOverlayOptions(routeOverlayOptions);
mAMapNaviView.setViewOptions(options);
}
public void goToOverview(){
if (mAMapNaviView.isRouteOverviewNow()){
mAMapNaviView.recoverLockMode();
}else {
mAMapNaviView.displayOverview();
}
}
@Override
public void onClick(View v) {
// if (v.getId() == R.id.navi_overviewbuttonview){
// goToOverview();
// }
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mAMapNaviView.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
mAMapNaviView.onResume();
}
@Override
public void onPause() {
super.onPause();
mAMapNaviView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
NaviToDestinationModel.getInstance(getContext()).setVoiceIsMute(false);
mAMapNaviView.onDestroy();
if (mNaviToStartInfoCallback != null){
mNaviToStartInfoCallback = null;
}
}
@Override
public void onNaviSetting() {
//底部导航设置点击回调
}
@Override
public void onNaviCancel() {
}
@Override
public void onNaviMapMode(int naviMode) {
//导航态车头模式0:车头朝上状态1:正北朝上模式。
}
@Override
public void onNaviTurnClick() {
//转弯view的点击回调
}
@Override
public void onNextRoadClick() {
//下一个道路View点击回调
}
@Override
public void onScanViewButtonClick() {
//全览按钮点击回调
}
@Override
public void onLockMap(boolean isLock) {
//锁地图状态发生变化时回调
}
@Override
public void onNaviViewLoaded() {
Log.d("wlx", "导航页面加载成功");
Log.d("wlx", "请不要使用AMapNaviView.getMap().setOnMapLoadedListener();会overwrite导航SDK内部画线逻辑");
}
@Override
public void onMapTypeChanged(int i) {
}
@Override
public void onNaviViewShowMode(int i) {
}
@Override
public boolean onNaviBackClick() {
return false;
}
/**
* 车道信息说明:
* <p>
* 0xFF, 无对应车道
* 0, 直行
* 1, 左转
* 2, 直行+左转
* 3, 右转
* 4, 直行+右转
* 5, 左掉头
* 6, 左转+右转
* 7, 直行+左转+右转
* 8, 右掉头
* 9, 直行+左掉头
* 10, 直行+右掉头
* 11, 左转+左掉头
* 12, 右转+右掉头
* 13, 直行+扩展
* 14, 左转+左掉头+扩展
* 15, 保留
* 16, 直行+左转+左掉头
* 17, 右转+左掉头
* 18, 左转+右转+左掉头
* 19, 直行+右转+左掉头
* 20, 左转+右掉头
* 21, 公交车道
* 22, 空车道
* 23 可变车道
*/
String[] array = {
"直行车道"
, "左转车道"
, "左转或直行车道"
, "右转车道"
, "右转或直行车道"
, "左掉头车道"
, "左转或者右转车道"
, " 左转或右转或直行车道"
, "右转掉头车道"
, "直行或左转掉头车道"
, "直行或右转掉头车道"
, "左转或左掉头车道"
, "右转或右掉头车道"
, "直行并且车道扩展"
, "左转+左掉头+扩展"
, "不可以选择该车道"
, "直行+左转+左掉头车道"
, "右转+左掉头"
, "左转+右转+左掉头"
, "直行+右转+左掉头"
, "左转+右掉头"
, "公交车道"
, "空车道"
, "可变车道"
};
String[] actions = {
"直行"
, "左转"
, "左转或直行"
, "右转"
, "右转或这行"
, "左掉头"
, "左转或者右转"
, " 左转或右转或直行"
, "右转掉头"
, "直行或左转掉头"
, "直行或右转掉头"
, "左转或左掉头"
, "右转或右掉头"
, "直行并且车道扩展"
, "左转+左掉头+扩展"
, "不可以选择"
, "直行+左转+左掉头"
, "右转+左掉头"
, "左转+右转+左掉头"
, "直行+右转+左掉头"
, "左转+右掉头"
, "公交车道"
, "空车道"
, "可变车道"
};
}

View File

@@ -0,0 +1,498 @@
package com.mogo.och.taxi.passenger.ui;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.amap.api.navi.model.NaviLatLng;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.taxi.passenger.callback.IOCHTaxiNaviChangedCallback;
import com.mogo.och.taxi.passenger.constant.OrderStatusEnum;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import com.mogo.och.taxi.passenger.model.MogoOCHTaxiModelNew;
import com.mogo.och.taxi.passenger.model.NaviToDestinationModel;
import com.mogo.och.taxi.passenger.utils.OchTaxiUtils;
import java.text.DecimalFormat;
import java.util.Calendar;
/**
* @author congtaowang
* @since 2021/1/18
* 正在进行中订单
*/
public class OCHTaxiBeingServerdOrdersFragment extends BaseTaxiUIFragment implements View.OnClickListener, IOCHTaxiNaviChangedCallback {
public static final String TAG = "OCHTaxiBeingServerd";
private static Activity mActivity;
private static OCHTaxiFragment mTaxiFragment;
private long mOrderId;
private double mOrderStartStationLat = 0;
private double mOrderStartStationLng = 0;
public static OCHTaxiBeingServerdOrdersFragment newInstance(Activity activity, OCHTaxiFragment taxiFragment) {
mActivity = activity;
mTaxiFragment = taxiFragment;
Bundle args = new Bundle();
OCHTaxiBeingServerdOrdersFragment fragment = new OCHTaxiBeingServerdOrdersFragment();
fragment.setArguments(args);
return fragment;
}
private TextView mOrderStatus;
private ImageView mOrderCancel;
private TextView mOrderServerStatus;
private ConstraintLayout mBeingOrderLayout;
private ConstraintLayout mContentModule3;
private ConstraintLayout mContentModule2;
private TextView mDistanceAndTime3;
private TextView mDistanceAndTime2;
private TextView mStationTv2;
private TextView mOrderOtherContent3;
private TextView mArrivedStartTimeTv32;
private TextView mTitleTV2;
private LinearLayout mContentModule31;
private TextView mStationTv31;
private LinearLayout mContentModule32;
private TextView mStationTv32;
private TextView mArrivedStationTitleTv32;
private TextView mGoAheadStationTitleTv31;
private TextView mCatchStationTitleTv31;
private ImageView mNaviIcon;
private TextView mNoDatasTv;
private ConstraintLayout mNoDataView;
private volatile int saveOrderState = -1;
@Override
protected int getLayoutId() {
return R.layout.taxi_being_order;
}
@Override
protected void initViews(View view) {
mOrderStatus = view.findViewById(R.id.module_och_taxi_order_status);
mOrderCancel = view.findViewById(R.id.module_och_taxi_order_cancel_iv);
mOrderServerStatus = view.findViewById(R.id.module_och_taxi_order_server_status_tv);
mBeingOrderLayout = view.findViewById(R.id.module_och_taxi_being_order_content);
mContentModule2 = view.findViewById(R.id.module_och_taxi_order_status_station_2);
mContentModule3 = view.findViewById(R.id.module_och_taxi_order_status_station_3);
mDistanceAndTime2 = view.findViewById(R.id.module_och_taxi_order_distance_anchor_2);
mContentModule31 = view.findViewById(R.id.module_och_taxi_order_go_ahead_station_31);
mContentModule32 = view.findViewById(R.id.module_och_taxi_order_arrive_station_32);
mStationTv2 = view.findViewById(R.id.module_och_taxi_order_station_2);
mStationTv31 = view.findViewById(R.id.module_och_taxi_order_start_station_31);
mStationTv32 = view.findViewById(R.id.module_och_taxi_order_end_station_32);
mOrderOtherContent3 = view.findViewById(R.id.module_och_taxi_order_other_content_3);
mDistanceAndTime3 = view.findViewById(R.id.module_och_taxi_order_distance_anchor_3);
mArrivedStartTimeTv32 = view.findViewById(R.id.module_och_taxi_order_had_arrived_time_32);
mTitleTV2 = view.findViewById(R.id.module_och_taxi_order_station_title_2);
mCatchStationTitleTv31 = view.findViewById(R.id.go_ahead_station_catch_31);
mGoAheadStationTitleTv31 = view.findViewById(R.id.go_ahead_station_31);
mArrivedStationTitleTv32 = view.findViewById(R.id.arrive_station_32);
mNoDatasTv = view.findViewById(R.id.no_order_data_tv);
mNoDataView = view.findViewById(R.id.being_no_data_view);
mOrderCancel.setOnClickListener(this);
mOrderServerStatus.setOnClickListener(this);
initNaviView(view);
isHaveBeingOrder(false);
if (DebugConfig.isDebug()) {
initOrderTestBar(view);
}
}
@Override
public void onResume() {
super.onResume();
MogoOCHTaxiModelNew.getInstance().startOrStopOrderLoop();
}
private void initNaviView(View view) {
mNaviIcon = view.findViewById(R.id.module_och_taxi_navi_iv);
mNaviIcon.setOnClickListener(this);
}
private boolean isSpeakedEndingNotice = false;
/**
* 初始化订单信息
*/
@RequiresApi(api = Build.VERSION_CODES.P)
public void updateCurrentOrderStatusChanged(OrderQueryRespBean.Result order) {
if (order == null) return;
if (order.orderStatus == OrderStatusEnum.JourneyCompleted.getCode()) {
isHaveBeingOrder(false);
return;
}
mOrderId = order.orderId;
onOrderStatusChanged(order.orderStatus);
if (OrderStatusEnum.ArriveAtEndStation.getCode() == order.orderStatus) {
mTaxiFragment.queryCurOrderRouteInfo();
mContentModule3.setVisibility(View.GONE);
mContentModule2.setVisibility(View.VISIBLE);
Logger.d(TAG, "已经达到终点");
mOrderStatus.setText(R.string.module_och_taxi_arrive_at_end_station2);
mOrderServerStatus.setText(R.string.module_och_taxi_order_server_end);
mOrderServerStatus.setTextColor(Color.parseColor("#FFFFFF"));
GradientDrawable background = (GradientDrawable) mOrderServerStatus.getBackground();//GradientDrawable是Drawable的子类
background.setColor(Color.parseColor("#FF1D5EF3"));
mOrderServerStatus.setClickable(true);
// String strHtml3 = "<font color=\"#CAD6FF\">送乘客至</font><br>"
// + "<b><font color=\"#FFFFFF\"><big>" + order.endSiteAddr + "<big></font></b>";
mTitleTV2.setText("送乘客至");
mStationTv2.setText(order.endSiteAddr);
// String strHtml2 = "<font color=\"#CAD6FF\">距离 </font>" + "<b><font color=\"#FFFFFF\">- -</font></b>" + "<font color=\"#CAD6FF\"> 公里,</font>"
// + "<font color=\"#CAD6FF\">用时 </font>" + "<b><font color=\"#FFFFFF\">- -</font></b>" + "<font color=\"#CAD6FF\"> 分钟</font>";
// mDistanceAndTime.setText(Html.fromHtml(strHtml2));
} else if (OrderStatusEnum.OnTheWayToEndStation.getCode() == order.orderStatus) {
Logger.d(TAG, "已经去往终点");
mContentModule3.setVisibility(View.GONE);
mContentModule2.setVisibility(View.VISIBLE);
mOrderStatus.setText(R.string.module_och_taxi_on_the_way_2_end_station);
mOrderServerStatus.setText(R.string.module_och_taxi_order_server_end);
mOrderServerStatus.setTextColor(Color.parseColor("#4DFFFFFF"));
GradientDrawable background = (GradientDrawable) mOrderServerStatus.getBackground();//GradientDrawable是Drawable的子类
background.setColor(Color.parseColor("#4D1D5EF3"));
mOrderServerStatus.setClickable(false);
// String strHtml3 = "<font color=\"#CAD6FF\">送乘客至</font><br>"
// + "<b><font color=\"#FFFFFF\"><big>" + order.endSiteAddr + "<big></font></b>";
mTitleTV2.setText("送乘客至");
// mStationTv2.setText(order.endSiteAddr);
mStationTv2.setText(order.endSiteAddr);
// String strHtml4 = "<font color=\"#CAD6FF\">距离 </font>" + "<b><font color=\"#FFFFFF\">- -</font></b>" + "<font color=\"#CAD6FF\"> 公里,</font>"
// + "<font color=\"#CAD6FF\">用时 </font>" + "<b><font color=\"#FFFFFF\">- -</font></b>" + "<font color=\"#CAD6FF\"> 分钟</font>";
// mDistanceAndTime.setText(Html.fromHtml(strHtml4));
} else if (OrderStatusEnum.ArriveAtStartStation.getCode() == order.orderStatus) {
Logger.d(TAG, "已经达到起点");
mContentModule2.setVisibility(View.GONE);
mContentModule3.setVisibility(View.VISIBLE);
mArrivedStartTimeTv32.setVisibility(View.VISIBLE);
mContentModule32.setVisibility(View.VISIBLE);
mContentModule31.setVisibility(View.GONE);
mOrderOtherContent3.setVisibility(View.GONE);
mOrderStatus.setText(R.string.module_och_taxi_waiting);
mOrderServerStatus.setText(R.string.module_och_taxi_order_server_start);
GradientDrawable background = (GradientDrawable) mOrderServerStatus.getBackground();//GradientDrawable是Drawable的子类
background.setColor(Color.parseColor("#FF1D5EF3"));
mOrderServerStatus.setTextColor(Color.parseColor("#FFFFFF"));
mOrderServerStatus.setClickable(true);
Calendar currentCale = DateTimeUtils.getCurrentDateTime();
String currentHM = OchTaxiUtils.formatCalendarToString(currentCale, OchTaxiUtils.TAXI_HH_mm);
String currentDay = OchTaxiUtils.formatCalendarToString(currentCale, OchTaxiUtils.TAXI_yyyy_MM_dd);
String strHtml11 = "<font color=\"#CAD6FF\">已于</font><br>"
+ "<b><font color=\"#FFFFFF\"><big><big>" + currentHM + "</big></big></font></b>"
+ "<font color=\"#CAD6FF\">" + " " + "到达乘客上车地点</font>";
mArrivedStartTimeTv32.setLineHeight(60);
mArrivedStartTimeTv32.setText(Html.fromHtml(strHtml11));
// String strHtml12 = "<font color=\"#CAD6FF\">送乘客至</font><br>"
// + "<b><font color=\"#FFFFFF\"><big>" + order.endSiteAddr + "</big</font></b>";
mArrivedStationTitleTv32.setText("送乘客至");
mStationTv32.setText(order.endSiteAddr);
currentCale.add(Calendar.MINUTE, 10);
String strHtml13 = "";
if (currentDay.equals(OchTaxiUtils.formatCalendarToString(currentCale, OchTaxiUtils.TAXI_yyyy_MM_dd))) {
strHtml13 = "<font color=\"#CAD6FF\">免费等待至 </font>"
+ "<b><font color=\"#FFFFFF\"><big>" + OchTaxiUtils.formatCalendarToString(currentCale, OchTaxiUtils.TAXI_HH_mm) + "</big></b></font>";
} else {
strHtml13 = "<font color=\"#CAD6FF\">免费等待至</font>"
+ "<font color=\"#FFFFFF\"><big>" + OchTaxiUtils.formatCalendarToString(currentCale, OchTaxiUtils.TAXI_MM_dd_HH_mm) + "</big></font>";
}
mDistanceAndTime3.setText(Html.fromHtml(strHtml13));
} else if (MogoOCHTaxiModelNew.getInstance().checkCurrentOCHOrder()) {
Logger.d(TAG, "前往乘客上车地点");
mContentModule2.setVisibility(View.GONE);
mContentModule3.setVisibility(View.VISIBLE);
mContentModule31.setVisibility(View.VISIBLE);
mArrivedStartTimeTv32.setVisibility(View.GONE);
mContentModule32.setVisibility(View.GONE);
mOrderOtherContent3.setVisibility(View.VISIBLE);
mDistanceAndTime3.setVisibility(View.VISIBLE);
mOrderStatus.setText(R.string.module_och_taxi_new_order);
mOrderServerStatus.setText(R.string.module_och_taxi_order_server_start);
mOrderServerStatus.setTextColor(Color.parseColor("#4DFFFFFF"));
GradientDrawable background = (GradientDrawable) mOrderServerStatus.getBackground();//GradientDrawable是Drawable的子类
background.setColor(Color.parseColor("#4D1D5EF3"));
mOrderServerStatus.setClickable(false);
mGoAheadStationTitleTv31.setText("前往");
mCatchStationTitleTv31.setText("接乘客");
// String strHtml0 = "<font color=\"#CAD6FF\">前往</font><br>"
// + "<b><font color=\"#FFFFFF\"><big>" + order.startSiteAddr + "</big></font></b><br>"
// + "<font color=\"#CAD6FF\">接乘客</font>";
mStationTv31.setText(order.startSiteAddr);
Calendar currentCale = DateTimeUtils.getCurrentDateTime();
Calendar startCale = OchTaxiUtils.formatLongToCalendar(order.bookingTime);
String currentDay = OchTaxiUtils.formatCalendarToString(currentCale, OchTaxiUtils.TAXI_yyyy_MM_dd);
String startDay = OchTaxiUtils.formatCalendarToString(startCale, OchTaxiUtils.TAXI_yyyy_MM_dd);
String strHtml1 = "";
if (currentDay.equals(startDay)) {
strHtml1 = "<font color=\"#CAD6FF\">乘客将于</font><br>"
+ "<b><font color=\"#FFFFFF\"><big><big>" + OchTaxiUtils.formatCalendarToString(startCale, OchTaxiUtils.TAXI_HH_mm) + "</big></big></font></b>"
+ "<font color=\"#CAD6FF\"> 用车</font>";
} else {
strHtml1 = "<font color=\"#CAD6FF\">乘客将于</font><br>"
+ "<b><font color=\"#FFFFFF\"><big><big>" + OchTaxiUtils.formatCalendarToString(startCale, OchTaxiUtils.TAXI_MM_dd_HH_mm) + "</big></big></font></b>"
+ "<font color=\"#CAD6FF\"> 用车</font>";
}
mOrderOtherContent3.setText(Html.fromHtml(strHtml1));
// String strHtml2 = "<font color=\"#CAD6FF\">距离 </font>" + "<b><font color=\"#FFFFFF\">- -</font></b>" + "<font color=\"#CAD6FF\"> 公里,</font>"
// + "<font color=\"#CAD6FF\">用时 </font>" + "<b><font color=\"#FFFFFF\">- -</font></b>" + "<font color=\"#CAD6FF\"> 分钟</font>";
// mDistanceAndTime.setText(Html.fromHtml(strHtml2));
mOrderStartStationLat = order.startSiteGcjPoint.get(1);
mOrderStartStationLng = order.startSiteGcjPoint.get(0);
}
}
private void startNaviToStartStation(boolean isShow, double orderStartStationLat, double orderStartStationLng) {
NaviToDestinationModel.getInstance(getContext()).destroyAmaNavi();
Log.d(TAG, "currentLatLng=" + mTaxiFragment.mCurLatitude + " " + mTaxiFragment.mCurLongitude);
NaviLatLng startNaviLatLng = new NaviLatLng(mTaxiFragment.mCurLatitude, mTaxiFragment.mCurLongitude);
NaviLatLng endNaviLatLng = new NaviLatLng(orderStartStationLat, orderStartStationLng);
NaviToDestinationModel.getInstance(getContext()).initAMapNavi(startNaviLatLng, endNaviLatLng);
NaviToDestinationModel.getInstance(getContext()).setVoiceIsMute(isShow);
NaviToDestinationModel.getInstance(getContext()).setOCHTaciNaviChangedCallback(this);
}
private void showOrHideNavi(boolean isShow) {
if (!isShow) {
mNaviIcon.setVisibility(View.GONE);
NaviToDestinationModel.getInstance(getContext()).destroyAmaNavi();
mTaxiFragment.showNaviToStartStationFragment(false);
}
}
public void updateDistanceAndTime(long meters, long timeInSecond) {
// Log.d(TAG,"meters = "+meters);
if (mContentModule3 != null && mContentModule3.getVisibility() == View.VISIBLE) {
DecimalFormat fnum = new DecimalFormat("##0.0");
String dis = fnum.format((float) meters / 1000);
String strHtml2 = "<font color=\"#CAD6FF\">里程 </font>" + "<b><font color=\"#FFFFFF\">" + dis + "</font></b>" + "<font color=\"#CAD6FF\"> 公里</font>"
+ "<font color=\"#CAD6FF\">,剩余 </font>" + "<b><font color=\"#FFFFFF\">" + (int) timeInSecond / 60 + "</font></b>" + "<font color=\"#CAD6FF\"> 分钟</font>";
mDistanceAndTime3.setText(Html.fromHtml(strHtml2));
mNaviIcon.setVisibility(View.VISIBLE);
} else if (mContentModule2 != null && mContentModule2.getVisibility() == View.VISIBLE) {
DecimalFormat fnum = new DecimalFormat("##0.0");
String dis = fnum.format((float) meters / 1000);
String strHtml2 = "<font color=\"#CAD6FF\">距离 </font>" + "<b><font color=\"#FFFFFF\">" + dis + "</font></b>" + "<font color=\"#CAD6FF\"> 公里</font>";
// + "<font color=\"#CAD6FF\">,用时 </font>" + "<b><font color=\"#FFFFFF\">"+(int)timeInSecond/60+"</font></b>" + "<font color=\"#CAD6FF\"> 分钟</font>";
mDistanceAndTime2.setText(Html.fromHtml(strHtml2));
}
}
public void onCurrentOrderRouteInfoGot(OrderQueryRouteInfoRespBean.Result routeInfo) {
Log.d(TAG, "meters = " + routeInfo.durationToEnd);
DecimalFormat fnum = new DecimalFormat("##0.0");
String dis = fnum.format((float) routeInfo.distanceToEnd / 1000);
String strHtml2 = "<font color=\"#CAD6FF\">距离 </font>" + "<b><font color=\"#FFFFFF\">" + dis + "</font></b>" + "<font color=\"#CAD6FF\"> 公里</font>"
+ "<font color=\"#CAD6FF\">,用时 </font>" + "<b><font color=\"#FFFFFF\">" + (int) routeInfo.durationToEnd / 60 + "</font></b>" + "<font color=\"#CAD6FF\"> 分钟</font>";
if (mContentModule2 != null && mContentModule2.getVisibility() == View.VISIBLE) {
mDistanceAndTime2.setText(Html.fromHtml(strHtml2));
} else if (mContentModule3 != null && mContentModule3.getVisibility() == View.VISIBLE) {
mDistanceAndTime3.setText(Html.fromHtml(strHtml2));
}
}
public synchronized void SpeakNoticeOnce() {
if (!isSpeakedEndingNotice) {
isSpeakedEndingNotice = true;
showNotice(mActivity.getString(R.string.module_och_taxi_order_complete_1));
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
NaviToDestinationModel.getInstance(getContext()).destroyAmaNavi();
}
private void startOrEndService(String step) {
if (step.equals("服务完成")) {//点击了完成服务,结束订单并更新订单信息
// isHaveBeingOrder(false);
mTaxiFragment.completeOrderService(OrderStatusEnum.JourneyCompleted);
showNotice("车辆已停稳,请携带好随身物品,下车请注意安全");
return;
} else if (step.equals("开始服务")) {//点击服务,开启自动驾驶
mTaxiFragment.startAutoPilot();
showNotice("自动驾驶已启动,请系好安全带");
}
}
public void onOrderStatusChanged(int status) {
Log.d(TAG, "status==" + status);
mActivity.runOnUiThread(() -> {
if (status == OrderStatusEnum.None.getCode() || status == OrderStatusEnum.Cancel.getCode() || status == OrderStatusEnum.JourneyCompleted.getCode()) {
isSpeakedEndingNotice = false;
isHaveBeingOrder(false);
} else {
isHaveBeingOrder(true);
}
if (status != saveOrderState) {
OrderStatusEnum ochStatus = OrderStatusEnum.valueOf(status);
switch (ochStatus) {
case OnTheWayToStartStation:
showNotice(mActivity.getString(R.string.module_och_taxi_new_order));
startNaviToStartStation(false, mOrderStartStationLat, mOrderStartStationLng);
showOrHideNavi(true);
break;
case Cancel:
showNotice(mActivity.getString(R.string.module_och_taxi_order_cancel));
showOrHideNavi(false);
break;
case ArriveAtStartStation:
showNotice(mActivity.getString(R.string.module_och_taxi_order_status_ph_text));
showOrHideNavi(false);
break;
case OnTheWayToEndStation:
// showNotice("欢迎使用蘑菇智行");
showOrHideNavi(false);
break;
case ArriveAtEndStation:
showNotice(mActivity.getString(R.string.module_och_taxi_order_complete_1));
showOrHideNavi(false);
break;
case JourneyCompleted:
showNotice("感谢您使用蘑菇智行,再见~");
showOrHideNavi(false);
break;
}
}
saveOrderState = status;
});
}
/**
* 是否有正在进行的订单进行UI显示
*
* @param being
*/
public void isHaveBeingOrder(boolean being) {
Log.d(TAG, "isHaveBeingOrder = " + being);
if (being) {
mNoDataView.setVisibility(View.GONE);
mBeingOrderLayout.setVisibility(View.VISIBLE);
mTaxiFragment.changeOperationViewVisible(View.GONE);
} else {
mNoDataView.setVisibility(View.VISIBLE);
mNoDatasTv.setText("暂无进行中订单");
mBeingOrderLayout.setVisibility(View.GONE);
mTaxiFragment.changeOperationViewVisible(View.VISIBLE);
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.module_och_taxi_order_server_status_tv) {
switch (mOrderServerStatus.getText().toString().trim()) {
case "开始服务":
case "服务完成":
Log.d(TAG, mOrderServerStatus.getText().toString());
startOrEndService(mOrderServerStatus.getText().toString().trim());
break;
}
} else if (v.getId() == R.id.module_och_taxi_order_cancel_iv) {
new OCHTaxiOrderCancelDialog(mTaxiFragment, mActivity, mOrderId, saveOrderState).show();
} else if (v.getId() == R.id.module_och_taxi_navi_iv) {
// TODO: 2021/11/30 打开去往乘客上车点的导航页面
if (mTaxiFragment != null) {
showNaviToStartStationFragment(true);
}
}
}
/**
* 显示/隐藏 前往乘客上车点的导航
*
* @param isShow
*/
private void showNaviToStartStationFragment(boolean isShow) {
mTaxiFragment.showNaviToStartStationFragment(isShow);
startNaviToStartStation(isShow, mOrderStartStationLat, mOrderStartStationLng);
}
public void onCurrentOrderCancelDone() {
//提交取消订单后的回调
TipToast.tip("订单取消成功");
//更新界面
isHaveBeingOrder(false);
showOrHideNavi(false);
}
/**
* 订单流转debug START
*/
private void initOrderTestBar(View view) {
mOrderStatus.setOnLongClickListener(v -> {
mTaxiFragment.clickTestBar();
return false;
});
}
public void showNotice(String notice) {
mActivity.runOnUiThread(() -> {
AIAssist.getInstance(getContext()).speakTTSVoice(notice);
});
}
@Override
public void onCurrentNaviDistAndTimeChanged(int meters, int timeInSecond) {
updateDistanceAndTime(meters, timeInSecond);
}
@Override
public void reInitNaviAmap(boolean isPlay, boolean isRestart) {
Log.d(TAG, "isPlay = " + isPlay + ", isRestart=" + isRestart);
if (!isRestart) {
mTaxiFragment.showNaviToStartStationFragment(false);
return;
}
mTaxiFragment.showNaviToStartStationFragment(false);
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (saveOrderState == OrderStatusEnum.OnTheWayToStartStation.getCode()) {
startNaviToStartStation(false, mOrderStartStationLat, mOrderStartStationLng);
}
}
}, 2000);
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (saveOrderState == OrderStatusEnum.OnTheWayToStartStation.getCode()) {
if (mNaviIcon.getVisibility() == View.GONE) {
mNaviIcon.setVisibility(View.VISIBLE);
}
}
}
}, 3000);
}
/**
* END
*/
}

View File

@@ -0,0 +1,338 @@
package com.mogo.och.taxi.passenger.ui;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentTransaction;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.autopilot.AutopilotRouteInfo;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.constant.OrderStatusEnum;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import com.mogo.och.taxi.passenger.model.MogoOCHTaxiModelNew;
import com.mogo.och.taxi.passenger.presenter.OCHTaxiPresenter;
import com.mogo.och.taxi.passenger.utils.PinYinUtil;
import java.lang.ref.WeakReference;
import java.util.List;
/**
* @author congtaowang
* @since 2021/1/18
*
* 网约车-出租车UI
*/
public class OCHTaxiFragment extends BaseOchTaxiTabFragment<OCHTaxiFragment, OCHTaxiPresenter> implements OCHTaxiView{
public static final String TAG = "OCHTaxiFragment";
public static OCHTaxiFragment newInstance() {
Bundle args = new Bundle();
OCHTaxiFragment fragment = new OCHTaxiFragment();
fragment.setArguments( args );
return fragment;
}
private OCHTaxiGrabOrderFragment grabOrderFragment;
private OCHTaxiServerOrdersFragment serverOrdersFragment;
private WeakReference<OCHTaxiPersonalDialogFragment> personalDialogFragment = null;
protected double mCurLatitude = 0.0;
protected double mCurLongitude = 0.0;
@Override
public int getStationPanelViewId() {
return R.layout.taxi_panel;
}
@Override
public void restartAutopilot() {
// 在自动驾驶中,才会有重新开启自动驾驶的操作
if (mPresenter.getCurOrderStatus() == OrderStatusEnum.OnTheWayToEndStation) {
Logger.d( TAG, "restartAutopilot" );
mPresenter.startAutoPilot();
startOrStopLoadingAnim(true);
}
}
@Override
public String getTagName() {
return "OCHTaxiFragment";
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void initViews() {
super.initViews();
mPersonalBtn.setVisibility(View.GONE);
initFragment();
hidPanel();
if ( MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.isVrMode() ) {
switchVRFlatMode(true);
} else {
switchVRFlatMode(false);
}
if (FunctionBuildConfig.appIdentityMode == 0) {
tvOperationStatus.setVisibility(View.VISIBLE);
} else {
tvOperationStatus.setVisibility(View.GONE);
}
if (DebugConfig.isDebug()) {
initOrderTestBar();
}
}
private void initFragment() {
serverOrdersFragment = OCHTaxiServerOrdersFragment.newInstance();
grabOrderFragment = OCHTaxiGrabOrderFragment.newInstance();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
//默认显示OCHTaxiServerOrdersFragment
transaction.add(R.id.fragment_container,serverOrdersFragment).show(serverOrdersFragment);
transaction.add(R.id.fragment_container,grabOrderFragment).hide(grabOrderFragment);
transaction.commitAllowingStateLoss();
}
private void showGrabFragmentAndUpdate() {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (grabOrderFragment == null){
grabOrderFragment = OCHTaxiGrabOrderFragment.newInstance();
transaction.add(R.id.fragment_container,grabOrderFragment).show(grabOrderFragment).commitAllowingStateLoss();
}else {
transaction.show(grabOrderFragment).hide(serverOrdersFragment).commitAllowingStateLoss();
}
}
public void showServerFragmentAndUpdate() {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (serverOrdersFragment == null){
serverOrdersFragment = OCHTaxiServerOrdersFragment.newInstance();
transaction.add(R.id.fragment_container,serverOrdersFragment).show(serverOrdersFragment);
}else {
transaction.show(serverOrdersFragment).hide(grabOrderFragment).commitAllowingStateLoss();
}
}
@NonNull
@Override
protected OCHTaxiPresenter createPresenter() {
return new OCHTaxiPresenter( this );
}
@Override
protected void onChangeOperationStatus() {
super.onChangeOperationStatus();
mPresenter.updateCarStatus();
}
public void switchVRFlatMode(boolean isVRMode) {
if (mRootView != null) {
mRootView.setVisibility(isVRMode ? View.VISIBLE : View.GONE);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
public void updateOperationStatus(boolean inOperation) {
Logger.e(TAG,"onOperationChanged:"+ inOperation);
isOperationStatus = inOperation;
if ( inOperation ) {
tvOperationStatus.setText( "收车" );
mPersonalBtn.setVisibility(View.VISIBLE);
tvOperationStatus.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.taxi_back_btn),null,null,null);
showPanel();
} else {
// AIAssist.getInstance(getContext()).speakTTSVoice("已收车");
tvOperationStatus.setText("出车");
tvOperationStatus.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.taxi_out_btn),null,null,null);
mPersonalBtn.setVisibility(View.GONE);
hidPanel();
}
}
@Override
protected void onGoToTaxiOrders() {
personalDialogFragment = new WeakReference<>(new OCHTaxiPersonalDialogFragment(this));
personalDialogFragment.get().show(getActivity().getSupportFragmentManager(),"service_data");
}
public void routeResult(List<AutopilotRouteInfo.RouteModels> routeList) {
if (routeList == null ) return;
// double distance = calculateTravelDistance(mogoLocation,routeList);
// if ( MogoOCHTaxiModel.getInstance().checkCurrentOCHOrder() ) {
// MogoOCHTaxiModel.getInstance().getCurrentOCHOrder().decreaseTravelDistance( distance );
// updateOrderBaseStatusInfo();
// }
// Logger.d("lianglihui","routeResult 剩余导航距离:"+distance);
// if (routeList != null && routeList.size() >0){
// Logger.d("lianglihui","routeResult:"+routeList.size());
// //adas回调导航路径 绘制引导线
// if ( ochTaxiOverlayManager == null){
// ochTaxiOverlayManager = new OCHTaxiOverlayManager(this.getContext());
// }
// ochTaxiOverlayManager.draw(mogoLocation,routeList);
// }
}
@Override
public void onMapLoaded() {
}
public void updateAutopilotStatus(int status) {
onAutopilotStatusChanged(status);
}
/**
* 收到自动驾驶通知的成功状态之后,设置本地状态及服务端状态
*/
private void resetOCHTaxiOrderAutopilotStatus() {
mPresenter.updateCurOrderStatus(OrderStatusEnum.OnTheWayToEndStation);
}
@RequiresApi(api = Build.VERSION_CODES.P)
public void updateCurrentOrderStatusChanged(OrderQueryRespBean.Result order){
if (serverOrdersFragment != null){
serverOrdersFragment.updateCurrentOrderStatusChanged(order);
}
}
public void startAutoPilot(){
mPresenter.startAutoPilot();
startOrStopLoadingAnim(true);
}
public void completeOrderService(OrderStatusEnum status){
mPresenter.updateCurOrderStatus(status);
}
public void cancelCurOrder(int reasonType, String reaso){
mPresenter.cancelCurOrder(reasonType,reaso);
}
public void cancelOrderById(long orderId, int reasonType, String reason){
mPresenter.cancelOrderById(orderId,reasonType,reason);
}
public void onCurrentOrderCancelDone(){
if (null == serverOrdersFragment) return;
serverOrdersFragment.onCurrentOrderCancelDone();
}
public void onOrderCancelDone(long orderId){
if (null == serverOrdersFragment) return;
serverOrdersFragment.onOrderCancelDone(orderId);
}
public void onNewBookingOrderGot(OrderQueryRespBean.Result order){
if (null == order) return;
showGrabFragmentAndUpdate();
grabOrderFragment.updateGrabOrder(order);
}
public void grabOrder(){
mPresenter.grabOrder();
}
public void cancelNewBookingOrder(){
mPresenter.cancelNewBookingOrder();
showServerFragmentAndUpdate();
}
public void onGrabOrderExecuteDone(){
if (null == grabOrderFragment) return;
grabOrderFragment.onGrabOrderExecuteDone();
}
public void onGrabOrderSuccess(OrderQueryRespBean.Result order){
if (null == grabOrderFragment) return;
if (null == order){
showServerFragmentAndUpdate();
return;
}
showGrabFragmentAndUpdate();
grabOrderFragment.onGrabOrderSuccess();
}
public void onGrabOrderFailed(OrderQueryRespBean.Result order){
if (order == null){
showServerFragmentAndUpdate();
return;
}
if (null == grabOrderFragment) return;
showGrabFragmentAndUpdate();
grabOrderFragment.onGrabOrderFailed();
}
public void onOrdersWaitServiceChanged(List<OrderQueryRespBean.Result> waitServiceList){
if (null == waitServiceList) return;
if (null == serverOrdersFragment) return;
serverOrdersFragment.onOrdersWaitServiceChanged(waitServiceList);
}
public void queryOrdersList(int page, int size){
mPresenter.queryOrdersList(page,size);
}
public void onOrdersListPageRefresh(List<OrderQueryRespBean.Result> ordersList){
if (null == personalDialogFragment) personalDialogFragment = new WeakReference<>(new OCHTaxiPersonalDialogFragment(this));
personalDialogFragment.get().onOrdersListPageRefresh(ordersList);
}
public void queryDriverServiceData(){
mPresenter.queryDriverServiceData();
}
public void onServiceDataUpdate(long dailyTimeDuration, long dailyOrderNum){
if (null == personalDialogFragment) return;
personalDialogFragment.get().onServiceDataUpdate(dailyTimeDuration,dailyOrderNum);
}
public void queryCurOrderRouteInfo(){
mPresenter.queryCurOrderRouteInfo();
}
public void onCurrentOrderRouteInfoGot(OrderQueryRouteInfoRespBean.Result routeInfo){
if (null == serverOrdersFragment) return;
serverOrdersFragment.onCurrentOrderRouteInfoGot(routeInfo);
}
public void onCurrentOrderDistToStartChanged(long meters, long timeInSecond){
// if (null == serverOrdersFragment) return;
// serverOrdersFragment.onCurrentOrderDistToStartChanged(meters,timeInSecond);
}
public void onCurrentOrderDistToEndChanged(long meters, long timeInSecond){
if (null == serverOrdersFragment) return;
serverOrdersFragment.onCurrentOrderDistToEndChanged(meters,timeInSecond);
}
public void updateLocation(double latitude,double longitude){
this.mCurLatitude = latitude;
this.mCurLongitude = longitude;
}
/**
* 订单流转debug START
*/
public void initOrderTestBar() {
findViewById(R.id.test_bar_to_start).setOnClickListener(v -> {
MogoOCHTaxiModelNew.getInstance().setArriveAtStartStation();
});
findViewById(R.id.test_bar_to_end).setOnClickListener(v -> {
MogoOCHTaxiModelNew.getInstance().setArriveAtEndStation();
});
findViewById(R.id.test_bar_on_the_way_to_end).setOnClickListener(v ->{
showNotice("自动驾驶已启动,请系好安全带");
MogoOCHTaxiModelNew.getInstance().setOnTheWayToEndStation();
});
}
public void clickTestBar(){
View testBar = findViewById(R.id.module_och_taxi_order_status_change_test_bar);
if (testBar.getVisibility() == View.VISIBLE) {
testBar.setVisibility(View.GONE);
} else {
TextView testCurOrderId = findViewById(R.id.test_bar_current_order_id);
TextView testCurStartName = findViewById(R.id.test_bar_current_start_name);
TextView testCurEndName = findViewById(R.id.test_bar_current_end_name);
OrderQueryRespBean.Result order = MogoOCHTaxiModelNew.getInstance().getCurrentOCHOrder();
testCurOrderId.setText(order == null ? "" : String.valueOf(order.orderId));
testCurStartName.setText(order == null ? "" : PinYinUtil.getPinYinHeadChar(order.startSiteAddr));
testCurEndName.setText(order == null ? "" : PinYinUtil.getPinYinHeadChar(order.endSiteAddr));
testBar.setVisibility(View.VISIBLE);
}
}
}

View File

@@ -0,0 +1,193 @@
package com.mogo.och.taxi.passenger.ui;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.utils.OchTaxiUtils;
import java.util.Calendar;
/**
* @author: wangmingjun
* @date: 2021/9/9
*/
public class OCHTaxiGrabOrderFragment extends BaseTaxiUIFragment implements View.OnClickListener {
private TextView mOrderReserverTime;
private TextView mOrderGrabBt;
private TextView mOrderStartStation;
private TextView mOrderEndStation;
private TextView mOrderStartTitle;
private TextView mOrderEndTitle;
private ImageView mOrderCancelIv;
private ImageView mGrabResultAnimView;
private AnimationDrawable mGrabSuccessAnim;
private AnimationDrawable mGrabFailureAnim;
private CountDownTimer countDownTimer = null;
public static OCHTaxiGrabOrderFragment newInstance() {
Bundle args = new Bundle();
OCHTaxiGrabOrderFragment fragment = new OCHTaxiGrabOrderFragment();
fragment.setArguments(args);
return fragment;
}
@Override
protected int getLayoutId() {
return R.layout.taxi_order_grab_view;
}
@Override
protected void initViews(View view) {
mOrderReserverTime = view.findViewById(R.id.grab_order_reserver_time);
mOrderCancelIv = view.findViewById(R.id.grab_order_cancel_iv);
mOrderGrabBt = view.findViewById(R.id.grab_order_tv);
mOrderStartStation = view.findViewById(R.id.grab_order_start_station);
mOrderEndStation = view.findViewById(R.id.grab_order_end_station);
mOrderEndTitle = view.findViewById(R.id.grab_order_end_station_title);
mOrderStartTitle = view.findViewById(R.id.grab_order_start_station_title);
mGrabResultAnimView = view.findViewById(R.id.grab_result_anim);
mGrabResultAnimView.setVisibility(View.GONE);
mOrderEndTitle.setVisibility(View.VISIBLE);
mOrderStartTitle.setVisibility(View.VISIBLE);
mOrderCancelIv.setOnClickListener(this);
mOrderGrabBt.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.grab_order_cancel_iv){//关闭抢单,如果是在抢单中,则只关闭界面,还继续抢单
if (mOrderGrabBt.getText().toString().equals("抢单中...")){
getOchTaxiFragment().showServerFragmentAndUpdate();
return;
}
if (null != countDownTimer){
countDownTimer.cancel();
}
getOchTaxiFragment().cancelNewBookingOrder();
}else if (v.getId() == R.id.grab_order_tv){
if (!mOrderGrabBt.getText().toString().equals("抢单中...")){
getOchTaxiFragment().grabOrder();
return;
}
}
}
private OCHTaxiFragment getOchTaxiFragment(){
return (OCHTaxiFragment)getParentFragment();
}
public void updateGrabOrder(OrderQueryRespBean.Result order){
mGrabResultAnimView.setVisibility(View.GONE);
Calendar calendar = OchTaxiUtils.formatLongToCalendar(order.bookingTime);
if (OchTaxiUtils.compareDateIsCurrentDay(calendar)){
mOrderReserverTime.setText("用车时间:今天 "+OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_HH_mm));
getOchTaxiFragment().showNotice("预约单,今天"+OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_HH_mm)+""
+order.startSiteAddr+""+order.endSiteAddr);
}else {
mOrderReserverTime.setText("用车时间:"+OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_MM_dd_HH_mm));
getOchTaxiFragment().showNotice("预约单,"+OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_MM_dd)+""
+order.startSiteAddr+""+order.endSiteAddr);
}
mOrderStartStation.setText(order.startSiteAddr);
mOrderEndStation.setText(order.endSiteAddr);
mOrderGrabBt.setClickable(true);
mOrderGrabBt.setTextColor(Color.parseColor("#FFFFFF"));
ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams)mOrderGrabBt.getLayoutParams();
lp.bottomMargin = 3;
mOrderGrabBt.setLayoutParams(lp);
mOrderGrabBt.setBackground(getResources().getDrawable(R.drawable.taxi_driver_grab_order_bt));
mOrderGrabBt.setText("抢单(10S)"); //开始倒计时任务
countDownTimer = new CountDownTimer(11000,1000){
@Override
public void onTick(long millisUntilFinished) {
mOrderGrabBt.setText("抢单"+"("+millisUntilFinished/1000+")");
}
@Override
public void onFinish() {//结束倒计时,不抢单
cancel();
getOchTaxiFragment().cancelNewBookingOrder();
}
}.start();
}
public void onGrabOrderExecuteDone(){//进入抢单状态btn样式改变并不可点击
if (null != countDownTimer){
countDownTimer.cancel();
}
mOrderGrabBt.setTextSize(21);
mOrderGrabBt.setText("抢单中...");
ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams)mOrderGrabBt.getLayoutParams();
lp.bottomMargin = 40;
mOrderGrabBt.setLayoutParams(lp);
mOrderGrabBt.setTextColor(Color.parseColor("#181D6D"));
mOrderGrabBt.setBackground(getResources().getDrawable(R.drawable.taxi_grabing_order_btn_bg));
mOrderGrabBt.setClickable(false);
}
// 接单成功,语音播报“抢单成功,请合理安排后续行程接送乘客”
// 接单未成功,语音播报“接单失败,请继续接单”
public void onGrabOrderSuccess(){//抢单成功更新btn 和 动画 语音
getOchTaxiFragment().showNotice("抢单成功,请合理安排后续行程接送乘客");
mGrabResultAnimView.setVisibility(View.VISIBLE);
mGrabResultAnimView.setImageDrawable(getResources().getDrawable(R.drawable.grab_success_anmi_flow));
mOrderGrabBt.setClickable(false);
mOrderGrabBt.setText("抢单成功!");
mGrabSuccessAnim = (AnimationDrawable)mGrabResultAnimView.getDrawable();
if (mGrabSuccessAnim.isOneShot()){
return;
}
mGrabSuccessAnim.start();
//开启动画结束的监听
long delayMillis = mGrabSuccessAnim.getDuration(0) * mGrabSuccessAnim.getNumberOfFrames();
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (null != mGrabSuccessAnim && mGrabSuccessAnim.isRunning()){
mGrabSuccessAnim.stop();
}
// if (mGrabSuccessAnim.getFrame(mGrabSuccessAnim.getNumberOfFrames()-1) == mGrabSuccessAnim.getCurrent()){
getOchTaxiFragment().showServerFragmentAndUpdate();
// }
}
},delayMillis);
//开启动画结束的监听
}
public void onGrabOrderFailed(){//抢单失败更新btn 和 动画 语音
getOchTaxiFragment().showNotice("接单失败,请继续接单");
mGrabResultAnimView.setVisibility(View.VISIBLE);
mGrabResultAnimView.setImageDrawable(getResources().getDrawable(R.drawable.grab_failure_anmi_flow));
mOrderGrabBt.setClickable(false);
mOrderGrabBt.setText("抢单失败!");
mGrabFailureAnim = (AnimationDrawable)mGrabResultAnimView.getDrawable();
mGrabFailureAnim.start();
//开启动画结束的监听
long delayMillis = mGrabFailureAnim.getDuration(0) * mGrabFailureAnim.getNumberOfFrames();
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (null != mGrabFailureAnim && mGrabFailureAnim.isRunning()){
mGrabFailureAnim.stop();
}
getOchTaxiFragment().showServerFragmentAndUpdate();
}
},delayMillis);
}
@Override
public void onDestroy() {
super.onDestroy();
if (countDownTimer != null) countDownTimer.cancel();
}
}

View File

@@ -0,0 +1,130 @@
package com.mogo.och.taxi.passenger.ui;
import android.content.Context;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.utils.OchTaxiUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2021/9/10
*/
public class OCHTaxiOperationDatasFragment extends BaseTaxiUIFragment {
private RecyclerView mRecyclerView;
private static Context mContext;
private List<Long> mDurationData = new ArrayList<>();
private List<Long> mOrderNumData = new ArrayList<>();
private List<Long> mData = new ArrayList<>();
private static int mType = 0;//0: 运营时长 1运营单数
private OperationDataAdapter mAdapter;
public static OCHTaxiOperationDatasFragment newInstance(Context context, int type) {
mContext = context;
mType = type;
Bundle args = new Bundle();
OCHTaxiOperationDatasFragment fragment = new OCHTaxiOperationDatasFragment();
fragment.setArguments(args);
return fragment;
}
@Override
protected int getLayoutId() {
return R.layout.taxi_operation_data_view;
}
@Override
protected void initViews(View view) {
mRecyclerView = view.findViewById(R.id.operation_data_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
mAdapter = new OperationDataAdapter(mContext, mData);
mRecyclerView.setAdapter(mAdapter);
}
public void setmType(int type) {
mType = type;
mData.clear();
if (mType == 0){
mData.addAll(mDurationData);
}else if (mType == 1){
mData.addAll(mOrderNumData);
}
if (mAdapter != null) mAdapter.notifyDataSetChanged();
}
public void updateData(long dailyTimeDuration, long dailyOrderNum) {
mDurationData.clear();
mOrderNumData.clear();
mData.clear();
mDurationData.add(dailyTimeDuration);
mOrderNumData.add(dailyOrderNum);
mData.addAll(mDurationData);
mAdapter.notifyDataSetChanged();
}
class OperationDataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Long> datas;
private Context context;
public OperationDataAdapter(Context context, List<Long> datas) {
this.datas = datas;
this.context = context;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.taxi_operation_data_item_view, parent, false);
OperationDataViewHolder viewHolder = new OperationDataViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof OperationDataViewHolder) {
OperationDataViewHolder viewHolder = (OperationDataViewHolder) holder;
if (0 == mType){
String hourData = TextUtils.isEmpty(OchTaxiUtils.secondsToHourStr(datas.get(position))) ? "0": OchTaxiUtils.secondsToHourStr(datas.get(position));
String minuteData = OchTaxiUtils.secondsToMinuteStr(datas.get(position));
String data = "<font><b><big><big><big>" + hourData + "</big></big></big></b> 时 </font>" + "<font><b><big><big><big>" + minuteData + "</big></big></big></b> 分</font>";
viewHolder.operationDataTv.setText(Html.fromHtml(data));
viewHolder.operationDataTitle.setText("今日在线时长");
}else if (1 == mType){
String data = "<font><b><big><big><big>" + String.valueOf(datas.get(position)) + "</big></big></big></b>" + "" + "</font>";
viewHolder.operationDataTv.setText(Html.fromHtml(data));
viewHolder.operationDataTitle.setText("今日订单完成数");
}
}
}
@Override
public int getItemCount() {
return datas.size();
}
}
class OperationDataViewHolder extends RecyclerView.ViewHolder {
private TextView operationDataTv;
private TextView operationDataTitle;
public OperationDataViewHolder(@NonNull View itemView) {
super(itemView);
operationDataTv = itemView.findViewById(R.id.operation_data_tv);
operationDataTitle = itemView.findViewById(R.id.operation_data_title_tv);
}
}
}

View File

@@ -0,0 +1,210 @@
package com.mogo.och.taxi.passenger.ui;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.och.taxi.passenger.constant.OrderStatusEnum;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.constant.OrderCancelReasons;
import java.lang.ref.WeakReference;
/**
* @author: wangmingjun
* @date: 2021/8/18
*/
public class OCHTaxiOrderCancelDialog extends AlertDialog implements View.OnClickListener,AdapterView.OnItemClickListener {
private static final String TAG = "OCHTaxiOrderCancelDial";
protected WeakReference<Context> contextWeakReference;
private GridView mContentView;
private TextView mCancelCommitTv;
private TextView mDialogCancelTv;
private String mCurrentReason = "";
private ContentAdapter mContentAdapter;
private int mOrderStatus;//1预约单其他为即时单的状态 主要是控制乘客上车 乘客下车这几个选项的显示
private String[] mContentArrays;
private WeakReference<OCHTaxiFragment> mOchTaxiFragmentWeak;
private long mOrderId;
protected OCHTaxiOrderCancelDialog(OCHTaxiFragment fragment, Context context, long orderId, int orderStatus) {
super(context,R.style.OrderCancelDialog);
mOrderId = orderId;
mOchTaxiFragmentWeak = new WeakReference<>(fragment);
this.mOrderStatus = orderStatus;
contextWeakReference = new WeakReference<>(context);
initReasonArray();
}
private void initReasonArray() {
if (1 == mOrderStatus) {
mContentArrays = new String[]{OrderCancelReasons.BookPassengerCancel.getMsg(), OrderCancelReasons.CarBroken.getMsg(),
OrderCancelReasons.BookJourneyConflict.getMsg(), OrderCancelReasons.BatteryLow.getMsg(),
OrderCancelReasons.BookOther.getMsg()};
return;
}
OrderStatusEnum ochStatus = OrderStatusEnum.valueOf(mOrderStatus);
switch (ochStatus) {
case OnTheWayToStartStation:
mContentArrays = new String[]{OrderCancelReasons.CarBroken.getMsg(), OrderCancelReasons.DeviceBroken.getMsg(),
OrderCancelReasons.BatteryLow.getMsg(), OrderCancelReasons.DriverIsIll.getMsg()};
break;
case ArriveAtStartStation:
mContentArrays = new String[]{OrderCancelReasons.CarBroken.getMsg(), OrderCancelReasons.DeviceBroken.getMsg(),
OrderCancelReasons.BatteryLow.getMsg(), OrderCancelReasons.DriverIsIll.getMsg(),
OrderCancelReasons.PassengerNotArrive.getMsg()};
break;
case OnTheWayToEndStation:
case ArriveAtEndStation:
mContentArrays = new String[]{OrderCancelReasons.CarBroken.getMsg(), OrderCancelReasons.DeviceBroken.getMsg(),
OrderCancelReasons.BatteryLow.getMsg(), OrderCancelReasons.DriverIsIll.getMsg(), OrderCancelReasons.PassengerStopOver.getMsg()};
break;
default:
mContentArrays = new String[]{OrderCancelReasons.CarBroken.getMsg(), OrderCancelReasons.DeviceBroken.getMsg(),
OrderCancelReasons.BatteryLow.getMsg(), OrderCancelReasons.DriverIsIll.getMsg(),
OrderCancelReasons.PassengerNotArrive.getMsg(), OrderCancelReasons.PassengerStopOver.getMsg()};
break;
}
}
protected OCHTaxiOrderCancelDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
protected OCHTaxiOrderCancelDialog(Context context, int themeResId) {
super(context, themeResId);
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setBackgroundDrawableResource(R.drawable.taxi_order_cancel_dialog_bg);
setContentView(R.layout.taxi_order_cancel_view);
initView();
setCancelable(false);
setCanceledOnTouchOutside(false);
Window window = getWindow();
//dialog padding 去掉
window.getDecorView().setPadding(0,0,0,0);
window.setDimAmount(0.5f);
window.getDecorView().setBackgroundColor(Color.parseColor("#00FFFFFF"));//设置背景, 不然显示不全
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void initView() {
mContentView = findViewById(R.id.module_och_taxi_order_cancel_content_gv);
mCancelCommitTv = findViewById(R.id.order_cancel_commit_tv);
mDialogCancelTv = findViewById(R.id.order_dialog_cancel_tv);
mContentAdapter = new ContentAdapter(contextWeakReference.get(), mContentArrays);
mContentView.setAdapter(mContentAdapter);
mContentView.setSelector(new ColorDrawable(Color.TRANSPARENT));
mContentView.setOnItemClickListener(this);
mCancelCommitTv.setOnClickListener(this);
mDialogCancelTv.setOnClickListener(this);
mContentView.setOnItemClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.order_cancel_commit_tv) {//bt commit
if (!TextUtils.isEmpty(mCurrentReason) && OrderCancelReasons.getType(mCurrentReason) != 0) {
if (1 == mOrderStatus){//预约单
mOchTaxiFragmentWeak.get().cancelOrderById(mOrderId,OrderCancelReasons.getType(mCurrentReason),mCurrentReason);
}else {//即时单
mOchTaxiFragmentWeak.get().cancelCurOrder(OrderCancelReasons.getType(mCurrentReason),mCurrentReason);
}
dismiss();
}else {
TipToast.longTip("取消原因不能为空");
}
}else if (v.getId() == R.id.order_dialog_cancel_tv){//close icon
mCurrentReason = "";
dismiss();
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG,"mCurrentReason ="+ mContentArrays[position]);
mCurrentReason = mContentArrays[position];
// GradientDrawable background = (GradientDrawable) mCancelBt.getBackground();//GradientDrawable是Drawable的子类
// background.setColor(Color.parseColor("#2B6EFF"));
// mCancelBt.setTextColor(Color.parseColor("#FFFFFF"));
// mCancelBt.setClickable(true);
mContentAdapter.notifyCurrentReasons(mCurrentReason);
}
class ContentAdapter extends BaseAdapter{
private Context context;
private String[] datas;
private LayoutInflater layoutInflater;
private String currentReasons = "";
public ContentAdapter(Context context, String[] array){
this.context = context;
datas = array;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return datas.length;
}
@Override
public Object getItem(int position) {
return datas[position];
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null){
convertView = layoutInflater.inflate(R.layout.taxi_order_checkbox_item,null);
viewHolder = new ViewHolder();
viewHolder.checkBoxTv = convertView.findViewById(R.id.item_checkbox);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkBoxTv.setText(datas[position]);
if(viewHolder.checkBoxTv.getText().toString().equals(currentReasons)){
viewHolder.checkBoxTv.setCompoundDrawablesWithIntrinsicBounds(context.getResources().getDrawable(R.drawable.taxi_selected_btn),null,null,null);
}else {
viewHolder.checkBoxTv.setCompoundDrawablesWithIntrinsicBounds(context.getResources().getDrawable(R.drawable.taxi_unselect_btn),null,null,null);
}
return convertView;
}
public void notifyCurrentReasons(String reason){
currentReasons = reason;
notifyDataSetChanged();
}
class ViewHolder {
TextView checkBoxTv;
}
}
}

View File

@@ -0,0 +1,490 @@
package com.mogo.och.taxi.passenger.ui;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.och.taxi.passenger.constant.OrderStatusEnum;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.constant.OrderTypeEnum;
import com.mogo.och.taxi.passenger.utils.OchTaxiUtils;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
/**
* @author: wangmingjun
* @date: 2021/8/18
*/
public class OCHTaxiPersonalDialogFragment extends DialogFragment implements View.OnClickListener {
private final static String TAG = "OCHTaxiOrdersDialog";
private RelativeLayout mOperationDataRl;
private ImageView mCloseIv;
private RecyclerView mOrdersRv;
private Button mShowOrdersBt;
private TabLayout mOperationTab;
private ViewPager mOperationViewPager;
private OrderAdapter mAdapter;
private ConstraintLayout mNoDatas;
private List<OrderQueryRespBean.Result> orders = new ArrayList<>();
private String[] mTabTitles = {"在线时长","订单完成数"};
private List<OCHTaxiOperationDatasFragment> fragments = new ArrayList<>();
private int mNextPage = 0;
private int mPerPageSize = 10;
private static OCHTaxiFragment mTaxiFragment;
private static boolean serverHadNoData = false;
public OCHTaxiPersonalDialogFragment(OCHTaxiFragment taxiFragment){
mTaxiFragment = taxiFragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
View view = inflater.inflate(R.layout.taxi_orders_list_view, container, false);
initView(view);
return view;
}
@Override
public void onStart() {
super.onStart();
setCancelable(false);
getDialog().setCanceledOnTouchOutside(true);
Window window = getDialog().getWindow();
//dialog padding 去掉
WindowManager.LayoutParams params = window.getAttributes();
params.x = 0;
params.y = 0;
WindowManager windowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
Point point = new Point();
windowManager.getDefaultDisplay().getSize(point);
params.width = (int)(point.x * 0.375);
params.height = point.y;
Log.d(TAG,"width= "+params.width+"height= "+params.height);
window.setAttributes(params);
window.getDecorView().setBackgroundColor(Color.parseColor("#00FFFFFF"));//设置背景, 不然显示不全
window.setGravity(Gravity.LEFT|Gravity.BOTTOM);
}
private void initView(View view) {
initOperationTabDatas(view);
mCloseIv = view.findViewById(R.id.module_och_taxi_order_list_close_iv);
mOperationDataRl = view.findViewById(R.id.module_och_taxi_operation_data_rl);
mShowOrdersBt = view.findViewById(R.id.module_och_taxi_order_list_show_bt);
mOrdersRv = view.findViewById(R.id.module_och_taxi_order_list);
mNoDatas = view.findViewById(R.id.no_order_data_view);
ImageView imageView = view.findViewById(R.id.no_order_data_iv);
imageView.setImageResource(R.drawable.no_order_data);
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams)imageView.getLayoutParams();
params.width = 480;
params.height = 480;
imageView.setLayoutParams(params);
mOrdersRv.setVisibility(View.GONE);
mNoDatas.setVisibility(View.GONE);
mShowOrdersBt.setOnClickListener(this);
mCloseIv.setOnClickListener(this);
}
private void initOperationTabDatas(View view) {
mOperationTab = view.findViewById(R.id.operation_data_tablayout);
mOperationViewPager = view.findViewById(R.id.operation_data_viewpager);
for (int i= 0;i < mTabTitles.length; i++){
TabLayout.Tab tab = mOperationTab.newTab();
tab.view.setBackgroundColor(Color.parseColor("#00000000"));
View tabView = View.inflate(getContext(),R.layout.taxi_operation_tab_item_custom,null);
TextView tv = tabView.findViewById(R.id.operation_tab_title);
tv.setText(mTabTitles[i]);
tab.setCustomView(tabView);
if (0 == i){
mOperationTab.addTab(tab,true);
changeOperationTabLayoutTabUI(tab,true);
fragments.add(OCHTaxiOperationDatasFragment.newInstance(getActivity(),0));
}else if (1 == i){
mOperationTab.addTab(tab);
changeOperationTabLayoutTabUI(tab,false);
fragments.add(OCHTaxiOperationDatasFragment.newInstance(getActivity(),1));
}
}
mOperationTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onTabSelected(TabLayout.Tab tab) {
mOperationViewPager.setCurrentItem(tab.getPosition());
changeOperationTabLayoutTabUI(tab,true);
fragments.get(tab.getPosition()).setmType(tab.getPosition());
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onTabUnselected(TabLayout.Tab tab) {
changeOperationTabLayoutTabUI(tab,false);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
mOperationViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mOperationTab.getTabAt(position).select();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
mOperationViewPager.setAdapter(new OrdersOperationFragmentAdapter(getChildFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
fragments.get(0).setmType(0);
mTaxiFragment.queryDriverServiceData();
}
public void onServiceDataUpdate(long dailyTimeDuration, long dailyOrderNum){
for (int i=0; i< fragments.size();i++){
fragments.get(i).updateData(dailyTimeDuration,dailyOrderNum);
}
}
private void changeOperationTabLayoutTabUI(TabLayout.Tab tab, boolean isSelected) {
TextView textView = (TextView) tab.getCustomView().findViewById(R.id.operation_tab_title);
ImageView imageView = (ImageView) tab.getCustomView().findViewById(R.id.operation_tab_line_iv);
if (isSelected){
textView.setTextSize(23);
Log.d(TAG,"SelectTv = "+ textView.getText());
textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
textView.setTextColor(Color.parseColor("#FFFFFF"));
imageView.setImageDrawable(getResources().getDrawable(R.drawable.taxi_driver_operation_tab_line));
}else {
textView.setTextSize(20);
Log.d(TAG,"unSelectTv = "+ textView.getText());
textView.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
textView.setTextColor(Color.parseColor("#A7B6F0"));
imageView.setImageDrawable(null);
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.module_och_taxi_order_list_close_iv){
dismiss();
}else {
mOrdersRv.setVisibility(View.VISIBLE);
mOperationDataRl.setVisibility(View.GONE);
mNoDatas.setVisibility(View.GONE);
initOrdersView();
requestOrdersList(mNextPage, mPerPageSize);
}
}
private void initOrdersView() {
mAdapter = new OrderAdapter(getContext(),orders);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
mOrdersRv.setLayoutManager(manager);
mOrdersRv.addOnScrollListener(new OnTaxiOrderRvOnScrollListener() {
@Override
public void onLoadMore() {
if (!serverHadNoData){
requestOrdersList(mNextPage, mPerPageSize);
}
}
});
mOrdersRv.setAdapter(mAdapter);
}
private void requestOrdersList(int page, int size){
mTaxiFragment.queryOrdersList(page,size);
}
public void onOrdersListPageRefresh(List<OrderQueryRespBean.Result> ordersList){
if (null == ordersList && mNextPage == 0){//无数据
mOrdersRv.setVisibility(View.GONE);
mNoDatas.setVisibility(View.VISIBLE);
return;
}
mOrdersRv.setVisibility(View.VISIBLE);
mNoDatas.setVisibility(View.GONE);
if ((null == ordersList) || (ordersList.size() < mPerPageSize && mNextPage > 0)){//已经没有更多数据,提示无数据
//已经没有更多数据
serverHadNoData = true;
orders.addAll(ordersList);
mAdapter.notifyDataSetChanged();
mNextPage = mNextPage +1;
return;
}
serverHadNoData = false;
orders.addAll(ordersList);
mAdapter.notifyDataSetChanged();
mNextPage = mNextPage +1;
}
class OrderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static final int ORDER_DETAIL_ITEM = 0;
private static final int DAY_GROUP_ITEM = 1;
private Context context;
List<OrderQueryRespBean.Result> orders;
public OrderAdapter(Context context,List<OrderQueryRespBean.Result> datas){
this.context = context;
this.orders = datas;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ORDER_DETAIL_ITEM){
View view = LayoutInflater.from(context).inflate(R.layout.taxi_orders_list_item,parent,false);
OrderDetailViewHolder viewHolder = new OrderDetailViewHolder(view);
return viewHolder;
}else if (viewType == DAY_GROUP_ITEM){
View view = LayoutInflater.from(context).inflate(R.layout.taxi_orders_list_day_item,parent,false);
DayGroupViewHolder viewHolder = new DayGroupViewHolder(view);
return viewHolder;
}
return null;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
OrderQueryRespBean.Result queryRespBean = orders.get(position);
if (null == queryRespBean) return;
if (holder instanceof DayGroupViewHolder){
DayGroupViewHolder groupViewHolder = (DayGroupViewHolder)holder;
groupViewHolder.dayGroupTv.setText(OchTaxiUtils.getYMDTime(queryRespBean.createTime));
bindOrderDetailData(queryRespBean,groupViewHolder.orderTimeTv,groupViewHolder.startStationTv,groupViewHolder.endStationTv,
groupViewHolder.orderStatusBt,groupViewHolder.orderTypeBt,groupViewHolder.orderNumTv);
if (isNoLineItem(position)){
groupViewHolder.dividerLine.setVisibility(View.VISIBLE);
}else {
groupViewHolder.dividerLine.setVisibility(View.GONE);
}
if (position == orders.size()-1 && serverHadNoData){
groupViewHolder.mBootNoDataView.setVisibility(View.VISIBLE);
}else {
groupViewHolder.mBootNoDataView.setVisibility(View.GONE);
}
}else if (holder instanceof OrderDetailViewHolder){
OrderDetailViewHolder detailViewHolder = (OrderDetailViewHolder)holder;
bindOrderDetailData(queryRespBean,detailViewHolder.orderTimeTv,detailViewHolder.startStationTv,detailViewHolder.endStationTv,
detailViewHolder.orderStatusBt,detailViewHolder.orderTypeBt,detailViewHolder.orderNumTv);
if (isNoLineItem(position)){
detailViewHolder.dividerLine.setVisibility(View.VISIBLE);
}else {
detailViewHolder.dividerLine.setVisibility(View.GONE);
}
if (position == orders.size()-1 && serverHadNoData){
detailViewHolder.mBootNoDataView.setVisibility(View.VISIBLE);
}else {
detailViewHolder.mBootNoDataView.setVisibility(View.GONE);
}
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
//第一个要显示时间
if (position == 0){
return DAY_GROUP_ITEM;
}
String currentDate = OchTaxiUtils.getYMDTime(orders.get(position).createTime);//获取当前订单时间
int prevIndex = position - 1;
String preDate = OchTaxiUtils.getYMDTime(orders.get(prevIndex).createTime);
boolean isDifferent = !preDate.equals(currentDate);//前一个订单的日期跟第二个订单的日期是否一致
return isDifferent ? DAY_GROUP_ITEM : ORDER_DETAIL_ITEM;//一样订单详情, 不一样新添加分组
}
private boolean isNoLineItem(int position){
if (position == orders.size() -1){
return false;
}else {
String currentDate = OchTaxiUtils.getYMDTime(orders.get(position).createTime);//获取当前订单时间
int nextIndex = position + 1;
String preDate = OchTaxiUtils.getYMDTime(orders.get(nextIndex).createTime);
boolean isDifferent = preDate.equals(currentDate);//订单跟后一个订单是否是同一天
return isDifferent;//一样有划分线, 不一样没有划分线
}
}
@Override
public int getItemCount() {
return orders.size();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void bindOrderDetailData(OrderQueryRespBean.Result queryRespBean, TextView orderTimeTv, TextView startStationTv, TextView endStationTv,
Button orderStatusBt, Button orderTypeBt, TextView orderNumTv){
Calendar calendar= Calendar.getInstance();
calendar.setTimeInMillis(queryRespBean.createTime);
orderTimeTv.setText(OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_HH_mm));
startStationTv.setText(queryRespBean.startSiteAddr);
endStationTv.setText(queryRespBean.endSiteAddr);
orderStatusBt.setText(getOrderStatus(queryRespBean.orderStatus,orderStatusBt));
orderTypeBt.setText(getOrderType(queryRespBean.orderType,orderTypeBt));
orderNumTv.setText("订单编号:"+String.valueOf(queryRespBean.orderId));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private String getOrderStatus(int status, Button button){
OrderStatusEnum orderStatus = OrderStatusEnum.valueOf(status);
switch (orderStatus){
case JourneyCompleted:
button.setBackground(context.getDrawable(R.drawable.taxi_order_button_status_canceled_bg));
return "已完成";
case Cancel:
button.setBackground(context.getDrawable(R.drawable.taxi_order_button_status_canceled_bg));
return "已取消";
default:
button.setBackground(context.getDrawable(R.drawable.taxi_order_button_status_bg));
return "服务中";
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private String getOrderType(int type, Button button){
if (type == OrderTypeEnum.Reserved.getType()){
button.setBackground(context.getDrawable(R.drawable.taxi_order_button_type_reserver_bg));
return "预约单";
}else{
button.setBackground(context.getDrawable(R.drawable.taxi_order_button_type_bg));
return "即时单";
}
}
}
class OrderDetailViewHolder extends RecyclerView.ViewHolder{
protected TextView orderTimeTv;
protected Button orderStatusBt;
protected TextView startStationTv;
protected TextView endStationTv;
protected TextView orderNumTv;
protected Button orderTypeBt;
protected View dividerLine;
protected View mBootNoDataView;
public OrderDetailViewHolder(@NonNull View itemView) {
super(itemView);
orderTimeTv = itemView.findViewById(R.id.order_time_hm_tv);
orderStatusBt = itemView.findViewById(R.id.order_status_bt);
startStationTv = itemView.findViewById(R.id.grab_order_start_station);
endStationTv = itemView.findViewById(R.id.grab_order_end_station);
orderNumTv = itemView.findViewById(R.id.order_num);
orderTypeBt = itemView.findViewById(R.id.order_type_bt);
dividerLine = itemView.findViewById(R.id.module_och_taxi_order_divider);
mBootNoDataView = itemView.findViewById(R.id.boot_refresh_no_data_view);
if (DebugConfig.isDebug()){
// TODO: 2021/11/23 因当前上线版本均打开了debug所以此处隐藏orderId
orderNumTv.setVisibility(View.GONE);
}else {
orderNumTv.setVisibility(View.GONE);
}
}
}
class DayGroupViewHolder extends OrderDetailViewHolder{
private TextView dayGroupTv;
public DayGroupViewHolder(@NonNull View itemView) {
super(itemView);
dayGroupTv = itemView.findViewById(R.id.order_day_tv);
}
}
abstract class OnTaxiOrderRvOnScrollListener extends RecyclerView.OnScrollListener{
private boolean isUpwardSliding = false;
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
//不滑动
if (manager instanceof LinearLayoutManager && newState == SCROLL_STATE_IDLE){
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) manager;
int lastItemPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
int itemCount = linearLayoutManager.getItemCount();
Log.d(TAG,"lastItemPosition=="+lastItemPosition+",itemCount=="+itemCount);
//向上滑动到最后一个
if ((lastItemPosition == itemCount-1) && isUpwardSliding){
onLoadMore();
}
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
isUpwardSliding = dy > 0;
}
public abstract void onLoadMore();
}
@Override
public void dismiss() {
super.dismiss();
mNextPage = 0;
orders.clear();
}
private class OrdersOperationFragmentAdapter extends FragmentPagerAdapter{
public OrdersOperationFragmentAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return mTabTitles[position];
}
}
}

View File

@@ -0,0 +1,110 @@
package com.mogo.och.taxi.passenger.ui;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import androidx.appcompat.widget.AppCompatImageView;
import com.mogo.och.taxi.passenger.R;
/**
* @author: wangmingjun
* @date: 2021/9/29
*/
public class OCHTaxiRadiuImageView extends AppCompatImageView {
private float width, height;
private int defaultRadius = 0;
private int radius;
private int leftTopRadius;
private int rightTopRadius;
private int rightBottomRadius;
private int leftBottomRadius;
public OCHTaxiRadiuImageView(Context context) {
this(context, null);
init(context, null);
}
public OCHTaxiRadiuImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
init(context, attrs);
}
public OCHTaxiRadiuImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (Build.VERSION.SDK_INT < 18) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
// 读取配置
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RoundCornerImageView);
radius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_taxi_radius, defaultRadius);
leftTopRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_taxi_left_top_radius, defaultRadius);
rightTopRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_taxi_right_top_radius, defaultRadius);
rightBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_taxi_right_bottom_radius, defaultRadius);
leftBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_taxi_left_bottom_radius, defaultRadius);
if (defaultRadius == leftTopRadius) {
leftTopRadius = radius;
}
if (defaultRadius == rightTopRadius) {
rightTopRadius = radius;
}
if (defaultRadius == rightBottomRadius) {
rightBottomRadius = radius;
}
if (defaultRadius == leftBottomRadius) {
leftBottomRadius = radius;
}
array.recycle();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
width = getWidth();
height = getHeight();
}
@Override
protected void onDraw(Canvas canvas) {
//这里做下判断,只有图片的宽高大于设置的圆角距离的时候才进行裁剪
int maxLeft = Math.max(leftTopRadius, leftBottomRadius);
int maxRight = Math.max(rightTopRadius, rightBottomRadius);
int minWidth = maxLeft + maxRight;
int maxTop = Math.max(leftTopRadius, rightTopRadius);
int maxBottom = Math.max(leftBottomRadius, rightBottomRadius);
int minHeight = maxTop + maxBottom;
if (width >= minWidth && height > minHeight) {
Path path = new Path();
//右上,右下,左下,左上
path.moveTo(leftTopRadius, 0);
path.lineTo(width - rightTopRadius, 0);
path.quadTo(width, 0, width, rightTopRadius);
path.lineTo(width, height - rightBottomRadius);
path.quadTo(width, height, width - rightBottomRadius, height);
path.lineTo(leftBottomRadius, height);
path.quadTo(0, height, 0, height - leftBottomRadius);
path.lineTo(0, leftTopRadius);
path.quadTo(0, 0, leftTopRadius, 0);
canvas.clipPath(path);
}
super.onDraw(canvas);
}
}

View File

@@ -0,0 +1,183 @@
package com.mogo.och.taxi.passenger.ui;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
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.ConstraintLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.utils.OchTaxiUtils;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
/**
* @author: wangmingjun
* @date: 2021/9/2
* 待服务订单列表
*/
public class OCHTaxiReserveOrdersFragment extends BaseTaxiUIFragment {
private RecyclerView mRecyclerView;
private TextView mNodataTv;
private ConstraintLayout mNoDataView;
private View mBootRefreshNoDataView;
private List<OrderQueryRespBean.Result> mDatas = new ArrayList<>();
private ToBeServedOrdersAdapter mAdapter;
private static OCHTaxiFragment mTaxiFragment;
private static Activity mActivity;
private boolean isUpwardSliding = false;
public static OCHTaxiReserveOrdersFragment newInstance(Activity activity, OCHTaxiFragment taxiFragment){
mActivity = activity;
mTaxiFragment = taxiFragment;
Bundle args = new Bundle();
OCHTaxiReserveOrdersFragment fragment = new OCHTaxiReserveOrdersFragment();
fragment.setArguments( args );
return fragment;
}
@Override
protected int getLayoutId() {
return R.layout.taxi_reserve_orders;
}
@Override
protected void initViews(View view) {
mRecyclerView = view.findViewById(R.id.order_to_be_served_rv);
mNodataTv = view.findViewById(R.id.no_order_data_tv);
mNoDataView = view.findViewById(R.id.no_order_data_view);
mNodataTv.setText("暂无待服务订单");
mBootRefreshNoDataView = view.findViewById(R.id.list_boot_refresh_no_data_view);
mBootRefreshNoDataView.setVisibility(View.GONE);
mAdapter = new ToBeServedOrdersAdapter(getActivity(),mDatas);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getParentFragment().getActivity()));
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
//不滑动
if (manager instanceof LinearLayoutManager && newState == SCROLL_STATE_IDLE){
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) manager;
int lastItemPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
int itemCount = manager.getItemCount();
if ((lastItemPosition == itemCount-1) && !isUpwardSliding){
//显示没有更多数据
mBootRefreshNoDataView.setVisibility(View.VISIBLE);
}
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
isUpwardSliding = dy > 0;
}
});
mRecyclerView.setAdapter(mAdapter);
}
public void onOrdersWaitServiceChanged(List<OrderQueryRespBean.Result> waitServiceList){//待服务订单展示
if (waitServiceList.size() == 0){
showNoDataTip();
return;
}
mNoDataView.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
mDatas.clear();
mDatas.addAll(waitServiceList);
mAdapter.notifyDataSetChanged();
}
private void showNoDataTip() {
mBootRefreshNoDataView.setVisibility(View.GONE);
mNoDataView.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
}
class ToBeServedOrdersAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private List<OrderQueryRespBean.Result> datas;
private Context context;
public ToBeServedOrdersAdapter(Context context, List<OrderQueryRespBean.Result> datas){
this.datas = datas;
this.context = context;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.taxi_order_reserve_item,parent,false);
ToBeServedOrdersViewHolder viewHolder = new ToBeServedOrdersViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (datas != null && datas.size() >0 ){
ToBeServedOrdersViewHolder viewHolder = (ToBeServedOrdersViewHolder)holder;
OrderQueryRespBean.Result order = datas.get(position);
Calendar calendar = OchTaxiUtils.formatLongToCalendar(order.bookingTime);
if (OchTaxiUtils.compareDateIsCurrentDay(calendar)){
viewHolder.orderTime.setText("用车时间:今天"+OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_HH_mm));
}else {
viewHolder.orderTime.setText("用车时间:"+OchTaxiUtils.formatCalendarToString(calendar,OchTaxiUtils.TAXI_MM_dd_HH_mm));
}
viewHolder.orderCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new OCHTaxiOrderCancelDialog(mTaxiFragment,context,order.orderId,1).show();
}
});
viewHolder.startStation.setText(order.startSiteAddr);
viewHolder.endStation.setText(order.endSiteAddr);
if (position == mDatas.size() -1){
viewHolder.deliverLine.setVisibility(View.GONE);
}
}
}
@Override
public int getItemCount() {
return datas.size();
}
}
class ToBeServedOrdersViewHolder extends RecyclerView.ViewHolder{
TextView orderTime;
ImageView orderCancel;
TextView startStation;
TextView endStation;
View deliverLine;
public ToBeServedOrdersViewHolder(@NonNull View itemView) {
super(itemView);
orderTime = itemView.findViewById(R.id.to_be_order_time);
orderCancel = itemView.findViewById(R.id.to_be_order_cancel_iv);
startStation = itemView.findViewById(R.id.base_start_station);
endStation = itemView.findViewById(R.id.base_end_station);
deliverLine = itemView.findViewById(R.id.to_be_order_divider);
}
}
public void onOrderCancelDone(long orderId){
TipToast.tip("订单取消成功");
for (int i=0; i< mDatas.size();i++){
OrderQueryRespBean.Result result = mDatas.get(i);
if (orderId == result.orderId){
mDatas.remove(i);
mAdapter.notifyDataSetChanged();
break;
}
}
}
}

View File

@@ -0,0 +1,214 @@
package com.mogo.och.taxi.passenger.ui;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import com.mogo.och.taxi.passenger.bean.OrderQueryRouteInfoRespBean;
import java.util.ArrayList;
import java.util.List;
/**
* @author congtaowang
* @since 2021/1/18
*
* 网约车-出租车UI
*/
public class OCHTaxiServerOrdersFragment extends BaseTaxiUIFragment {
public static final String TAG = "OCHTaxiFragment";
public static OCHTaxiServerOrdersFragment newInstance() {
Bundle args = new Bundle();
OCHTaxiServerOrdersFragment fragment = new OCHTaxiServerOrdersFragment();
fragment.setArguments( args );
return fragment;
}
private FragmentTransaction mFragmentTransaction;
private TabLayout mTaxiOrderTab;
private TextView mWaitOrderSum;
private ViewPager mTaxiOrderPager;
private String[] mTabTitles = {"进行中","待服务"};
private List<Fragment> fragments = new ArrayList<>();
private OCHTaxiBeingServerdOrdersFragment beingServerdOrdersFragment = null;
private OCHTaxiReserveOrdersFragment reserveOrdersFragment = null;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected int getLayoutId() {
return R.layout.taxi_server_orders_panel;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void initViews(View view) {
initOrderTab(view);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void initOrderTab(View view) {
mWaitOrderSum = view.findViewById(R.id.wait_order_num);
mTaxiOrderTab = view.findViewById(R.id.module_och_taxi_tab);
mTaxiOrderPager = view.findViewById(R.id.module_och_taxi_view_pager);
for (int i= 0;i < mTabTitles.length; i++){
TabLayout.Tab tab = mTaxiOrderTab.newTab();
tab.view.setBackgroundColor(Color.parseColor("#00000000"));
View tabView = View.inflate(getActivity(),R.layout.taxi_tab_item_custom,null);
TextView tv = tabView.findViewById(R.id.tab_title);
tv.setText(mTabTitles[i]);
tab.setCustomView(tabView);
if (0 == i){
mTaxiOrderTab.addTab(tab,true);
changeTabLayoutTabUI(tab,true);
beingServerdOrdersFragment = OCHTaxiBeingServerdOrdersFragment.newInstance(getActivity(),(OCHTaxiFragment) getParentFragment());
fragments.add(beingServerdOrdersFragment);
}else if (1 == i){
mTaxiOrderTab.addTab(tab);
changeTabLayoutTabUI(tab,false);
reserveOrdersFragment = OCHTaxiReserveOrdersFragment.newInstance(getActivity(),(OCHTaxiFragment) getParentFragment());
fragments.add(reserveOrdersFragment);
}
}
Log.d(TAG,"activity="+getActivity());
mTaxiOrderTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onTabSelected(TabLayout.Tab tab) {
mTaxiOrderPager.setCurrentItem(tab.getPosition());
changeTabLayoutTabUI(tab,true);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onTabUnselected(TabLayout.Tab tab) {
changeTabLayoutTabUI(tab,false);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
mTaxiOrderPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mTaxiOrderTab.getTabAt(position).select();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
mTaxiOrderPager.setAdapter(new OrdersFragmentAdapter(getChildFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void changeTabLayoutTabUI(TabLayout.Tab tab, boolean isSelected){
TextView textView = (TextView) tab.getCustomView().findViewById(R.id.tab_title);
if (isSelected){
textView.setBackground(getActivity().getDrawable(R.drawable.taxi_driver_tab_item_bg));
textView.setTextSize(20);
Log.d(TAG,"SelectTv = "+ textView.getText());
textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
textView.setTextColor(Color.parseColor("#FFFFFF"));
}else {
textView.setBackground(null);
textView.setTextSize(18);
Log.d(TAG,"unSelectTv = "+ textView.getText());
textView.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
textView.setTextColor(Color.parseColor("#CCD4F5"));
}
}
class OrdersFragmentAdapter extends FragmentPagerAdapter{
private FragmentManager fragmentManager;
public OrdersFragmentAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
this.fragmentManager = fm;
}
@NonNull
@Override
public Fragment getItem(int position) {
Logger.d( TAG, "getItem="+position);
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
Logger.d( TAG, "getPageTitle="+position);
return mTabTitles[position];
}
}
@RequiresApi(api = Build.VERSION_CODES.P)
public void updateCurrentOrderStatusChanged(OrderQueryRespBean.Result order){
if (beingServerdOrdersFragment != null){
mTaxiOrderTab.getTabAt(0).select();
beingServerdOrdersFragment.updateCurrentOrderStatusChanged(order);
}
}
public void onOrdersWaitServiceChanged(List<OrderQueryRespBean.Result> waitServiceList){
if (waitServiceList.size() == 0){
mWaitOrderSum.setVisibility(View.GONE);
}else {
mWaitOrderSum.setText(String.valueOf(waitServiceList.size()));
mWaitOrderSum.setVisibility(View.VISIBLE);
}
if (null == reserveOrdersFragment) return;
reserveOrdersFragment.onOrdersWaitServiceChanged(waitServiceList);
}
public void onOrderCancelDone(long orderId){
if (null == reserveOrdersFragment) return;
reserveOrdersFragment.onOrderCancelDone(orderId);
}
public void onCurrentOrderCancelDone(){
if (null == beingServerdOrdersFragment) return;
beingServerdOrdersFragment.onCurrentOrderCancelDone();
}
public void onCurrentOrderDistToStartChanged(long meters, long timeInSecond){
if (null == beingServerdOrdersFragment) return;
beingServerdOrdersFragment.updateDistanceAndTime(meters,timeInSecond);
}
public void onCurrentOrderDistToEndChanged(long meters, long timeInSecond){
if (null == beingServerdOrdersFragment) return;
beingServerdOrdersFragment.updateDistanceAndTime(meters,timeInSecond);
}
public void onCurrentOrderRouteInfoGot(OrderQueryRouteInfoRespBean.Result routeInfo){
if (null == beingServerdOrdersFragment) return;
beingServerdOrdersFragment.onCurrentOrderRouteInfoGot(routeInfo);
}
}

View File

@@ -0,0 +1,13 @@
package com.mogo.och.taxi.passenger.ui;
import com.mogo.commons.mvp.IView;
public
/**
* @author congtaowang
* @since 2021/1/18
*
* 描述
*/
interface OCHTaxiView extends IView {
}

View File

@@ -0,0 +1,13 @@
package com.mogo.och.taxi.passenger.utils
import android.content.res.Resources
/**
* @author: wangmingjun
* @date: 2022/1/21
*/
object DimenUtil{
fun dp2px(value:Float):Float{
return (0.5f + value * Resources.getSystem().displayMetrics.density)
}
}

View File

@@ -0,0 +1,93 @@
package com.mogo.och.taxi.passenger.utils;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
* @author: wangmingjun
* @date: 2021/8/20
*/
public class OchTaxiUtils {
public static final String TAXI_HH_mm = "HH:mm";
public static final String TAXI_MM_dd = "MM-dd";
public static final String TAXI_MM_dd_HH_mm = "MM-dd HH:mm";
public static final String TAXI_yyyy_MM_dd = "yyyy-MM-dd";
public static final String TAXI_yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
public static String formatCalendarToString(Calendar calendar, String format){
if (calendar == null) return "";
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.format(calendar.getTime());
}catch (Exception e){
e.printStackTrace();
}
return "";
}
public static boolean compareDateIsCurrentDay(Calendar targetCalendar){
Calendar currentCale = DateTimeUtils.getCurrentDateTime();
String currentDay = formatCalendarToString(currentCale,OchTaxiUtils.TAXI_yyyy_MM_dd);
if (currentDay.equals(formatCalendarToString(targetCalendar,OchTaxiUtils.TAXI_yyyy_MM_dd))){
return true;
}else {
return false;
}
}
public static Calendar formatLongToCalendar(long time){
Calendar calendar = null;
try {
calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
}catch (Exception e){
e.printStackTrace();
}
return calendar;
}
public static String formatLongToString(long time, String format){
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.format(time);
}catch (Exception e){
e.printStackTrace();
}
return "";
}
public static String getYMDTime(long time){//格式为 2021.8.21
try {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
int month = calendar.get(Calendar.MONTH) + 1;
return calendar.get(Calendar.YEAR)+"."+month+"."+ calendar.get(Calendar.DAY_OF_MONTH);
}catch (Exception e){
e.printStackTrace();
}
return "";
}
/**
*
* @param seconds 60
* @return 1 时
*/
public static String secondsToHourStr(long seconds){//秒数转成相应的 小时分钟数
if (seconds >= 3600){
int hours = (int)seconds/3600;
return String.valueOf(hours);
}
return "";
}
/**
*
* @param seconds 60
* @return 1 时
*/
public static String secondsToMinuteStr(long seconds){//秒数转成相应的 小时分钟数
int minute = (int)(seconds % 3600)/60;
return String.valueOf(minute);
}
}

View File

@@ -0,0 +1,22 @@
package com.mogo.och.taxi.passenger.utils;
import com.mogo.och.taxi.passenger.bean.OrderQueryRespBean;
import java.util.Arrays;
import java.util.List;
/**
* Created on 2021/9/11
*/
public class OrderUtil {
// 判断两个list中的订单是否相同依据orderId
public static boolean haveSameOrders(List<OrderQueryRespBean.Result> list1,
List<OrderQueryRespBean.Result> list2) {
OrderQueryRespBean.Result[] arr1 = list1.toArray(new OrderQueryRespBean.Result[]{});
OrderQueryRespBean.Result[] arr2 = list2.toArray(new OrderQueryRespBean.Result[]{});
Arrays.sort(arr1);
Arrays.sort(arr1);
return Arrays.equals(arr1,arr2);
}
}

View File

@@ -0,0 +1,37 @@
package com.mogo.och.taxi.passenger.utils;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import androidx.core.content.ContextCompat;
/**
* @author: wangmingjun
* @date: 2021/12/7
*/
public class PermissionUtil {
public static boolean checkPermission(Context context,String... permissons) {
for (String permisson : permissons) {
if ((ContextCompat.checkSelfPermission(context,
permisson) != PackageManager.PERMISSION_GRANTED)) {
return false;
}
}
return true;
}
public static boolean isLocServiceEnable(Context context) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,31 @@
package com.mogo.och.taxi.passenger.utils;
import net.sourceforge.pinyin4j.PinyinHelper;
/**
* @author: wangmingjun
* @date: 2021/11/26
*/
public class PinYinUtil {
/**
* 得到中文字符串首字母
* @param str 需要转化的中文字符串
* @return 大写首字母缩写的字符串
*/
public static String getPinYinHeadChar(String str) {
str = str.replaceAll("[\\p{P}‘’“”|+=¥$<>^~]", "");
StringBuilder convert = new StringBuilder();
for (int j = 0; j < str.length(); j++) {
char word = str.charAt(j);
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
if (pinyinArray != null) {
convert.append(pinyinArray[0].charAt(0));
} else {
if (!"".equals(String.valueOf(word).trim())){
convert.append(word);
}
}
}
return convert.toString().trim().toUpperCase();
}
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/taxi_autopilot_text_color_normal"/>
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" tools:ignore="MissingDefaultResource">
<item android:drawable="@drawable/taxi_ic_autopilot_bg_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/taxi_ic_autopilot_bg"/>
</selector>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape android:shape="rectangle">
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="50px" android:topLeftRadius="50px" android:topRightRadius="20px" />
<gradient android:angle="315" android:endColor="#2B6EFF" android:startColor="#2B6EFF" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="50px" android:topLeftRadius="50px" android:topRightRadius="20px" />
<gradient android:angle="315" android:endColor="#3B4577" android:startColor="#3B4577" />
</shape>
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- <item android:state_checked="true">-->
<!-- <shape android:shape="rectangle">-->
<!-- <corners android:bottomLeftRadius="20px" android:bottomRightRadius="50px" android:topLeftRadius="50px" android:topRightRadius="20px" />-->
<!-- <gradient android:angle="315" android:endColor="#2B6EFF" android:startColor="#2B6EFF" />-->
<!-- </shape>-->
<!-- </item>-->
<item>
<shape android:shape="rectangle">
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="50px" android:topLeftRadius="50px" android:topRightRadius="20px" />
<gradient android:angle="315" android:endColor="#1E2E87 " android:startColor="#7792F9" />
</shape>
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

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