diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java index 9b2a255a28..1aa9a224eb 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java @@ -33,6 +33,7 @@ import com.mogo.module.common.MogoModulePaths; import com.mogo.module.common.map.MapCenterPointStrategy; import com.mogo.module.common.map.Scene; import com.mogo.module.service.intent.IntentHandlerFactory; +import com.mogo.module.service.launchercard.LauncherCardRefresher; import com.mogo.module.service.marker.MapMarkerManager; import com.mogo.module.service.network.RefreshCallback; import com.mogo.module.service.network.RefreshModel; @@ -303,6 +304,7 @@ public class MogoServices implements IMogoMapListener, restartAutoRefreshAtTime( 2_000L ); } mIsMainPageFirstResume = false; + LauncherCardRefresher.getInstance( mContext ).stop(); } else { unregisterInternalUnWakeupWords(); stopAutoRefreshStrategy(); @@ -397,7 +399,6 @@ public class MogoServices implements IMogoMapListener, if ( DebugConfig.isLaunchLocationService() ) { initLocationServiceProcess( context ); } - } private void initLocationServiceProcess( Context context ) { diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/intent/AccStatusIntentHandler.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/intent/AccStatusIntentHandler.java index 38a6de48b4..6bdcfa4e2e 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/intent/AccStatusIntentHandler.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/intent/AccStatusIntentHandler.java @@ -6,6 +6,7 @@ import android.content.Intent; import com.mogo.module.common.utils.CarSeries; import com.mogo.module.service.MarkerServiceHandler; import com.mogo.module.service.ServiceConst; +import com.mogo.module.service.launchercard.LauncherCardRefresher; import com.mogo.module.service.receiver.AccStatusReceiver; import com.mogo.utils.TipToast; import com.mogo.utils.logger.Logger; @@ -69,6 +70,11 @@ class AccStatusIntentHandler implements IntentHandler { } Logger.d( TAG, "acc status: %s", state ); MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, accOn ); + if ( accOn ) { + LauncherCardRefresher.getInstance( context ).start(); + } else { + LauncherCardRefresher.getInstance( context ).stop(); + } } } } diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefreshStrategy.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefreshStrategy.java new file mode 100644 index 0000000000..4c6f2db4c8 --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefreshStrategy.java @@ -0,0 +1,46 @@ +package com.mogo.module.service.launchercard; + +public class LauncherCardRefreshStrategy { + + private long interval; // 间隔时间 + private LauncherCardRefreshType type = LauncherCardRefreshType.OnlineCar; + + private LauncherCardRefreshStrategy next; + + public LauncherCardRefreshStrategy( long interval, LauncherCardRefreshStrategy next ) { + this.interval = interval; + this.next = next; + } + + public long getInterval() { + return interval; + } + + public LauncherCardRefreshType getType() { + if ( type == LauncherCardRefreshType.ExploreWay ) { + type = LauncherCardRefreshType.OnlineCar; + } else { + type = LauncherCardRefreshType.ExploreWay; + } + return type; + } + + public int getLimit() { + return type.limit; + } + + public String getDesc() { + return type.desc; + } + + public int getRadius() { + return 2_000; + } + + public LauncherCardRefreshStrategy getNext() { + if ( next == null ) { + return this; + } + return next; + } +} \ No newline at end of file diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefreshType.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefreshType.java new file mode 100644 index 0000000000..4cf2aa21d6 --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefreshType.java @@ -0,0 +1,15 @@ + +package com.mogo.module.service.launchercard; + +public enum LauncherCardRefreshType { + ExploreWay( 50, "道路事件" ), + OnlineCar( 20, "车友" ); + + public int limit; + public String desc; + + LauncherCardRefreshType( int limit, String desc ) { + this.limit = limit; + this.desc = desc; + } +} \ No newline at end of file diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefresher.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefresher.java new file mode 100644 index 0000000000..0128368112 --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/launchercard/LauncherCardRefresher.java @@ -0,0 +1,223 @@ +package com.mogo.module.service.launchercard; + +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.voice.AIAssist; +import com.mogo.commons.voice.VoicePreemptType; +import com.mogo.map.MogoLatLng; +import com.mogo.map.location.MogoLocation; +import com.mogo.module.common.entity.MarkerResponse; +import com.mogo.module.service.MarkerServiceHandler; +import com.mogo.module.service.R; +import com.mogo.module.service.network.RefreshCallback; +import com.mogo.module.service.network.RefreshModel; +import com.mogo.utils.AppUtils; +import com.mogo.utils.logger.Logger; +import com.mogo.utils.storage.SharedPrefsMgr; + +public +/** + * @author congtaowang + * @since 2020/8/17 + * + * 描述 + */ +class LauncherCardRefresher { + + private static final String TAG = "LauncherCardRefresher"; + + public static final String KEY_LauncherCardTipCounter = "LauncherCardTipCounter"; + public static final String KEY_LauncherCardTipLastTipTime = "LauncherCardTipLastTipTime"; + + + private static volatile LauncherCardRefresher sInstance; + + public static final int MSG_REFRESH = 2020; + public static final long ONE_MINUTE = 60 * 1000L; + + private LauncherCardRefresher( Context context ) { + mContext = context; + } + + public static LauncherCardRefresher getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( LauncherCardRefresher.class ) { + if ( sInstance == null ) { + sInstance = new LauncherCardRefresher( context ); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + private Object readResolve() { + // 阻止反序列化,必须实现 Serializable 接口 + return sInstance; + } + + private Handler mHandler = new Handler( Looper.getMainLooper() ) { + @Override + public void handleMessage( Message msg ) { + super.handleMessage( msg ); + if ( mRefreshStop ) { + return; + } + try { + handleRefreshMsg(); + } catch ( Exception e ) { + Logger.e( TAG, e, "error when refresh launcher card." ); + } + } + }; + + private final Context mContext; + private boolean mRefreshStop = true; + private boolean mStart = false; + private RefreshModel mRefreshModel; + private LauncherCardRefreshStrategy mRefreshStrategy = new LauncherCardRefreshStrategy( + 1 * ONE_MINUTE, + new LauncherCardRefreshStrategy( 1 * ONE_MINUTE, null ) + ); + + public void start() { + if ( DebugConfig.isLauncher() || DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_BYD ) { + return; + } + if ( mStart ) { + return; + } + + int counter = SharedPrefsMgr.getInstance( mContext ).getInt( KEY_LauncherCardTipCounter, 0 ); + if ( counter >= 5 ) { + long lastTipTime = SharedPrefsMgr.getInstance( mContext ).getLong( KEY_LauncherCardTipLastTipTime, 0L ); + if ( System.currentTimeMillis() - lastTipTime < /*10 * 24 * 60 **/ ONE_MINUTE ) { + stop(); + return; + } else { + SharedPrefsMgr.getInstance( mContext ).putInt( KEY_LauncherCardTipCounter, 0 ); + counter = 0; + SharedPrefsMgr.getInstance( mContext ).putLong( KEY_LauncherCardTipLastTipTime, 0L ); + } + } + mHandler.sendEmptyMessageDelayed( MSG_REFRESH, mRefreshStrategy.getInterval() ); + Logger.d( TAG, "start" ); + mRefreshStop = false; + mStart = true; + + SharedPrefsMgr.getInstance( mContext ).putInt( KEY_LauncherCardTipCounter, ++counter ); + SharedPrefsMgr.getInstance( mContext ).putLong( KEY_LauncherCardTipLastTipTime, System.currentTimeMillis() ); + } + + public void stop() { + mRefreshStop = true; + mStart = false; + mHandler.removeMessages( MSG_REFRESH ); + Logger.d( TAG, "stop" ); + } + + private void restart() { + if ( !mStart ) { + return; + } + mRefreshStop = false; + mHandler.removeMessages( MSG_REFRESH ); + mHandler.sendEmptyMessageDelayed( MSG_REFRESH, mRefreshStrategy.getInterval() ); + } + + private void handleRefreshMsg() { + if ( mRefreshModel == null ) { + mRefreshModel = new RefreshModel( mContext ); + } + MogoLocation location = MarkerServiceHandler.getMogoLocationClient().getLastKnowLocation(); + if ( location == null ) { + restart(); + return; + } + if ( mRefreshStrategy.getType() == LauncherCardRefreshType.ExploreWay ) { + mRefreshModel.refreshDataSync( new MogoLatLng( location.getLatitude(), location.getLongitude() ), + mRefreshStrategy.getRadius(), + mRefreshStrategy.getLimit(), + new RefreshCallback< MarkerResponse >() { + @Override + public void onSuccess( MarkerResponse response ) { + notifyLauncherCard( LauncherCardRefreshType.ExploreWay, response ); + mRefreshStrategy = mRefreshStrategy.getNext(); + restart(); + } + + @Override + public void onFail() { + mRefreshStrategy = mRefreshStrategy.getNext(); + restart(); + } + } ); + } else { + mRefreshModel.queryOnLineCarWithRoute( new MogoLatLng( location.getLatitude(), location.getLongitude() ), + false, + true, + mRefreshStrategy.getRadius(), + mRefreshStrategy.getLimit(), + new RefreshCallback< MarkerResponse >() { + @Override + public void onSuccess( MarkerResponse response ) { + notifyLauncherCard( LauncherCardRefreshType.OnlineCar, response ); + mRefreshStrategy = mRefreshStrategy.getNext(); + restart(); + } + + @Override + public void onFail() { + mRefreshStrategy = mRefreshStrategy.getNext(); + restart(); + } + } ); + } + } + + private void notifyLauncherCard( LauncherCardRefreshType type, MarkerResponse response ) { + if ( response == null || response.getResult() == null ) { + return; + } + String tts = mContext.getString( R.string.module_service_launcher_card_tips ); + String info = mContext.getString( R.string.module_service_launcher_card_info ); + if ( type == LauncherCardRefreshType.ExploreWay ) { + if ( response.getResult().getExploreWay() == null || response.getResult().getExploreWay().isEmpty() ) { + return; + } + speakTTS( String.format( tts, response.getResult().getExploreWay().size(), mRefreshStrategy.getDesc() ) ); + notifyLauncherCard( String.format( info, response.getResult().getExploreWay().size(), mRefreshStrategy.getDesc() ) ); + } else { + if ( response.getResult().getOnlineCar() == null || response.getResult().getOnlineCar().isEmpty() ) { + return; + } + speakTTS( String.format( tts, response.getResult().getOnlineCar().size(), mRefreshStrategy.getDesc() ) ); + notifyLauncherCard( String.format( info, response.getResult().getOnlineCar().size(), mRefreshStrategy.getDesc() ) ); + } + } + + private void speakTTS( String msg ) { + if ( AppUtils.isAppForeground( mContext ) ) { + return; + } + Logger.d( TAG, msg ); + AIAssist.getInstance( mContext ).speakTTSVoice( msg, VoicePreemptType.PREEMPT_TYPE_NEXT, null ); + } + + private void notifyLauncherCard( String info ) { + Intent intent = new Intent( "com.mogo.launcher.v2x" ); + intent.putExtra( "v2x_warning_type", 20000 ); + intent.putExtra( "v2x_warining_timeout", 20 ); + intent.putExtra( "v2x_warning_tts", "" ); + intent.putExtra( "v2x_warning_info", info ); + mContext.sendBroadcast( intent ); + } +} diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshApiService.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshApiService.java index ab6e8ff02d..27c5136805 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshApiService.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshApiService.java @@ -26,6 +26,10 @@ public interface RefreshApiService { @POST( "/yycp-launcherSnapshot/launcherSnapshot/querySnapshotAsync" ) Observable< BaseData > refreshData( @FieldMap Map< String, Object > parameters ); + @FormUrlEncoded + @POST( "/yycp-launcherSnapshot/launcherSnapshot/querySnapshotSync" ) + Observable< MarkerResponse > refreshDataSync( @FieldMap Map< String, Object > parameters ); + @FormUrlEncoded @POST( "/yycp-launcherSnapshot/user/queryOnLineCarWithRoute" ) Observable queryOnLineCarWithRoute(@FieldMap Map< String, Object > parameters ); diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshModel.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshModel.java index d87bec74a3..1634eaa782 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshModel.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/network/RefreshModel.java @@ -105,6 +105,51 @@ public class RefreshModel { } } + public void refreshDataSync( MogoLatLng latLng, int radius, int limit, final RefreshCallback callback ) { + if ( mRefreshApiService != null ) { + final Map< String, Object > query = new ParamsProvider.Builder( mContext ).build(); + final RefreshBody refreshBody = new RefreshBody(); + refreshBody.limit = limit; + refreshBody.location = new RefreshBody.LatLon( latLng.lat, latLng.lng ); + refreshBody.radius = radius; + refreshBody.dataType.add( ServiceConst.CARD_TYPE_ROAD_CONDITION ); + + String data = GsonUtil.jsonFromObject( refreshBody ); + query.put( "data", data ); + Logger.d( TAG, data ); + + + mRefreshApiService.refreshDataSync( query ) + .subscribeOn( Schedulers.io() ) + .observeOn( AndroidSchedulers.mainThread() ) + .subscribe( new SubscribeImpl< MarkerResponse >( RequestOptions.create( mContext ) ) { + @Override + public void onSuccess( MarkerResponse o ) { + super.onSuccess( o ); + if ( callback != null ) { + callback.onSuccess( o ); + } + } + + @Override + public void onError( Throwable e ) { + super.onError( e ); + if ( callback != null ) { + callback.onFail(); + } + } + + @Override + public void onError( String message, int code ) { + super.onError( message, code ); + if ( callback != null ) { + callback.onFail(); + } + } + } ); + } + } + /** * 查询车辆 及路线 * diff --git a/modules/mogo-module-service/src/main/res/values/strings.xml b/modules/mogo-module-service/src/main/res/values/strings.xml index e25a4adb00..edd40e08b0 100644 --- a/modules/mogo-module-service/src/main/res/values/strings.xml +++ b/modules/mogo-module-service/src/main/res/values/strings.xml @@ -1,4 +1,6 @@ mogo-module-service 辅助\n驾驶 + 你的周围有%d个%s,请点击查看,你也可以对我说打开蘑菇出行 + 周围有%d个%s