1.1.3 广告需求

This commit is contained in:
wangcongtao
2020-08-25 10:25:47 +08:00
parent b19d4e21e4
commit 8c7508e385
9 changed files with 398 additions and 46 deletions

View File

@@ -5,10 +5,13 @@ import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.network.ParamsProvider;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.commons.network.Utils;
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;
@@ -16,10 +19,26 @@ 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.module.service.network.ZhidaoApiService;
import com.mogo.module.service.network.ZhidaoRefreshModel;
import com.mogo.module.service.network.bean.LauncherCardAdvertisementData;
import com.mogo.utils.AppUtils;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.RequestOptions;
import com.mogo.utils.storage.SharedPrefsMgr;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public
/**
* @author congtaowang
@@ -37,13 +56,24 @@ class LauncherCardRefresher {
private static volatile LauncherCardRefresher sInstance;
// 刷新道路事件/车友
public static final int MSG_REFRESH = 2020;
public static final int MSG_TTS_TIP = 2021;
public static final long ONE_MINUTE = 15 * 1000L;
// 刷新卡片默认显示内容
public static final int MSG_REFRESH_DEFAULT_CARD = 2021;
// 刷新卡片广告
public static final int MSG_REFRESH_ADVERTISEMENT = 2022;
// 开始刷新广告数据
public static final int MSG_START_REFRESH_ADVERTISEMENT = 2023;
public static final long ONE_MINUTE = 60 * 1000L;
public static final long ONE_DAY = 24 * 60 * ONE_MINUTE;
private String mLaunchTTSText;
private LauncherCardAdvertisementData.LauncherCardAdvertisement mDefaultLauncherCardConfig;
private List< LauncherCardAdvertisementData.LauncherCardAdvertisement > mAdvertisements;
private LauncherCardRefresher( Context context ) {
mContext = context;
mRefreshModel = new RefreshModel( mContext );
mZhidaoRefreshModel = new ZhidaoRefreshModel( mContext );
}
public static LauncherCardRefresher getInstance( Context context ) {
@@ -81,11 +111,18 @@ class LauncherCardRefresher {
Logger.e( TAG, e, "error when refresh launcher card." );
}
break;
case MSG_TTS_TIP:
playTTS();
case MSG_REFRESH_DEFAULT_CARD:
renderDefaultLauncherCardConfig();
mRefreshStrategy = mRefreshStrategy.getNext();
restart();
break;
case MSG_REFRESH_ADVERTISEMENT:
int index = msg.arg1;// 当前广告索引
loopRenderAdvertisements( index );
break;
case MSG_START_REFRESH_ADVERTISEMENT:
startAdvertisementsStrategy();
break;
}
}
};
@@ -94,6 +131,7 @@ class LauncherCardRefresher {
private boolean mRefreshStop = true;
private boolean mStart = false;
private RefreshModel mRefreshModel;
private ZhidaoRefreshModel mZhidaoRefreshModel;
private LauncherCardRefreshStrategy mRefreshStrategy = new LauncherCardRefreshStrategy(
2 * ONE_MINUTE,
new LauncherCardRefreshStrategy(
@@ -103,7 +141,7 @@ class LauncherCardRefresher {
null,
MSG_REFRESH ),
MSG_REFRESH ),
MSG_TTS_TIP
MSG_REFRESH_DEFAULT_CARD
);
public void start() {
@@ -113,7 +151,17 @@ class LauncherCardRefresher {
if ( mStart ) {
return;
}
Logger.d( TAG, "start" );
mLaunchTTSText = mContext.getString( R.string.module_service_open_app_tip );
startExplorerWayStrategy();
// 延时一分钟加载数据已保证accOn之后网络恢复正常
mHandler.sendEmptyMessageDelayed( MSG_START_REFRESH_ADVERTISEMENT, ONE_MINUTE );
}
/**
* 道路事件和车友播报
*/
private void startExplorerWayStrategy() {
int counter = SharedPrefsMgr.getInstance( mContext ).getInt( KEY_LauncherCardTipCounter, 0 );
if ( counter >= 5 ) {
long lastTipTime = SharedPrefsMgr.getInstance( mContext ).getLong( KEY_LauncherCardTipLastTipTime, 0L );
@@ -127,7 +175,6 @@ class LauncherCardRefresher {
}
}
mHandler.sendEmptyMessageDelayed( mRefreshStrategy.getMsgType(), mRefreshStrategy.getInterval() );
Logger.d( TAG, "start" );
mRefreshStop = false;
mStart = true;
@@ -139,7 +186,6 @@ class LauncherCardRefresher {
mRefreshStop = true;
mStart = false;
mHandler.removeMessages( MSG_REFRESH );
mHandler.removeMessages( MSG_TTS_TIP );
Logger.d( TAG, "stop" );
}
@@ -149,14 +195,10 @@ class LauncherCardRefresher {
}
mRefreshStop = false;
mHandler.removeMessages( MSG_REFRESH );
mHandler.removeMessages( MSG_TTS_TIP );
mHandler.sendEmptyMessageDelayed( mRefreshStrategy.getMsgType(), mRefreshStrategy.getInterval() );
}
private void handleRefreshMsg() {
if ( mRefreshModel == null ) {
mRefreshModel = new RefreshModel( mContext );
}
MogoLocation location = MarkerServiceHandler.getMogoLocationClient().getLastKnowLocation();
if ( location == null ) {
restart();
@@ -177,7 +219,7 @@ class LauncherCardRefresher {
new RefreshCallback< MarkerResponse >() {
@Override
public void onSuccess( MarkerResponse response ) {
notifyLauncherCard( LauncherCardRefreshType.ExploreWay, response );
notifyLauncherCardExplorerWayChanged( LauncherCardRefreshType.ExploreWay, response );
mRefreshStrategy = mRefreshStrategy.getNext();
restart();
}
@@ -199,7 +241,7 @@ class LauncherCardRefresher {
new RefreshCallback< MarkerResponse >() {
@Override
public void onSuccess( MarkerResponse response ) {
notifyLauncherCard( LauncherCardRefreshType.OnlineCar, response );
notifyLauncherCardExplorerWayChanged( LauncherCardRefreshType.OnlineCar, response );
mRefreshStrategy = mRefreshStrategy.getNext();
restart();
}
@@ -213,7 +255,7 @@ class LauncherCardRefresher {
}
private boolean notifyLauncherCard( LauncherCardRefreshType type, MarkerResponse response ) {
private boolean notifyLauncherCardExplorerWayChanged( LauncherCardRefreshType type, MarkerResponse response ) {
if ( response == null || response.getResult() == null ) {
return false;
}
@@ -224,28 +266,30 @@ class LauncherCardRefresher {
return false;
}
int size = response.getResult().getExploreWay().size();
speakTTS( tts = String.format( tts, size, mRefreshStrategy.getDesc() ) );
notifyLauncherCard( String.format( info, size, mRefreshStrategy.getDesc() ), size, tts );
speakTTS( tts = String.format( tts, size, mRefreshStrategy.getDesc() ), true );
notifyLauncherCardExplorerWayChanged( String.format( info, size, mRefreshStrategy.getDesc() ), size, tts );
} else {
if ( response.getResult().getOnlineCar() == null || response.getResult().getOnlineCar().isEmpty() ) {
return false;
}
int size = response.getResult().getOnlineCar().size();
speakTTS( tts = String.format( tts, size, mRefreshStrategy.getDesc() ) );
notifyLauncherCard( String.format( info, size, mRefreshStrategy.getDesc() ), size , tts);
speakTTS( tts = String.format( tts, size, mRefreshStrategy.getDesc() ), true );
notifyLauncherCardExplorerWayChanged( String.format( info, size, mRefreshStrategy.getDesc() ), size, tts );
}
return true;
}
private void speakTTS( String msg ) {
if ( AppUtils.isAppForeground( mContext ) ) {
return;
private void speakTTS( String msg, boolean checkAppForeground ) {
if ( checkAppForeground ) {
if ( AppUtils.isAppForeground( mContext ) ) {
return;
}
}
Logger.d( TAG, msg );
AIAssist.getInstance( mContext ).speakTTSVoice( msg );
}
private void notifyLauncherCard( String info, int amount, String tts ) {
private void notifyLauncherCardExplorerWayChanged( String info, int amount, String tts ) {
Intent intent = new Intent( "com.mogo.launcher.v2x" );
intent.putExtra( "v2x_warning_type", "20000" );
intent.putExtra( "v2x_warining_timeout", 20 * 1000 );
@@ -256,11 +300,153 @@ class LauncherCardRefresher {
Logger.d( TAG, "发送广播到桌面卡片." );
}
private void playTTS() {
/**
* 1. 刷新默认卡片样式
* <p>
* 2. 播报默认卡片语音
*/
private void renderDefaultLauncherCardConfig() {
if ( mDefaultLauncherCardConfig != null ) {
long curr = System.currentTimeMillis();
if ( mDefaultLauncherCardConfig.endTime > curr && mDefaultLauncherCardConfig.startTime < curr ) {
Intent intent = new Intent( "com.mogo.launcher.v2x.card" );
intent.putExtra( "v2x_card_title", mDefaultLauncherCardConfig.name );
intent.putExtra( "v2x_card_icon", mDefaultLauncherCardConfig.filePath );
intent.putExtra( "v2x_card_content", mDefaultLauncherCardConfig.cardContent );
intent.putExtra( "v2x_card_button_name", mDefaultLauncherCardConfig.buttonContent );
intent.putExtra( "v2x_card_startTime", mDefaultLauncherCardConfig.startTime );
intent.putExtra( "v2x_card_endTime", mDefaultLauncherCardConfig.endTime );
mContext.sendBroadcast( intent );
Logger.d( TAG, "发送默认配置广播到桌面卡片." );
if ( !TextUtils.isEmpty( mDefaultLauncherCardConfig.content ) ) {
mLaunchTTSText = mDefaultLauncherCardConfig.content;
}
}
}
try {
AIAssist.getInstance( mContext ).speakTTSVoice( mContext.getString( R.string.module_service_open_app_tip ) );
speakTTS( mLaunchTTSText, true );
} catch ( Exception e ) {
e.printStackTrace();
}
startLoopRenderAdvertisements();
}
/**
* 请求广告数据
*/
private void startAdvertisementsStrategy() {
final Map< String, Object > query = new ParamsProvider.Builder( mContext )
.append( "modelType", 30 )
.build();
mZhidaoRefreshModel.getRefreshApiService().getCarAdvertisingList( query )
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() )
.subscribe( new SubscribeImpl< LauncherCardAdvertisementData >( RequestOptions.create( mContext ) ) {
@Override
public void onError( Throwable e ) {
super.onError( e );
Logger.e( TAG, e, "获取配置失败" );
}
@Override
public void onSuccess( LauncherCardAdvertisementData data ) {
super.onSuccess( data );
if ( data == null || data.result == null ) {
Logger.d( TAG, "carAdvertisingList is empty." );
return;
}
Logger.d( TAG, "获取配置成功" );
handleGotCarAdvertisingList( data.result );
}
@Override
public void onError( String message, int code ) {
super.onError( message, code );
Logger.e( TAG, "获取配置失败 msg = %s, code = %s", message, code );
}
} );
}
private void handleGotCarAdvertisingList( List< LauncherCardAdvertisementData.LauncherCardAdvertisement > data ) {
if ( data == null ) {
mAdvertisements = null;
return;
}
mAdvertisements = new ArrayList<>();
for ( LauncherCardAdvertisementData.LauncherCardAdvertisement launcherCardAdvertisement : data ) {
if ( launcherCardAdvertisement == null ) {
continue;
}
if ( launcherCardAdvertisement.cardType == LauncherCardAdvertisementData.TYPE_DEFAULT_CONFIG ) {
mDefaultLauncherCardConfig = launcherCardAdvertisement;
} else if ( launcherCardAdvertisement.cardType == LauncherCardAdvertisementData.TYPE_ACTIVITY ) {
long curr = System.currentTimeMillis();
if ( curr > launcherCardAdvertisement.startTime && curr < launcherCardAdvertisement.endTime ) {
mAdvertisements.add( launcherCardAdvertisement );
} else {
Logger.w( TAG, "广告已过期 %s", launcherCardAdvertisement.cardContent );
}
}
}
if ( !mAdvertisements.isEmpty() && mAdvertisements.size() > 1 ) {
LauncherCardAdvertisementData.LauncherCardAdvertisement[] sorted = new LauncherCardAdvertisementData.LauncherCardAdvertisement[mAdvertisements.size()];
Arrays.sort( sorted, ( ( o1, o2 ) -> {
return o1.sort < o2.sort ? 1 : ( o1.sort == o2.sort ? 0 : -1 );
} ) );
mAdvertisements = Arrays.asList( sorted );
}
}
/**
* 开始按策略展示广告
*/
private void startLoopRenderAdvertisements() {
if ( mAdvertisements == null || mAdvertisements.isEmpty() ) {
return;
}
Message msg = Message.obtain();
msg.what = MSG_REFRESH_ADVERTISEMENT;
msg.arg1 = 0;
mHandler.sendMessage( msg );
}
private void loopRenderAdvertisements( int index ) {
try {
index = index % mAdvertisements.size();
LauncherCardAdvertisementData.LauncherCardAdvertisement advertisement = mAdvertisements.get( index );
Message msg = Message.obtain();
msg.what = MSG_REFRESH_ADVERTISEMENT;
msg.arg1 = ++index;
mHandler.sendMessageDelayed( msg, advertisement.popupNum * ONE_MINUTE );
renderAdvertisement( advertisement );
} catch ( Exception e ) {
Logger.e( TAG, e, "loopRenderAdvertisements" );
}
}
/**
* 刷新广告
*/
private void renderAdvertisement( LauncherCardAdvertisementData.LauncherCardAdvertisement advertisement ) {
if ( advertisement == null ) {
return;
}
long curr = System.currentTimeMillis();
if ( advertisement.endTime > curr && advertisement.startTime < curr ) {
Intent intent = new Intent( "com.mogo.launcher.v2x.card" );
intent.putExtra( "v2x_card_title", advertisement.name );
intent.putExtra( "v2x_card_icon", advertisement.filePath );
intent.putExtra( "v2x_card_content", advertisement.cardContent );
intent.putExtra( "v2x_card_button_name", advertisement.buttonContent );
intent.putExtra( "v2x_card_startTime", advertisement.startTime );
intent.putExtra( "v2x_card_endTime", advertisement.endTime );
mContext.sendBroadcast( intent );
if ( !AppUtils.isAppForeground( mContext ) ) {
speakTTS( advertisement.content, true );
}
Logger.d( TAG, "发送广告配置广播到桌面卡片." );
}
}
}

View File

@@ -7,12 +7,10 @@ import com.mogo.module.service.network.bean.DemoUserInfoEntity;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.Single;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;
/**
* @author congtaowang
@@ -32,12 +30,11 @@ public interface RefreshApiService {
@FormUrlEncoded
@POST( "/yycp-launcherSnapshot/user/queryOnLineCarWithRoute" )
Observable<MarkerResponse> queryOnLineCarWithRoute(@FieldMap Map< String, Object > parameters );
Observable< MarkerResponse > queryOnLineCarWithRoute( @FieldMap Map< String, Object > parameters );
/**
* 查询演示车用户信息
*/
@GET("/yycp-launcherSnapshot/mock/getMockUserInfos")
@GET( "/yycp-launcherSnapshot/mock/getMockUserInfos" )
Observable< DemoUserInfoEntity > getMockUsers();
}

View File

@@ -47,6 +47,10 @@ public class RefreshModel {
this.mRefreshApiService = network.create( RefreshApiService.class, getNetHost() );
}
public RefreshApiService getRefreshApiService() {
return mRefreshApiService;
}
public static String getNetHost() {
switch ( DebugConfig.getNetMode() ) {
case DebugConfig.NET_MODE_DEV:

View File

@@ -0,0 +1,28 @@
package com.mogo.module.service.network;
import com.mogo.module.service.network.bean.LauncherCardAdvertisementData;
import java.util.Map;
import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.QueryMap;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 接口描述
*/
public interface ZhidaoApiService {
/**
* 获取桌面卡片配置
*
* @param parameters
* @return
*/
@GET( "/marketing/advertisingPosition/getCarAdvertisingList" )
Observable< LauncherCardAdvertisementData > getCarAdvertisingList( @QueryMap Map< String, Object > parameters );
}

View File

@@ -0,0 +1,66 @@
package com.mogo.module.service.network;
import android.content.Context;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.data.BaseData;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.network.ParamsProvider;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.commons.network.Utils;
import com.mogo.map.MogoLatLng;
import com.mogo.module.common.entity.MarkerResponse;
import com.mogo.module.service.ServiceConst;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.network.IMogoNetwork;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.RequestOptions;
import com.mogo.utils.network.utils.GsonUtil;
import java.util.Map;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 使用智道的域名
*/
public class ZhidaoRefreshModel {
private static final String TAG = "RefreshModel";
public static final String HOST_DEV = "http://carlife-test.zhidaohulian.com";
public static final String HOST_TEST = "http://carlife-test.zhidaohulian.com";
public static final String HOST_DEMO = "http://carlife-test.zhidaohulian.com";
public static final String HOST_PRODUCT = "https://api.zhidaohulian.com";
private final Context mContext;
private ZhidaoApiService mRefreshApiService;
public ZhidaoRefreshModel( Context context ) {
this.mContext = context;
IMogoNetwork network = ( IMogoNetwork ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_NETWORK ).navigation( context );
this.mRefreshApiService = network.create( ZhidaoApiService.class, getNetHost() );
}
public ZhidaoApiService getRefreshApiService() {
return mRefreshApiService;
}
public static String getNetHost() {
switch ( DebugConfig.getNetMode() ) {
case DebugConfig.NET_MODE_DEV:
return HOST_DEV;
case DebugConfig.NET_MODE_QA:
return HOST_TEST;
case DebugConfig.NET_MODE_DEMO:
return HOST_DEMO;
default:
return HOST_PRODUCT;
}
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.module.service.network.bean;
import com.mogo.commons.data.BaseData;
import java.util.List;
public
/**
* @author congtaowang
* @since 2020/8/24
*
* 描述
*/
class LauncherCardAdvertisementData extends BaseData {
// 启动展示
public static final int TYPE_DEFAULT_CONFIG = 1;
// 活动
public static final int TYPE_ACTIVITY = 2;
public List< LauncherCardAdvertisement > result;
/**
* 卡片名称 name
* 卡片类型 fileType 1-启动展示、2-活动播报
* 卡片样式 filePath
* 卡片文案 cardContent
* 按钮文案 url
* 语音文案 content
* 活动期限 是时间戳 ,还是标准时间 startTime endTime Date类型
* 播报频次间隔popupNum
* 活动展示顺序 sort
*/
public static class LauncherCardAdvertisement {
public String name;
public int cardType;
public String filePath;
public String cardContent;
public String buttonContent;
public String content;
public int sort;
public long startTime;
public long endTime;
public int popupNum; // 间隔时间:分钟
}
}