This commit is contained in:
wangcongtao
2020-03-02 16:50:07 +08:00
parent 61fcda00ae
commit 135cced9d9
8 changed files with 826 additions and 696 deletions

View File

@@ -64,172 +64,33 @@ import java.util.List;
* 4. 用户交互语音导致地图视图移动,缩放,不触发刷新
*/
@Route( path = ServiceConst.PATH_REFRESH_STRATEGY )
public class MogoServiceProvider implements IMogoModuleProvider,
IMogoMapListener,
IMogoLocationListener,
IMogoNaviListener,
IMogoStatusChangedListener,
IMogoIntentListener {
public class MogoServiceProvider implements IMogoModuleProvider{
private static final String TAG = "MogoRefreshStrategyProvider";
/**
* 自动刷新策略
*/
private AutoRefreshStrategy mAutoRefreshStrategy = new AutoRefreshStrategy();
private MogoLatLng mLastAutoRefreshLocation = null;
@Override
public int getType() {
return ModuleType.TYPE_SERVICE;
}
private IMogoMarkerManager mMarkerManager;
private IMogoMapUIController mUiController;
/**
* 是否已计算出地图显示状态
*/
private boolean mIsMapStatusOk = false;
/**
* 地图显示是横屏还是竖屏:根据地图右上角和左下角坐标计算
*/
boolean mIsVertical = false;
private MogoReceiver mAIAssistReceiver;
/**
* 手动刷新策略
*/
private CustomRefreshStrategy mCustomRefreshStrategy = new CustomRefreshStrategy();
private float mLastZoomLevel = 0;
private RefreshModel mRefreshModel;
private long mRefreshRemainingTime = Long.MAX_VALUE;
// 上次手动操作的中心点坐标
private MogoLatLng mLastCustomRefreshCenterLocation;
private IMogoMapService mMogoMapService;
private IMogoStatusManager mStatusManager;
private IMogoIntentManager mIntentManager;
/**
* 地图视图初始化
*/
private boolean mIsCameraInited = true;
/**
* 是否针对第一次请求失败的情况(开机请求、地库长时间没网络)
* <p>
* 说明第一次地位成功因为网络问题导致请求失败则在其他策略请求之前尝试10s请求一次。
*/
private boolean mLoopRequest = false;
private Handler mHandler = new Handler( Looper.getMainLooper() ) {
@Override
public void handleMessage( @NonNull Message msg ) {
super.handleMessage( msg );
switch ( msg.what ) {
case ServiceConst.MSG_TYPE_REFRESH_DECREASE:
if ( mStatusManager.isSearchUIShow() || mStatusManager.isADASShow() ) {
stopAutoRefreshStrategy();
return;
}
mRefreshRemainingTime -= ServiceConst.DECREASE_INTERVAL;
if ( mRefreshRemainingTime == 0 ) {
Logger.d( TAG, "move to center and refresh data." );
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, false );
mUiController.recoverLockMode();
mStatusManager.setUserInteractionStatus( TAG, true, false );
mUiController.changeZoom( 16.0f );
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
} else {
mHandler.sendEmptyMessageDelayed( msg.what, ServiceConst.DECREASE_INTERVAL );
}
break;
case ServiceConst.MSG_LOOP_REQUEST:
if ( mStatusManager.isSearchUIShow() || mStatusManager.isADASShow() ) {
return;
}
if ( mLoopRequest ) {
Logger.d( TAG, "补偿刷新触发" );
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
break;
}
}
};
private Context mContext;
/**
* 地图视图西南角坐标
*/
private MogoLatLng mCameraSouthWestPosition;
/**
* 地图视图东北角坐标
*/
private MogoLatLng mCameraNorthEastPosition;
/**
* 手动刷新回调
*/
private RefreshCallback mCustomRefreshCallback = new RefreshCallback() {
@Override
public void onSuccess() {
mLoopRequest = false;
mRefreshRemainingTimeStatus = false;
// 用户手动操作地图刷新成功后,设置状态为 true引发延时策略
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, true );
}
@Override
public void onFail() {
}
};
/**
* 自动刷新回调
*/
private RefreshCallback mAutoRefreshCallback = new RefreshCallback() {
@Override
public void onSuccess() {
mLoopRequest = false;
Logger.d( TAG, "request Success." );
invokeAutoRefreshStrategy();
}
@Override
public void onFail() {
if ( mLoopRequest ) {
Logger.d( TAG, "onFail and loop" );
mHandler.sendEmptyMessageDelayed( ServiceConst.MSG_LOOP_REQUEST, ServiceConst.LOOP_INTERVAL );
} else {
invokeAutoRefreshStrategy();
}
}
private void invokeAutoRefreshStrategy() {
if ( mStatusManager.isSearchUIShow() ) {
return;
}
mRefreshRemainingTime = mAutoRefreshStrategy.getInterval();
mHandler.removeMessages( ServiceConst.MSG_TYPE_REFRESH_DECREASE );
mHandler.sendEmptyMessageDelayed( ServiceConst.MSG_TYPE_REFRESH_DECREASE, ServiceConst.DECREASE_INTERVAL );
}
};
// 延时状态
private boolean mRefreshRemainingTimeStatus = false;
@NonNull
@Override
public String getModuleName() {
return ServiceConst.TYPE;
}
@Override
public final Fragment createFragment( Context context, Bundle data ) {
public Fragment createFragment( Context context, Bundle data ) {
return null;
}
@Override
public final View createView( Context context ) {
public View createView( Context context ) {
return null;
}
@Override
public final IMogoModuleLifecycle getCardLifecycle() {
public IMogoModuleLifecycle getCardLifecycle() {
return null;
}
@@ -238,11 +99,6 @@ public class MogoServiceProvider implements IMogoModuleProvider,
return null;
}
@Override
public int getType() {
return ModuleType.TYPE_SERVICE;
}
@Override
public IMogoNaviListener getNaviListener() {
return null;
@@ -253,434 +109,11 @@ public class MogoServiceProvider implements IMogoModuleProvider,
return null;
}
@NonNull
@Override
public String getModuleName() {
return ServiceConst.TYPE;
}
@Override
public void init( Context context ) {
mContext = context;
mRefreshModel = new RefreshModel( context );
mMogoMapService = ( IMogoMapService ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_MAP ).navigation( context );
mMarkerManager = mMogoMapService.getMarkerManager( context );
mUiController = mMogoMapService.getMapUIController();
mStatusManager = ( IMogoStatusManager ) ARouter.getInstance().build( MogoServicePaths.PATH_STATUS_MANAGER ).navigation( context );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.USER_INTERACTED, this );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.SEARCH_UI, this );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.V2X_UI, this );
//TODO 初始化地图地图绘制大而全的Marker
MarkerServiceHandler.init( mContext );
registerAIReceiver( context );
IMogoRegisterCenter registerCenter = ( IMogoRegisterCenter ) ARouter.getInstance().build( MogoServicePaths.PATH_REGISTER_CENTER ).navigation( context );
registerCenter.registerMogoLocationListener( getModuleName(), this );
registerCenter.registerMogoNaviListener( getModuleName(), this );
registerCenter.registerMogoMapListener( getModuleName(), this );
mIntentManager = ( IMogoIntentManager ) ARouter.getInstance().build( MogoServicePaths.PATH_INTENT_MANAGER ).navigation( context );
mIntentManager.registerIntentListener( MogoReceiver.ACTIION_ADAS, this );
mIntentManager.registerIntentListener( Intent.ACTION_POWER_CONNECTED, this );
mIntentManager.registerIntentListener( Intent.ACTION_POWER_DISCONNECTED, this );
mIntentManager.registerIntentListener( MogoReceiver.ACTION_NWD_ACC, this );
mIntentManager.registerIntentListener( MogoReceiver.ACTION_VOICE_UI, this );
}
private void registerAIReceiver( Context context ) {
if ( context == null ) {
return;
}
List< MogoModule > modules = MogoModulePaths.getModules();
if ( modules.isEmpty() || modules == null ) {
return;
}
mAIAssistReceiver = new MogoReceiver( context );
IntentFilter filter = new IntentFilter();
if ( modules != null && !modules.isEmpty() ) {
for ( MogoModule module : modules ) {
if ( TextUtils.isEmpty( module.getBroadcastAction() ) ) {
continue;
}
filter.addAction( module.getBroadcastAction() );
}
}
filter.addAction( MogoReceiver.VOICE_ACTION );
filter.addAction( MogoReceiver.ACTIION_ADAS );
filter.addAction( MogoReceiver.ACTION_NWD_ACC );
// acc On
filter.addAction( Intent.ACTION_POWER_CONNECTED );
filter.addAction( Intent.ACTION_POWER_DISCONNECTED );
// 小智语音
filter.addAction( MogoReceiver.ACTION_VOICE_UI );
try {
context.getApplicationContext().registerReceiver( mAIAssistReceiver, filter );
Logger.i( TAG, "register voice receiver." );
} catch ( Exception e ) {
Logger.e( TAG, e, "error. " );
}
}
@Override
public void onMapLoaded() {
refreshCameraPosition();
}
private void initMapStatus() {
if ( mIsMapStatusOk ) {
return;
}
try {
float width = getMapCameraFactWidth();
float height = getMapCameraFactHeight();
mIsVertical = width < height;
Logger.i( TAG, "map status is vertical : " + mIsVertical );
mIsMapStatusOk = true;
} catch ( Exception e ) {
e.printStackTrace();
}
}
/**
* 地图视图对应的实际宽度
*
* @return
*/
private float getMapCameraFactWidth() {
try {
return Utils.calculateLineDistance( mCameraNorthEastPosition, new MogoLatLng( mCameraNorthEastPosition.lat, mCameraSouthWestPosition.lng ) );
} catch ( Exception e ) {
return 1000f;
}
}
/**
* 地图视图对应的实际高度
*
* @return
*/
private float getMapCameraFactHeight() {
try {
return Utils.calculateLineDistance( mCameraSouthWestPosition, new MogoLatLng( mCameraNorthEastPosition.lat, mCameraSouthWestPosition.lng ) );
} catch ( Exception e ) {
return 1000f;
}
}
/**
* 刷新视图范围坐标
*/
private void refreshCameraPosition() {
mCameraSouthWestPosition = mUiController.getCameraSouthWestPosition();
mCameraNorthEastPosition = mUiController.getCameraNorthEastPosition();
initMapStatus();
if ( mIsVertical ) {
float width = getMapCameraFactWidth();
Logger.i( TAG, "current zoom level width: %f m", width );
} else {
float height = getMapCameraFactHeight();
Logger.i( TAG, "current zoom level height: %f m", height );
}
}
@Override
public void onTouch( MotionEvent motionEvent ) {
switch ( motionEvent.getActionMasked() ) {
case MotionEvent.ACTION_DOWN:
if ( mLastZoomLevel == 0 ) {
mLastZoomLevel = mUiController.getZoomLevel();
Logger.i( TAG, "初始化缩放级别 为:%f", mLastZoomLevel );
}
break;
case MotionEvent.ACTION_UP:
break;
}
}
private void stopAutoRefreshStrategy() {
Logger.d( TAG, "stop auto refresh strategy" );
mHandler.removeMessages( ServiceConst.MSG_TYPE_REFRESH_DECREASE );
}
@Override
public void onPOIClick( MogoPoi poi ) {
}
@Override
public void onMapClick( MogoLatLng latLng ) {
}
@Override
public void onLockMap( boolean isLock ) {
}
@Override
public void onMapModeChanged( EnumMapUI ui ) {
}
@Override
public void onMapChanged( MogoLatLng latLng, float zoom, float tilt, float bearing ) {
if ( mIsCameraInited ) {
mLastZoomLevel = zoom;
mLastCustomRefreshCenterLocation = latLng;
mIsCameraInited = false;
return;
}
if ( mLastZoomLevel != zoom || mCameraNorthEastPosition == null ) {
refreshCameraPosition();
}
// 部分非用户操作导致地图视图变化:绘线、圈点等不触发用户刷新
// 消费状态
if ( mStatusManager.isUserInteracted() ) {
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
refreshCameraPosition();
return;
}
// v2x // adas 状态下不做任何操作
if ( mStatusManager.isADASShow() ) {
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
refreshCameraPosition();
return;
}
// 手动刷新触发
if ( mLastZoomLevel - zoom > mCustomRefreshStrategy.getZoomOutLevel() ) {
// 缩放级别缩小
notifyRefreshData( latLng, getQueryRadius(), mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
} else if ( mLastZoomLevel - zoom < 0 ) {
mLastZoomLevel = zoom;
} else if ( mLastZoomLevel == zoom ) {
// 手动平移
if ( invokeRefreshWhenTranslationByUser( latLng ) ) {
notifyRefreshData( latLng, getQueryRadius(), mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
}
}
}
private int getQueryRadius() {
if ( mIsVertical ) {
return ( ( int ) ( getMapCameraFactWidth() / 2 ) );
}
return ( ( int ) ( getMapCameraFactHeight() / 2 ) );
}
/**
* 平移地图刷新策略
*
* @return
*/
private boolean invokeRefreshWhenTranslationByUser( MogoLatLng latLng ) {
try {
float factor = 0.0f;
if ( mIsVertical ) {
factor = getMapCameraFactWidth();
} else {
factor = getMapCameraFactHeight();
}
if ( factor == 0.0f ) {
return false;
}
Logger.d( TAG, "invokeRefreshWhenTranslationByUsermLastCustomRefreshCenterLocation = %s, latLng = %s", mLastCustomRefreshCenterLocation, latLng );
float distance = Utils.calculateLineDistance( latLng, mLastCustomRefreshCenterLocation );
return distance > factor;
} catch ( Exception e ) {
Logger.e( TAG, e, "warming. " );
return false;
}
}
@Override
public void onLocationChanged( MogoLocation location ) {
if ( mStatusManager.isADASShow() ) {
return;
}
if ( mStatusManager.isSearchUIShow() ) {
return;
}
if ( location == null ) {
return;
}
// 自动刷新触发
final MogoLatLng point = new MogoLatLng( location.getLatitude(), location.getLongitude() );
if ( mLastAutoRefreshLocation == null ) {
mLastAutoRefreshLocation = point;
mLoopRequest = true;
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
return;
}
float distance = Utils.calculateLineDistance( mLastAutoRefreshLocation, point );
if ( distance > mAutoRefreshStrategy.getDistance() ) {
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, false );
mUiController.recoverLockMode();
mStatusManager.setUserInteractionStatus( TAG, true, false );
mUiController.changeZoom( 16.0f );
mLastAutoRefreshLocation = point;
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
}
/**
* 刷新数据
*/
private void notifyRefreshData( MogoLatLng latLng, int radius, RefreshCallback callback ) {
if ( mStatusManager.isSearchUIShow() ) {
return;
}
Logger.d( TAG, mAutoRefreshCallback == callback ? "触发自动刷新" : "触发手动刷新" );
int amount = mLastZoomLevel >= 10 ? 5 : 10;
mRefreshModel.refreshData( latLng, radius, amount, callback );
Logger.i( TAG, "刷新半径 = %d, 点 = %s, zoomLevel = %f, amount = %d", radius, latLng, mLastZoomLevel, amount );
}
@Override
public void onInitNaviFailure() {
}
@Override
public void onInitNaviSuccess() {
}
@Override
public void onNaviInfoUpdate( MogoNaviInfo naviinfo ) {
}
@Override
public void onStartNavi() {
}
@Override
public void onStopNavi() {
}
@Override
public void onStatusChanged( StatusDescriptor descriptor, boolean isTrue ) {
Logger.d( TAG, "状态发生改变---descriptor---" + descriptor + "----isTrue---" + isTrue );
switch ( descriptor ) {
case USER_INTERACTED:
if ( isTrue && !mRefreshRemainingTimeStatus ) {
mRefreshRemainingTimeStatus = true;
mRefreshRemainingTime += mAutoRefreshStrategy.getInterruptInterval();
Logger.i( TAG, "用户状态改变,自动刷新时间延时,%s ms后自动刷新", mRefreshRemainingTime );
}
break;
case SEARCH_UI:
if ( isTrue ) {
// 搜索时,不在自动刷新打点策略
stopAutoRefreshStrategy();
} else {
// 搜索后,打开打点策略
if ( mAutoRefreshCallback != null ) {
mAutoRefreshCallback.onSuccess();
}
}
break;
case V2X_UI:
try {
if ( isTrue ) {
// V2X_UI时不在自动刷新打点策略
stopAutoRefreshStrategy();
// 清除所有的打点信息记录
MarkerServiceHandler.getMapMarkerManager().alreadySmallMarker.clear();
} else {
// 主动刷新
refreshStrategy();
// V2X_UI后打开打点策略
if ( mAutoRefreshCallback != null ) {
mAutoRefreshCallback.onSuccess();
}
}
} catch ( Exception e ) {
e.printStackTrace();
}
break;
}
}
public void refreshStrategy() {
Logger.d( TAG, "move to center and refresh data." );
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, false );
mUiController.recoverLockMode();// 锁车代替移到中心点
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
@Override
public void onCalculateSuccess() {
}
@Override
public void onoCalculateFailed() {
}
@Override
public void onUpdateTraffic( MogoTraffic traffic ) {
if ( traffic != null ) {
Logger.i( TAG, "speed = %d, desc = %s", traffic.getSpeedLimit(), traffic.getDesc() );
// 发送当前限速到 adas
Intent intent = new Intent( "com.mogo.launcher.adas" );
intent.putExtra( "adas_speed_limit", traffic.getSpeedLimit() );
mContext.sendBroadcast( intent );
}
}
public IMogoMarkerClickListener getMarkerClickListener() {
return null;
}
@Override
public void onIntentReceived( String command, Intent intent ) {
if ( MogoReceiver.ACTIION_ADAS.equals( command ) ) {
if ( intent == null ) {
return;
}
int status = intent.getIntExtra( MogoReceiver.PARAM_ADAS_STATUS, 0 );
if (status == 1 ){
MarkerServiceHandler.getMapUIController().setLockZoom(15);
}else{
MarkerServiceHandler.getMapUIController().setLockZoom(16);
}
mStatusManager.setADASUIShow( getModuleName(), status == 1 );
} else if ( Intent.ACTION_POWER_CONNECTED.equals( command ) ) {
mStatusManager.setAccStatus( getModuleName(), true );
} else if ( Intent.ACTION_POWER_DISCONNECTED.equals( command ) ) {
mStatusManager.setAccStatus( getModuleName(), false );
} else if ( MogoReceiver.ACTION_NWD_ACC.equals( command ) ) {
int state = intent.getByteExtra( MogoReceiver.PARAM_ACC_STATUS, ( byte ) 0 );
mStatusManager.setAccStatus( getModuleName(), state == 1 );
} else if ( MogoReceiver.ACTION_VOICE_UI.equals( command ) ) {
String val = intent.getStringExtra( MogoReceiver.PARRAM_WAKE_STATUS );
if ( TextUtils.equals( val, MogoReceiver.VALUE_DISMISS ) ) {
mStatusManager.setVoiceUIShow( TAG, false );
} else if ( TextUtils.equals( val, MogoReceiver.VALUE_SHOW ) ) {
mStatusManager.setVoiceUIShow( TAG, true );
}
}
}
@Override
public String getAppPackage() {
return null;
@@ -690,4 +123,9 @@ public class MogoServiceProvider implements IMogoModuleProvider,
public String getAppName() {
return null;
}
@Override
public void init( Context context ) {
MogoServices.getInstance().init( context );
}
}

View File

@@ -0,0 +1,647 @@
package com.mogo.module.service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.map.MogoLatLng;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.model.MogoPoi;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.navi.MogoTraffic;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.common.MogoModule;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.module.service.network.RefreshCallback;
import com.mogo.module.service.network.RefreshModel;
import com.mogo.module.service.receiver.MogoReceiver;
import com.mogo.module.service.refresh.AutoRefreshStrategy;
import com.mogo.module.service.refresh.CustomRefreshStrategy;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.intent.IMogoIntentListener;
import com.mogo.service.intent.IMogoIntentManager;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.module.IMogoRegisterCenter;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.logger.Logger;
import java.util.List;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 数据刷新策略
* <p>
* 1. 位置移动触发刷新
* 2. 用户手势交互导致地图视图移动跨过当前视图,延时 1 分钟,不累加
* 3. 用户手势缩小比例尺级别达2级延时 1 分钟,不累加
* 4. 用户交互语音导致地图视图移动,缩放,不触发刷新
*/
public class MogoServices implements IMogoMapListener,
IMogoLocationListener,
IMogoNaviListener,
IMogoStatusChangedListener,
IMogoIntentListener {
private MogoServices(){
// private constructor
}
private static final class InstanceHolder{
private static final MogoServices INSTANCE = new MogoServices();
}
public static MogoServices getInstance(){
return InstanceHolder.INSTANCE;
}
private Object readResolve(){
// 阻止反序列化,必须实现 Serializable 接口
return InstanceHolder.INSTANCE;
}
private static final String TAG = "MogoServices";
/**
* 自动刷新策略
*/
private AutoRefreshStrategy mAutoRefreshStrategy = new AutoRefreshStrategy();
private MogoLatLng mLastAutoRefreshLocation = null;
private IMogoMapUIController mUiController;
/**
* 是否已计算出地图显示状态
*/
private boolean mIsMapStatusOk = false;
/**
* 地图显示是横屏还是竖屏:根据地图右上角和左下角坐标计算
*/
private boolean mIsVertical = false;
private MogoReceiver mAIAssistReceiver;
/**
* 手动刷新策略
*/
private CustomRefreshStrategy mCustomRefreshStrategy = new CustomRefreshStrategy();
private float mLastZoomLevel = 0;
private RefreshModel mRefreshModel;
private long mRefreshRemainingTime = Long.MAX_VALUE;
// 上次手动操作的中心点坐标
private MogoLatLng mLastCustomRefreshCenterLocation;
private IMogoMapService mMogoMapService;
private IMogoStatusManager mStatusManager;
private IMogoIntentManager mIntentManager;
/**
* 地图视图初始化
*/
private boolean mIsCameraInited = true;
/**
* 是否针对第一次请求失败的情况(开机请求、地库长时间没网络)
* <p>
* 说明第一次地位成功因为网络问题导致请求失败则在其他策略请求之前尝试10s请求一次。
*/
private boolean mLoopRequest = false;
private Handler mHandler = new Handler( Looper.getMainLooper() ) {
@Override
public void handleMessage( @NonNull Message msg ) {
super.handleMessage( msg );
switch ( msg.what ) {
case ServiceConst.MSG_TYPE_REFRESH_DECREASE:
if ( mStatusManager.isSearchUIShow() || mStatusManager.isADASShow() ) {
stopAutoRefreshStrategy();
return;
}
mRefreshRemainingTime -= ServiceConst.DECREASE_INTERVAL;
if ( mRefreshRemainingTime == 0 ) {
Logger.d( TAG, "move to center and refresh data." );
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, false );
mUiController.recoverLockMode();
mStatusManager.setUserInteractionStatus( TAG, true, false );
mUiController.changeZoom( 16.0f );
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
} else {
mHandler.sendEmptyMessageDelayed( msg.what, ServiceConst.DECREASE_INTERVAL );
}
break;
case ServiceConst.MSG_LOOP_REQUEST:
if ( mStatusManager.isSearchUIShow() || mStatusManager.isADASShow() ) {
return;
}
if ( mLoopRequest ) {
Logger.d( TAG, "补偿刷新触发" );
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
break;
}
}
};
private Context mContext;
/**
* 地图视图西南角坐标
*/
private MogoLatLng mCameraSouthWestPosition;
/**
* 地图视图东北角坐标
*/
private MogoLatLng mCameraNorthEastPosition;
/**
* 手动刷新回调
*/
private RefreshCallback mCustomRefreshCallback = new RefreshCallback() {
@Override
public void onSuccess() {
mLoopRequest = false;
mRefreshRemainingTimeStatus = false;
// 用户手动操作地图刷新成功后,设置状态为 true引发延时策略
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, true );
}
@Override
public void onFail() {
}
};
/**
* 自动刷新回调
*/
private RefreshCallback mAutoRefreshCallback = new RefreshCallback() {
@Override
public void onSuccess() {
mLoopRequest = false;
Logger.d( TAG, "request Success." );
invokeAutoRefreshStrategy();
}
@Override
public void onFail() {
if ( mLoopRequest ) {
Logger.d( TAG, "onFail and loop" );
mHandler.sendEmptyMessageDelayed( ServiceConst.MSG_LOOP_REQUEST, ServiceConst.LOOP_INTERVAL );
} else {
invokeAutoRefreshStrategy();
}
}
private void invokeAutoRefreshStrategy() {
if ( mStatusManager.isSearchUIShow() ) {
return;
}
mRefreshRemainingTime = mAutoRefreshStrategy.getInterval();
mHandler.removeMessages( ServiceConst.MSG_TYPE_REFRESH_DECREASE );
mHandler.sendEmptyMessageDelayed( ServiceConst.MSG_TYPE_REFRESH_DECREASE, ServiceConst.DECREASE_INTERVAL );
}
};
// 延时状态
private boolean mRefreshRemainingTimeStatus = false;
public void init( Context context ) {
mContext = context;
mRefreshModel = new RefreshModel( context );
mMogoMapService = ( IMogoMapService ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_MAP ).navigation( context );
mUiController = mMogoMapService.getMapUIController();
mStatusManager = ( IMogoStatusManager ) ARouter.getInstance().build( MogoServicePaths.PATH_STATUS_MANAGER ).navigation( context );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.USER_INTERACTED, this );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.SEARCH_UI, this );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.V2X_UI, this );
//TODO 初始化地图地图绘制大而全的Marker
MarkerServiceHandler.init( mContext );
registerAIReceiver( context );
IMogoRegisterCenter registerCenter = ( IMogoRegisterCenter ) ARouter.getInstance().build( MogoServicePaths.PATH_REGISTER_CENTER ).navigation( context );
registerCenter.registerMogoLocationListener( ServiceConst.TYPE, this );
registerCenter.registerMogoNaviListener( ServiceConst.TYPE, this );
registerCenter.registerMogoMapListener( ServiceConst.TYPE, this );
mIntentManager = ( IMogoIntentManager ) ARouter.getInstance().build( MogoServicePaths.PATH_INTENT_MANAGER ).navigation( context );
mIntentManager.registerIntentListener( MogoReceiver.ACTIION_ADAS, this );
mIntentManager.registerIntentListener( Intent.ACTION_POWER_CONNECTED, this );
mIntentManager.registerIntentListener( Intent.ACTION_POWER_DISCONNECTED, this );
mIntentManager.registerIntentListener( MogoReceiver.ACTION_NWD_ACC, this );
mIntentManager.registerIntentListener( MogoReceiver.ACTION_VOICE_UI, this );
}
private void registerAIReceiver( Context context ) {
if ( context == null ) {
return;
}
List< MogoModule > modules = MogoModulePaths.getModules();
if ( modules.isEmpty() || modules == null ) {
return;
}
mAIAssistReceiver = new MogoReceiver( context );
IntentFilter filter = new IntentFilter();
if ( modules != null && !modules.isEmpty() ) {
for ( MogoModule module : modules ) {
if ( TextUtils.isEmpty( module.getBroadcastAction() ) ) {
continue;
}
filter.addAction( module.getBroadcastAction() );
}
}
filter.addAction( MogoReceiver.VOICE_ACTION );
filter.addAction( MogoReceiver.ACTIION_ADAS );
filter.addAction( MogoReceiver.ACTION_NWD_ACC );
// acc On
filter.addAction( Intent.ACTION_POWER_CONNECTED );
filter.addAction( Intent.ACTION_POWER_DISCONNECTED );
// 小智语音
filter.addAction( MogoReceiver.ACTION_VOICE_UI );
try {
context.getApplicationContext().registerReceiver( mAIAssistReceiver, filter );
Logger.i( TAG, "register voice receiver." );
} catch ( Exception e ) {
Logger.e( TAG, e, "error. " );
}
}
@Override
public void onMapLoaded() {
refreshCameraPosition();
}
private void initMapStatus() {
if ( mIsMapStatusOk ) {
return;
}
try {
float width = getMapCameraFactWidth();
float height = getMapCameraFactHeight();
mIsVertical = width < height;
Logger.i( TAG, "map status is vertical : " + mIsVertical );
mIsMapStatusOk = true;
} catch ( Exception e ) {
e.printStackTrace();
}
}
/**
* 地图视图对应的实际宽度
*
* @return
*/
private float getMapCameraFactWidth() {
try {
return Utils.calculateLineDistance( mCameraNorthEastPosition, new MogoLatLng( mCameraNorthEastPosition.lat, mCameraSouthWestPosition.lng ) );
} catch ( Exception e ) {
return 1000f;
}
}
/**
* 地图视图对应的实际高度
*
* @return
*/
private float getMapCameraFactHeight() {
try {
return Utils.calculateLineDistance( mCameraSouthWestPosition, new MogoLatLng( mCameraNorthEastPosition.lat, mCameraSouthWestPosition.lng ) );
} catch ( Exception e ) {
return 1000f;
}
}
/**
* 刷新视图范围坐标
*/
private void refreshCameraPosition() {
mCameraSouthWestPosition = mUiController.getCameraSouthWestPosition();
mCameraNorthEastPosition = mUiController.getCameraNorthEastPosition();
initMapStatus();
if ( mIsVertical ) {
float width = getMapCameraFactWidth();
Logger.i( TAG, "current zoom level width: %f m", width );
} else {
float height = getMapCameraFactHeight();
Logger.i( TAG, "current zoom level height: %f m", height );
}
}
@Override
public void onTouch( MotionEvent motionEvent ) {
switch ( motionEvent.getActionMasked() ) {
case MotionEvent.ACTION_DOWN:
if ( mLastZoomLevel == 0 ) {
mLastZoomLevel = mUiController.getZoomLevel();
Logger.i( TAG, "初始化缩放级别 为:%f", mLastZoomLevel );
}
break;
case MotionEvent.ACTION_UP:
break;
}
}
private void stopAutoRefreshStrategy() {
Logger.d( TAG, "stop auto refresh strategy" );
mHandler.removeMessages( ServiceConst.MSG_TYPE_REFRESH_DECREASE );
}
@Override
public void onPOIClick( MogoPoi poi ) {
}
@Override
public void onMapClick( MogoLatLng latLng ) {
}
@Override
public void onLockMap( boolean isLock ) {
}
@Override
public void onMapModeChanged( EnumMapUI ui ) {
}
@Override
public void onMapChanged( MogoLatLng latLng, float zoom, float tilt, float bearing ) {
if ( mIsCameraInited ) {
mLastZoomLevel = zoom;
mLastCustomRefreshCenterLocation = latLng;
mIsCameraInited = false;
return;
}
if ( mLastZoomLevel != zoom || mCameraNorthEastPosition == null ) {
refreshCameraPosition();
}
// 部分非用户操作导致地图视图变化:绘线、圈点等不触发用户刷新
// 消费状态
if ( mStatusManager.isUserInteracted() ) {
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
refreshCameraPosition();
return;
}
// v2x // adas 状态下不做任何操作
if ( mStatusManager.isADASShow() ) {
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
refreshCameraPosition();
return;
}
// 手动刷新触发
if ( mLastZoomLevel - zoom > mCustomRefreshStrategy.getZoomOutLevel() ) {
// 缩放级别缩小
notifyRefreshData( latLng, getQueryRadius(), mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
} else if ( mLastZoomLevel - zoom < 0 ) {
mLastZoomLevel = zoom;
} else if ( mLastZoomLevel == zoom ) {
// 手动平移
if ( invokeRefreshWhenTranslationByUser( latLng ) ) {
notifyRefreshData( latLng, getQueryRadius(), mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
}
}
}
private int getQueryRadius() {
if ( mIsVertical ) {
return ( ( int ) ( getMapCameraFactWidth() / 2 ) );
}
return ( ( int ) ( getMapCameraFactHeight() / 2 ) );
}
/**
* 平移地图刷新策略
*
* @return
*/
private boolean invokeRefreshWhenTranslationByUser( MogoLatLng latLng ) {
try {
float factor = 0.0f;
if ( mIsVertical ) {
factor = getMapCameraFactWidth();
} else {
factor = getMapCameraFactHeight();
}
if ( factor == 0.0f ) {
return false;
}
Logger.d( TAG, "invokeRefreshWhenTranslationByUsermLastCustomRefreshCenterLocation = %s, latLng = %s", mLastCustomRefreshCenterLocation, latLng );
float distance = Utils.calculateLineDistance( latLng, mLastCustomRefreshCenterLocation );
return distance > factor;
} catch ( Exception e ) {
Logger.e( TAG, e, "warming. " );
return false;
}
}
@Override
public void onLocationChanged( MogoLocation location ) {
if ( mStatusManager.isADASShow() ) {
return;
}
if ( mStatusManager.isSearchUIShow() ) {
return;
}
if ( location == null ) {
return;
}
// 自动刷新触发
final MogoLatLng point = new MogoLatLng( location.getLatitude(), location.getLongitude() );
if ( mLastAutoRefreshLocation == null ) {
mLastAutoRefreshLocation = point;
mLoopRequest = true;
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
return;
}
float distance = Utils.calculateLineDistance( mLastAutoRefreshLocation, point );
if ( distance > mAutoRefreshStrategy.getDistance() ) {
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, false );
mUiController.recoverLockMode();
mStatusManager.setUserInteractionStatus( TAG, true, false );
mUiController.changeZoom( 16.0f );
mLastAutoRefreshLocation = point;
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
}
/**
* 刷新数据
*/
private void notifyRefreshData( MogoLatLng latLng, int radius, RefreshCallback callback ) {
if ( mStatusManager.isSearchUIShow() ) {
return;
}
Logger.d( TAG, mAutoRefreshCallback == callback ? "触发自动刷新" : "触发手动刷新" );
int amount = mLastZoomLevel >= 10 ? 5 : 10;
mRefreshModel.refreshData( latLng, radius, amount, callback );
Logger.i( TAG, "刷新半径 = %d, 点 = %s, zoomLevel = %f, amount = %d", radius, latLng, mLastZoomLevel, amount );
}
@Override
public void onInitNaviFailure() {
}
@Override
public void onInitNaviSuccess() {
}
@Override
public void onNaviInfoUpdate( MogoNaviInfo naviinfo ) {
}
@Override
public void onStartNavi() {
}
@Override
public void onStopNavi() {
}
@Override
public void onStatusChanged( StatusDescriptor descriptor, boolean isTrue ) {
Logger.d( TAG, "状态发生改变---descriptor---" + descriptor + "----isTrue---" + isTrue );
switch ( descriptor ) {
case USER_INTERACTED:
if ( isTrue && !mRefreshRemainingTimeStatus ) {
mRefreshRemainingTimeStatus = true;
mRefreshRemainingTime += mAutoRefreshStrategy.getInterruptInterval();
Logger.i( TAG, "用户状态改变,自动刷新时间延时,%s ms后自动刷新", mRefreshRemainingTime );
}
break;
case SEARCH_UI:
if ( isTrue ) {
// 搜索时,不在自动刷新打点策略
stopAutoRefreshStrategy();
} else {
// 搜索后,打开打点策略
if ( mAutoRefreshCallback != null ) {
mAutoRefreshCallback.onSuccess();
}
}
break;
case V2X_UI:
try {
if ( isTrue ) {
// V2X_UI时不在自动刷新打点策略
stopAutoRefreshStrategy();
// 清除所有的打点信息记录
MarkerServiceHandler.getMapMarkerManager().alreadySmallMarker.clear();
} else {
// 主动刷新
refreshStrategy();
// V2X_UI后打开打点策略
if ( mAutoRefreshCallback != null ) {
mAutoRefreshCallback.onSuccess();
}
}
} catch ( Exception e ) {
e.printStackTrace();
}
break;
}
}
public void refreshStrategy() {
Logger.d( TAG, "move to center and refresh data." );
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, false );
mUiController.recoverLockMode();// 锁车代替移到中心点
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
@Override
public void onCalculateSuccess() {
}
@Override
public void onoCalculateFailed() {
}
@Override
public void onUpdateTraffic( MogoTraffic traffic ) {
if ( traffic != null ) {
Logger.i( TAG, "speed = %d, desc = %s", traffic.getSpeedLimit(), traffic.getDesc() );
// 发送当前限速到 adas
Intent intent = new Intent( "com.mogo.launcher.adas" );
intent.putExtra( "adas_speed_limit", traffic.getSpeedLimit() );
mContext.sendBroadcast( intent );
}
}
public IMogoMarkerClickListener getMarkerClickListener() {
return null;
}
@Override
public void onIntentReceived( String command, Intent intent ) {
if ( MogoReceiver.ACTIION_ADAS.equals( command ) ) {
if ( intent == null ) {
return;
}
int status = intent.getIntExtra( MogoReceiver.PARAM_ADAS_STATUS, 0 );
if (status == 1 ){
MarkerServiceHandler.getMapUIController().setLockZoom(15);
}else{
MarkerServiceHandler.getMapUIController().setLockZoom(16);
}
mStatusManager.setADASUIShow( ServiceConst.TYPE, status == 1 );
} else if ( Intent.ACTION_POWER_CONNECTED.equals( command ) ) {
mStatusManager.setAccStatus( ServiceConst.TYPE, true );
} else if ( Intent.ACTION_POWER_DISCONNECTED.equals( command ) ) {
mStatusManager.setAccStatus( ServiceConst.TYPE, false );
} else if ( MogoReceiver.ACTION_NWD_ACC.equals( command ) ) {
int state = intent.getByteExtra( MogoReceiver.PARAM_ACC_STATUS, ( byte ) 0 );
mStatusManager.setAccStatus( ServiceConst.TYPE, state == 1 );
} else if ( MogoReceiver.ACTION_VOICE_UI.equals( command ) ) {
String val = intent.getStringExtra( MogoReceiver.PARRAM_WAKE_STATUS );
if ( TextUtils.equals( val, MogoReceiver.VALUE_DISMISS ) ) {
mStatusManager.setVoiceUIShow( TAG, false );
} else if ( TextUtils.equals( val, MogoReceiver.VALUE_SHOW ) ) {
mStatusManager.setVoiceUIShow( TAG, true );
}
}
}
}

View File

@@ -25,12 +25,14 @@ import com.mogo.module.common.entity.MarkerShareMusic;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.MogoServiceProvider;
import com.mogo.module.service.MogoServices;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.service.Utils;
import com.mogo.module.service.datamanager.MogoDataHandler;
import com.mogo.module.service.utils.ViewUtils;
import com.mogo.service.cardmanager.IMogoCardChangedListener;
import com.mogo.service.connection.IMogoOnMessageListener;
import com.mogo.utils.ThreadPoolService;
import com.mogo.utils.logger.Logger;
import org.json.JSONArray;
@@ -102,9 +104,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener, IMogoOnMessag
mLastHighLightModule = moduleName;
if (!isACC_ON) {
isACC_ON = true;
MogoServiceProvider mMogoServiceProvider = (MogoServiceProvider) ARouter.getInstance().build(ServiceConst.PATH_REFRESH_STRATEGY).navigation();
// 刷新 Marker
mMogoServiceProvider.refreshStrategy();
MogoServices.getInstance().refreshStrategy();
}
}
});
@@ -587,13 +587,12 @@ public class MapMarkerManager implements IMogoMarkerClickListener, IMogoOnMessag
public void onMsgReceived(final MarkerResponse response) {
Logger.d(TAG, "接收到了地图大而全数据");
if (!MarkerServiceHandler.getMogoStatusManager().isSearchUIShow() && isACC_ON) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
ThreadPoolService.execute( new Runnable() {
@Override
public void run() {
drawMapMarker(response);
}
});
} );
}
}
}

View File

@@ -56,7 +56,7 @@ public class RefreshModel {
if (mRefreshApiService != null) {
final Map<String, Object> query = new ParamsProvider.Builder(mContext).build();
final RefreshBody refreshBody = new RefreshBody();
refreshBody.limit = 5;
refreshBody.limit = limit;
refreshBody.location = new RefreshBody.LatLon(latLng.lat, latLng.lng);
refreshBody.radius = radius;
refreshBody.dataType.add(ServiceConst.CARD_TYPE_CARS_CHATTING);