merge of gradle.pro

This commit is contained in:
unknown
2020-07-17 18:52:51 +08:00
465 changed files with 26116 additions and 248 deletions

4
.idea/gradle.xml generated
View File

@@ -12,8 +12,9 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/foudations" />
<option value="$PROJECT_DIR$/foudations/mogo-base-services-apk" />
<option value="$PROJECT_DIR$/foudations/mogo-base-services-sdk" />
<option value="$PROJECT_DIR$/foudations/mogo-commons" />
<option value="$PROJECT_DIR$/foudations/mogo-connection" />
<option value="$PROJECT_DIR$/foudations/mogo-utils" />
<option value="$PROJECT_DIR$/libraries" />
<option value="$PROJECT_DIR$/libraries/map-amap" />
@@ -46,6 +47,7 @@
<option value="$PROJECT_DIR$/modules/mogo-module-share" />
<option value="$PROJECT_DIR$/modules/mogo-module-splash" />
<option value="$PROJECT_DIR$/modules/mogo-module-splash-noop" />
<option value="$PROJECT_DIR$/modules/mogo-module-v2x" />
<option value="$PROJECT_DIR$/services" />
<option value="$PROJECT_DIR$/services/mogo-service" />
<option value="$PROJECT_DIR$/services/mogo-service-api" />

35
app/README.md Normal file
View File

@@ -0,0 +1,35 @@
# APP 壳
## 加载模块
## 初始化部分服务
## 定义 flavor
### basic 维度
产品形态:区别 applicationId定义服务加载
1. independent独立app作为普通 app 运行在系统
2. launcher作为 launcher 运行在系统
### product 维度
产品线,各个产品线引入不同服务,实现不同服务内容
1. f8xx: 分体机 - launcher
2. e8xx: E系列m4(2+32) - launcher
3. em4: E系列m4(2+32) - launcher
4. em3: E系列m3(2+32) - independent
5. em1: E系列m1(1+16) - independent
6. d8xx: D系列(2+32) - independent
7. d82x: D系列(1+16) - independent
8. byd: 比亚迪应用市场 - independent
### env 维度
1. online: 线上环境
2. qa: 测试环境
3. demo: 演示环境(大部分时候都是测试环境)
## 区分 flavor 功能引入

View File

@@ -25,7 +25,7 @@ android {
externalNativeBuild {
ndk {
// 设置支持的SO库架构
abiFilters 'armeabi-v7a'
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
}
}
@@ -82,8 +82,8 @@ android {
applicationId rootProject.ext.android.independentApplicationId
// 是否启动位置服务
buildConfigField 'boolean', 'LAUNCH_LOCATION_SERVICE', 'false'
// 是否使用自定义导航
buildConfigField 'boolean', 'USE_CUSTOM_NAVI', 'false'
// 是否使用高德sdk自定义导航
buildConfigField 'boolean', 'USE_CUSTOM_NAVI', 'true'
// 是否作为 launcher 运行
buildConfigField 'boolean', 'IS_LAUNCHER', 'false'
}
@@ -93,7 +93,7 @@ android {
applicationId rootProject.ext.android.launcherApplicationId
// 是否启动位置服务
buildConfigField 'boolean', 'LAUNCH_LOCATION_SERVICE', 'true'
// 是否使用自定义导航
// 是否使用高德sdk自定义导航
buildConfigField 'boolean', 'USE_CUSTOM_NAVI', 'true'
// 是否作为 launcher 运行
buildConfigField 'boolean', 'IS_LAUNCHER', 'true'
@@ -246,7 +246,6 @@ dependencies {
implementation rootProject.ext.dependencies.carcallprovider
implementation rootProject.ext.dependencies.carcall
implementation rootProject.ext.dependencies.moduleV2x
implementation rootProject.ext.dependencies.moduletanlu, {
exclude group: 'com.mogo.module', module: 'module-share'
}
@@ -268,6 +267,7 @@ dependencies {
implementation rootProject.ext.dependencies.modulemedia
implementation rootProject.ext.dependencies.moduleservice
implementation rootProject.ext.dependencies.modulesplash
implementation rootProject.ext.dependencies.moduleV2x
// 事件面板分渠道引用
d82xImplementation rootProject.ext.dependencies.moduleventpanelnoop
em1Implementation rootProject.ext.dependencies.moduleventpanelnoop
@@ -301,6 +301,7 @@ dependencies {
implementation project(':modules:mogo-module-media')
implementation project(':modules:mogo-module-service')
implementation project(':modules:mogo-module-splash')
implementation project(':modules:mogo-module-v2x')
// 事件面板分渠道引用
d82xImplementation project(':modules:mogo-module-event-panel-noop')
em1Implementation project(':modules:mogo-module-event-panel-noop')
@@ -320,6 +321,8 @@ dependencies {
f8xxImplementation project(':modules:mogo-module-left-panel-noop')
em3Implementation project(':modules:mogo-module-left-panel-noop')
}
apply from: "./functions/baseservices.gradle"
}
//android.applicationVariants.all { variant ->

1
app/functions/README.md Normal file
View File

@@ -0,0 +1 @@
# 不同渠道依赖的实现不一样需要各个渠道都去依赖各自需要的实现渠道太多导致build.gradle 文件臃肿可以通过分gradle文件方式减少臃肿

View File

@@ -0,0 +1,26 @@
// 基础服务仅比亚迪渠道用sdk方式实现其他都基于apk基础服务
project.dependencies {
if (Boolean.valueOf(RELEASE)) {
bydImplementation rootProject.ext.dependencies.mogobaseservicesdk
d82xImplementation rootProject.ext.dependencies.mogobaseserviceapk
em1Implementation rootProject.ext.dependencies.mogobaseserviceapk
d8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk
em4Implementation rootProject.ext.dependencies.mogobaseserviceapk
e8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk
e8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk
f8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk
em3Implementation rootProject.ext.dependencies.mogobaseserviceapk
} else {
bydImplementation project(':foudations:mogo-base-services-sdk')
d82xImplementation project(':foudations:mogo-base-services-apk')
em1Implementation project(':foudations:mogo-base-services-apk')
d8xxImplementation project(':foudations:mogo-base-services-apk')
em4Implementation project(':foudations:mogo-base-services-apk')
e8xxImplementation project(':foudations:mogo-base-services-apk')
f8xxImplementation project(':foudations:mogo-base-services-apk')
em3Implementation project(':foudations:mogo-base-services-apk')
}
}

View File

@@ -9,6 +9,8 @@ import com.auto.zhidao.logsdk.CrashSystem;
import com.bytedance.boost_multidex.BoostMultiDex;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.authorize.authprovider.invoke.AuthorizeConstant;
import com.mogo.module.carchatting.card.CallChatConstant;
import com.mogo.module.common.MogoModule;
@@ -19,8 +21,12 @@ import com.mogo.module.push.base.PushUIConstants;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.tanlu.constant.TanluConstants;
import com.mogo.module.v2x.V2XConst;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.service.passport.IMogoPassportManager;
import com.mogo.service.passport.IMogoTicketCallback;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.logger.LogLevel;
import com.mogo.utils.logger.Logger;
import com.zhidao.boot.persistent.lib.PersistentManager;
@@ -43,66 +49,79 @@ public class MogoApplication extends AbsMogoApplication {
super.onCreate();
// Crash 日志收集
final long start = System.currentTimeMillis();
CrashSystem crashSystem = CrashSystem.getInstance(this);
CrashSystem crashSystem = CrashSystem.getInstance( this );
crashSystem.init();
//设置debug模式日志不上传
crashSystem.setDebug(BuildConfig.DEBUG);
Logger.init(BuildConfig.DEBUG ? LogLevel.DEBUG : LogLevel.OFF);
crashSystem.setDebug( BuildConfig.DEBUG );
Logger.init( BuildConfig.DEBUG ? LogLevel.DEBUG : LogLevel.OFF );
// MogoModulePaths.addModule(new MogoModule(PATH_GUIDE_FRAGMENT, PATH_GUIDE_MODULE_NAME));
MogoModulePaths.addModule(new MogoModule(AuthorizeConstant.PATH_AGREEMENT_FRAGMENT, AuthorizeConstant.PATH_AGREEMENT_MODULE_NAME));
MogoModulePaths.addModule( new MogoModule( AuthorizeConstant.PATH_AGREEMENT_FRAGMENT, AuthorizeConstant.PATH_AGREEMENT_MODULE_NAME ) );
//运营位卡片,需要默认显示,放在第一个加载
if (DebugConfig.isLauncher()) {
MogoModulePaths.addModule(new MogoModule(MediaConstants.TAG, MediaConstants.MODULE_TYPE));
if ( DebugConfig.isLauncher() ) {
MogoModulePaths.addModule( new MogoModule( MediaConstants.TAG, MediaConstants.MODULE_TYPE ) );
}
MogoModulePaths.addModule(new MogoModule(CallChatConstant.PROVIDER, CallChatConstant.MODULE_NAME));
MogoModulePaths.addModule(new MogoModule(TanluConstants.TAG, TanluConstants.MODEL_NAME));
MogoModulePaths.addModule(new MogoModule(MogoServicePaths.PATH_SHARE, "ShareControl"));
MogoModulePaths.addModule( new MogoModule( CallChatConstant.PROVIDER, CallChatConstant.MODULE_NAME ) );
MogoModulePaths.addModule( new MogoModule( TanluConstants.TAG, TanluConstants.MODEL_NAME ) );
MogoModulePaths.addModule( new MogoModule( MogoServicePaths.PATH_SHARE, "ShareControl" ) );
MogoModulePaths.addModule(new MogoModule(EventPanelConstants.PATH_NAME,
EventPanelConstants.MODULE_NAME));
MogoModulePaths.addModule(new MogoModule(LeftPanelConst.PATH_NAME,
LeftPanelConst.MODULE_NAME));
MogoModulePaths.addModule( new MogoModule( EventPanelConstants.PATH_NAME,
EventPanelConstants.MODULE_NAME ) );
MogoModulePaths.addModule( new MogoModule( LeftPanelConst.PATH_NAME,
LeftPanelConst.MODULE_NAME ) );
MogoModulePaths.addBaseModule( new MogoModule( ServiceConst.PATH_REFRESH_STRATEGY, ServiceConst.PATH_REFRESH_STRATEGY ) );
MogoModulePaths.addBaseModule( new MogoModule( V2XConst.PATH_V2X_UI, V2XConst.PATH_V2X_UI ) );
MogoModulePaths.addModule(new MogoModule( PushUIConstants.PATH, PushUIConstants.NAME));
MogoModulePaths.addModule( new MogoModule( PushUIConstants.PATH, PushUIConstants.NAME ) );
if (!DebugConfig.isLauncher()) {
PersistentManager.getInstance().initManager(this);
Intent intent = new Intent(this, MogoMainService.class);
startService(intent);
if ( !DebugConfig.isLauncher() ) {
PersistentManager.getInstance().initManager( this );
Intent intent = new Intent( this, MogoMainService.class );
startService( intent );
}
Log.i("timer", "cost " + (System.currentTimeMillis() - start) + "ms");
Log.i( "timer", "cost " + ( System.currentTimeMillis() - start ) + "ms" );
}
private void initDebugConfig(){
DebugConfig.setNetMode(BuildConfig.NET_ENV);
DebugConfig.setDebug(BuildConfig.DEBUG);
DebugConfig.setAIType(BuildConfig.AIType);
DebugConfig.setLaunchLocationService(BuildConfig.LAUNCH_LOCATION_SERVICE);
DebugConfig.setUseCustomNavi(BuildConfig.USE_CUSTOM_NAVI);
DebugConfig.setLauncher(BuildConfig.IS_LAUNCHER);
private void initDebugConfig() {
DebugConfig.setNetMode( BuildConfig.NET_ENV );
DebugConfig.setDebug( BuildConfig.DEBUG );
DebugConfig.setAIType( BuildConfig.AIType );
DebugConfig.setLaunchLocationService( BuildConfig.LAUNCH_LOCATION_SERVICE );
DebugConfig.setUseCustomNavi( BuildConfig.USE_CUSTOM_NAVI );
DebugConfig.setLauncher( BuildConfig.IS_LAUNCHER );
DebugConfig.setActiveAIAssistFlag( BuildConfig.AI_ASSIST_ACTIVE_STAUTS );
DebugConfig.setCarMachineType(BuildConfig.CAR_MACHINE_TYPE);
DebugConfig.setCarMachineType( BuildConfig.CAR_MACHINE_TYPE );
}
@Override
protected void init() {
super.init();
IMogoSocketManager mMogoSocketManager = ARouter.getInstance().navigation(IMogoSocketManager.class);
if (mMogoSocketManager != null) {
mMogoSocketManager.init(getApplicationContext(), "com.mogo.launcher");
} else {
Logger.e(TAG, "init socket server error.");
}
UiThreadHandler.postDelayed( () -> {
final IMogoServiceApis apis = ARouter.getInstance().navigation( IMogoServiceApis.class );
apis.getSocketManagerApi( getApplicationContext() ).init( getApplicationContext(), "com.mogo.launcher" );
apis.getPassportManagerApi().requestTicket( new IMogoTicketCallback() {
@Override
public void onSuccess( String ticket ) {
Logger.d( TAG, "ticket = %s", ticket );
}
@Override
public void onError( int code, String msg ) {
Logger.w( TAG, "code = %s, msg = %s", code, msg );
}
} );
apis.getLocationInfoApi().start();
apis.getMapServiceApi().getSingletonLocationClient( getApplicationContext() ).addLocationListener( location -> {
apis.getLocationInfoApi().provideLocation( location );
} );
}, 2_000L );
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
BoostMultiDex.install(base);
protected void attachBaseContext( Context base ) {
super.attachBaseContext( base );
BoostMultiDex.install( base );
}
}

View File

@@ -4,12 +4,12 @@ ext {
android = [
// applicationId : "com.mogo.launcher",
// zhidadoApplicationId: "com.zhidao.launcher",
launcherApplicationId : "com.mogo.launcher",
independentApplicationId: "com.mogo.launcher.app",
compileSdkVersion : 28,
buildToolsVersion : "29.0.2",
minSdkVersion : 19,
targetSdkVersion : 22,
launcherApplicationId : "com.mogo.launcher",
independentApplicationId: "com.mogo.launcher.app",
compileSdkVersion : 28,
buildToolsVersion : "29.0.2",
minSdkVersion : 19,
targetSdkVersion : 22,
]
dependencies = [
@@ -21,6 +21,8 @@ ext {
androidxviewpager2 : "androidx.viewpager2:viewpager2:1.0.0",
androidxrecyclerview : "androidx.recyclerview:recyclerview:1.1.0",
androidxcardview : "androidx.cardview:cardview:1.0.0",
// flexbox
flexbox : 'com.google.android:flexbox:2.0.1',
// 测试
junit : "junit:junit:4.12",
androidxjunit : "androidx.test.ext:junit:1.1.0",
@@ -73,11 +75,6 @@ ext {
// rxjava2 with room
roomRxjava : "android.arch.persistence.room:rxjava2:1.1.1",
// leakcanary
leakcanary : 'com.squareup.leakcanary:leakcanary-android:1.5.4',
leakcanarynoop : 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4',
// material
material : 'com.google.android.material:material:1.0.0',
@@ -172,5 +169,9 @@ ext {
moduleleftpanelnoop : "com.mogo.module:module-left-panel-noop:${MOGO_MODULE_LEFT_PANEL_VERSION}",
// 闪屏页
modulesplash : "com.mogo.module:module-splash:${MOGO_MODULE_SPLASH_VERSION}",
// 基础服务实现
mogobaseservicesdk : "com.mogo.base:services-apk:${MOGO_BASE_SERVICES_SDK_VERSION}",
mogobaseserviceapk : "com.mogo.base:services-sdk:${MOGO_BASE_SERVICES_APK_VERSION}",
]
}

View File

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

View File

@@ -0,0 +1,7 @@
## 基实现功能
基础服务apk实现对应功能位置上报、长连接、passport
位置上报com.zhidao.locationinfo
长链com.zhidao.socketservice
passport

View File

@@ -0,0 +1,51 @@
apply plugin: 'com.android.library'
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"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation rootProject.ext.dependencies.arouter
api rootProject.ext.dependencies.socketsdk
api rootProject.ext.dependencies.socketsdkconnsvrprotoco
api rootProject.ext.dependencies.socketsdkprotobufjava
implementation rootProject.ext.dependencies.accountsdk
if (Boolean.valueOf(RELEASE)) {
implementation rootProject.ext.dependencies.mogoutils
implementation rootProject.ext.dependencies.mogocommons
implementation rootProject.ext.dependencies.mogoserviceapi
} else {
implementation project(":foudations:mogo-utils")
implementation project(":foudations:mogo-commons")
implementation project(":services:mogo-service-api")
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.base
POM_ARTIFACT_ID=services-apk
VERSION_CODE=1

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,26 @@
package com.mogo.base.services.apk;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith( AndroidJUnit4.class )
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals( "com.mogo.base.services.apk.test", appContext.getPackageName() );
}
}

View File

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

View File

@@ -0,0 +1,63 @@
package com.mogo.base.services.locationinfo;
import android.content.Context;
import androidx.annotation.Keep;
import com.mogo.map.location.MogoLocation;
import com.mogo.service.locationinfo.IMogoLocationInfoService;
import com.mogo.utils.logger.Logger;
public
/**
* @author congtaowang
* @since 2020/7/16
*
* 位置服务
*/
@Keep
class MogoLocationInfoServices implements IMogoLocationInfoService {
private static final String TAG = "MogoLocationInfoServices-apk";
private static volatile MogoLocationInfoServices sInstance;
private MogoLocationInfoServices() {
}
@Keep
public static MogoLocationInfoServices getInstance() {
if ( sInstance == null ) {
synchronized ( MogoLocationInfoServices.class ) {
if ( sInstance == null ) {
sInstance = new MogoLocationInfoServices();
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
@Override
public void provideLocation( MogoLocation location ) {
Logger.d( TAG, "apk - provideLocation" );
}
@Override
public void start() {
Logger.d( TAG, "apk - start" );
}
@Override
public void stop() {
Logger.d( TAG, "apk - stop" );
}
@Override
public void init( Context context ) {
Logger.d( TAG, "apk - init" );
}
}

View File

@@ -0,0 +1,87 @@
package com.mogo.base.services.passport;
import android.content.Context;
import androidx.annotation.Keep;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.storage.SpStorage;
import com.mogo.service.passport.IMogoPassportManager;
import com.mogo.service.passport.IMogoTicketCallback;
import com.mogo.utils.logger.Logger;
import com.zhidao.account.sdk.AccountClientManager;
import com.zhidao.account.sdk.callback.TicketInfoCallback;
import com.zhidao.account.sdk.network.NetEnvironManager;
public
/**
* @author congtaowang
* @since 2020/7/16
*
* 描述
*/
@Keep
class PassportManager implements IMogoPassportManager {
private static final String TAG = "PassportManager-apk";
private static volatile PassportManager sInstance;
private PassportManager(){}
@Keep
public static PassportManager getInstance(){
if( sInstance == null ){
synchronized( PassportManager.class ) {
if( sInstance == null ){
sInstance = new PassportManager();
}
}
}
return sInstance;
}
public synchronized void release(){
sInstance = null;
}
@Override
public void requestTicket( final IMogoTicketCallback callback ) {
getTicket( new TicketInfoCallback() {
@Override
public void onSuccess( String ticket ) {
Logger.d( TAG, "success" );
SpStorage.setTicket( ticket );
if ( callback != null ) {
callback.onSuccess( ticket );
}
}
@Override
public void onFailure( int code, String msg ) {
Logger.d( TAG, "fail" );
if ( callback != null ) {
callback.onError( code, msg );
}
}
} );
}
private static void getTicket( TicketInfoCallback callback ) {
if ( DebugConfig.isLauncher() ) {
AccountClientManager.getTicket( callback );
} else {
AccountClientManager.getAppTicket( callback );
}
}
@Override
public void init( Context context ) {
int mode = DebugConfig.getNetMode();
if ( mode == DebugConfig.NET_MODE_DEMO ) {
// 演示环境用 qa 的
mode = DebugConfig.NET_MODE_QA;
}
AccountClientManager.init( context.getApplicationContext(), mode, NetEnvironManager.OS_2C, "os2.0-launcher" );
}
}

View File

@@ -0,0 +1,224 @@
package com.mogo.base.services.socket;
import android.content.Context;
import androidx.annotation.Keep;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mogo.service.connection.IMogoMsgAckListener;
import com.mogo.service.connection.IMogoOnMessageListener;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.service.connection.MsgBody;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.utils.GsonUtil;
import com.zhidao.ptech.connsvr.commom.protocol.MogoCommon;
import com.zhidao.ptech.connsvr.protocol.MogoConnsvr;
import com.zhidao.socketsdk.manager.OnSocketAckCallback;
import com.zhidao.socketsdk.manager.OnSocketReceiveCallback;
import com.zhidao.socketsdk.manager.SocketConnManager;
import com.zhidao.socketsdk.manager.SocketConnManagerImpl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author congtaowang
* @since 2019-12-31
* <p>
* 长链实现:基于 netty
*/
@Keep
public class SocketManager implements IMogoSocketManager, OnSocketReceiveCallback, OnSocketAckCallback {
private static final String TAG = "SocketManager-apk";
public static final int MSG_PRODUCT_LINE = MogoCommon.Product.mogoBussiness_VALUE;
private static final int MSG_HEADER_TYPE = MogoConnsvr.MsgType.mogoMsgTypeDispatchSvrNoRspReq_VALUE;
private static volatile SocketManager sInstance;
private SocketManager( Context context ) {
mSocketConnManager = SocketConnManagerImpl.getInstance( context );
mSocketConnManager.addSocketMessageCallback( this );
mSocketConnManager.addSocketAckCallback( this );
}
@Keep
public static SocketManager getInstance( Context context ) {
if ( sInstance == null ) {
synchronized ( SocketManager.class ) {
if ( sInstance == null ) {
sInstance = new SocketManager( context );
}
}
}
return sInstance;
}
/**
* 管理消息分发
* <p>
* key - msgType
*/
private Map< Integer, List< IMogoOnMessageListener > > mListeners = new ConcurrentHashMap<>();
/**
* 管理消息回执
* <p>
* key - msgId
*/
private Map< Long, IMogoMsgAckListener > mAckListeners = new ConcurrentHashMap<>();
private SocketConnManager mSocketConnManager;
public static final int MAX_CAP = 64; //保证充足的容量应对非常延时的推送
private ArrayList< Long > mReceivedMsgId = new ArrayList<>( MAX_CAP );
private int mCurrentIndex = 0;
@Override
public void init( Context context, String appId ) {
if ( mSocketConnManager != null ) {
mSocketConnManager.init( appId );
}
}
@Override
public void onMessageReceived( byte[] content, long msgId ) {
try {
MogoConnsvr.Payload payload = MogoConnsvr.Payload.parseFrom( content );
int msgType = payload.getMsgType();
Logger.d( TAG, "received msg type = %d", msgType );
List< IMogoOnMessageListener > listeners = mListeners.get( msgType );
if ( listeners != null && !listeners.isEmpty() ) {
Iterator< IMogoOnMessageListener > iterator = listeners.iterator();
if ( msgId != 0 ) { //兼容老版本
if ( mReceivedMsgId.contains( msgId ) ) { // 避免消息重发
return;
}
cacheLastReceivedMsgId( msgId );
}
Object object = null;
while ( iterator.hasNext() ) {
IMogoOnMessageListener listener = iterator.next();
if ( object == null ) {
object = GsonUtil.objectFromJson( payload.getPayload().toStringUtf8(), listener.target() );
}
if ( listener != null ) {
Logger.d( TAG, "received msgId = %s, content = %s", msgId, payload.getPayload().toStringUtf8() );
listener.onMsgReceived( object );
}
}
}
} catch ( InvalidProtocolBufferException e ) {
Logger.e( TAG, e, "parse msg error." );
}
}
private void cacheLastReceivedMsgId( long msgId ) {
if ( msgId == 0 ) {
return;
}
synchronized ( this ){
mReceivedMsgId.add( mCurrentIndex % MAX_CAP, msgId );
mCurrentIndex++;
}
}
@Override
public void onAck( byte[] headerBytes, byte[] payloadBytes ) {
try {
MogoConnsvr.Header header = MogoConnsvr.Header.parseFrom( headerBytes );
int msgType = header.getMsgType();
String appId = header.getAppId();
int productLine = header.getProductLine();
long msgId = header.getMsgId();
IMogoMsgAckListener listener = mAckListeners.remove( msgId );
if ( listener != null ) {
listener.onAck( msgId );
}
Logger.d( TAG, "send message success: msgType = %d, appId = %s, productLine = %d", msgType, appId, productLine );
} catch ( InvalidProtocolBufferException e ) {
e.printStackTrace();
}
}
@Override
public void registerOnMessageListener( int msgType, IMogoOnMessageListener listener ) {
if ( mListeners.containsKey( msgType ) ) {
Logger.w( TAG, "msgType %d is exist.", msgType );
}
if ( !mListeners.containsKey( msgType ) ) {
mListeners.put( msgType, new ArrayList< IMogoOnMessageListener >() );
}
mListeners.get( msgType ).add( listener );
}
@Override
public void unregisterOnMessageListener( int msgType ) {
mListeners.remove( msgType );
}
@Override
public void unregisterOnMessageListener( int msgType, IMogoOnMessageListener listener ) {
if ( listener == null ) {
return;
}
if ( !mListeners.containsKey( msgType ) ) {
return;
}
List< IMogoOnMessageListener > listeners = mListeners.get( msgType );
if ( listeners != null && listeners.contains( listener ) ) {
listeners.remove( listener );
}
}
@Override
public void sendMsg( MsgBody body, IMogoMsgAckListener listener ) {
Logger.d( TAG, "sendMsg." );
if ( mSocketConnManager != null ) {
if ( mSocketConnManager.isConnected() ) {
Logger.d( TAG, "isConnected." );
final byte[] pb = convertToPBBytes( body.getMsgType(), objectToBytes( body.getContent() ) );
mSocketConnManager.sendPayload(
MSG_PRODUCT_LINE,
pb,
MSG_HEADER_TYPE,
body.isAck(),
body.getMsgId()
);
mAckListeners.put( body.getMsgId(), listener );
} else {
Logger.e( TAG, "sendMsg error, connect is lost." );
}
} else {
Logger.e( TAG, "sendMsg error, client is null." );
}
}
public byte[] objectToBytes( Object obj ) {
String jsonStr = GsonUtil.jsonFromObject( obj );
return jsonStr.getBytes();
}
private byte[] convertToPBBytes( int msgType, byte[] payloadBytes ) {
MogoConnsvr.Payload payloadData = MogoConnsvr.Payload.newBuilder()
.setMsgType( msgType )
.setPayload( ByteString.copyFrom( payloadBytes ) ).build();
return payloadData.toByteArray();
}
public synchronized void release() {
mListeners.clear();
mListeners = null;
sInstance = null;
}
@Override
public void init( Context context ) {
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.base.services.apk;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals( 4, 2 + 2 );
}
}

View File

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

View File

@@ -0,0 +1,3 @@
## sdk实现功能
脱离基础服务apk实现对应功能位置上报、长连接、passport

View File

@@ -0,0 +1,53 @@
apply plugin: 'com.android.library'
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"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation rootProject.ext.dependencies.arouter
// 上报位置
implementation 'com.zhidao.locupload:loc-upload-sdk:1.0.6'
// 长链
implementation 'com.zhidao.socket:built-in-socket:1.0.11'
// passport
implementation 'com.zhidao.tcloginsdk:tclogin:1.0.6'
annotationProcessor 'com.elegant.spi:compiler:1.0.3'
if (Boolean.valueOf(RELEASE)) {
implementation rootProject.ext.dependencies.mogoutils
implementation rootProject.ext.dependencies.mogocommons
implementation rootProject.ext.dependencies.mogoserviceapi
} else {
implementation project(":foudations:mogo-utils")
implementation project(":foudations:mogo-commons")
implementation project(":services:mogo-service-api")
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.connection
POM_ARTIFACT_ID=mogo-base-services-sdk
VERSION_CODE=1

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,26 @@
package com.mogo.base.services;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith( AndroidJUnit4.class )
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals( "com.mogo.base.services.test", appContext.getPackageName() );
}
}

View File

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

View File

@@ -0,0 +1,98 @@
package com.mogo.base.services.locationinfo;
import android.content.Context;
import androidx.annotation.Keep;
import com.elegant.spi.annotations.Service;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.map.location.MogoLocation;
import com.mogo.service.locationinfo.IMogoLocationInfoService;
import com.mogo.utils.logger.Logger;
import com.zhidao.locupload.LocEnvironment;
import com.zhidao.locupload.LocUploadConfig;
import com.zhidao.locupload.LocUploadManager;
import com.zhidao.locupload.Platform;
import com.zhidao.locupload.location.LocationServiceProvider;
public
/**
* @author congtaowang
* @since 2020/7/16
*
* 位置服务
*/
@Keep
class MogoLocationInfoServices implements IMogoLocationInfoService {
private static final String TAG = "MogoLocationInfoServices-sdk";
private static volatile MogoLocationInfoServices sInstance;
private MogoLocation mLocation;
private MogoLocationInfoServices() {
}
@Keep
public static MogoLocationInfoServices getInstance() {
if ( sInstance == null ) {
synchronized ( MogoLocationInfoServices.class ) {
if ( sInstance == null ) {
sInstance = new MogoLocationInfoServices();
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
@Override
public void provideLocation( MogoLocation location ) {
mLocation = location;
Logger.d(TAG, "sdk - provideLocation");
}
public MogoLocation getLocation() {
return mLocation;
}
@Override
public void start() {
LocUploadManager.getInstance().startUpload();
Logger.d(TAG, "sdk - start");
}
@Override
public void stop() {
LocUploadManager.getInstance().stopUpload();
Logger.d(TAG, "sdk - stop");
}
@Override
public void init( Context context ) {
LocUploadConfig.instance().
setAppId( "dataCrawler" ).
setContext( context.getApplicationContext() ).
setLocEnvironment( getEnvironment() ).
setLoggable( DebugConfig.isDebug() ).
setPlatform( Platform.car ).
setLocInterval( 2000L );
Logger.d(TAG, "sdk - init");
}
private LocEnvironment getEnvironment() {
switch ( DebugConfig.getNetMode() ) {
case 1:
return LocEnvironment.dev;
case 2:
case 4:
return LocEnvironment.qa;
case 3:
default:
return LocEnvironment.release;
}
}
}

View File

@@ -0,0 +1,133 @@
package com.mogo.base.services.locationinfo;
import com.elegant.spi.annotations.Service;
import com.zhidao.locupload.location.LocationServiceProvider;
public
/**
* @author congtaowang
* @since 2020/7/16
*
* 描述
*/
@Service( value = LocationServiceProvider.class )
class MogoLocationSource extends LocationServiceProvider {
@Override
public float getBearing() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getBearing();
}
return 0;
}
@Override
public float getAccuracy() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getAccuracy();
}
return 0;
}
@Override
public String getProvider() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getProvider();
}
return null;
}
@Override
public float getSpeed() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getSpeed();
}
return 0;
}
@Override
public double getAltitude() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getAltitude();
}
return 0;
}
@Override
public String getAdCode() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getAdCode();
}
return null;
}
@Override
public int getLocType() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getLocType();
}
return 0;
}
@Override
public double getLatitude() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getLatitude();
}
return 0;
}
@Override
public double getLongitude() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getLongitude();
}
return 0;
}
@Override
public long getTime() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getTime();
}
return 0;
}
@Override
public String getCityCode() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getCityCode();
}
return null;
}
@Override
public String getCityName() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getCityName();
}
return null;
}
@Override
public int getGpsAccuracyStatus() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getGpsAccuracyStatus();
}
return 0;
}
@Override
public int getSatellites() {
if ( MogoLocationInfoServices.getInstance().getLocation() != null ) {
return MogoLocationInfoServices.getInstance().getLocation().getSatellite();
}
return 0;
}
@Override
public int getCarStatus() {
// 常开状态
return 1;
}
}

View File

@@ -0,0 +1,101 @@
package com.mogo.base.services.passport;
import android.content.Context;
import androidx.annotation.Keep;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.storage.SpStorage;
import com.mogo.service.passport.IMogoPassportManager;
import com.mogo.service.passport.IMogoTicketCallback;
import com.mogo.utils.logger.Logger;
import com.zhidao.accountsdk.manager.CarPadClientManagerImpl;
import com.zhidao.accountsdk.manager.TicketInfoCallback;
import com.zhidao.accountsdk.network.NetEnvironManager;
import com.zhidao.tcloginsdk.ToCLoginManagerImpl;
public
/**
* @author congtaowang
* @since 2020/7/16
*
* 描述
*/
@Keep
class PassportManager implements IMogoPassportManager {
private static final String TAG = "PassportManager-sdk";
private Context mContext;
private static volatile PassportManager sInstance;
private PassportManager(){}
@Keep
public static PassportManager getInstance(){
if( sInstance == null ){
synchronized( PassportManager.class ) {
if( sInstance == null ){
sInstance = new PassportManager();
}
}
}
return sInstance;
}
public synchronized void release(){
sInstance = null;
}
@Override
public void requestTicket( final IMogoTicketCallback callback ) {
getTicket( new TicketInfoCallback() {
@Override
public void onSuccess( String ticket ) {
Logger.d( TAG, "success" );
SpStorage.setTicket( ticket );
if ( callback != null ) {
callback.onSuccess( ticket );
}
}
@Override
public void onFailure( int code ) {
Logger.d( TAG, "fail" );
if ( callback != null ) {
callback.onError( code, "error." );
}
}
} );
}
private void getTicket( TicketInfoCallback callback ) {
CarPadClientManagerImpl.getInstance( mContext ).getTicket( "os2.0-launcher", new TicketInfoCallback() {
@Override
public void onSuccess( String ticket ) {
if ( callback != null ) {
callback.onSuccess( ticket );
}
}
@Override
public void onFailure( int code ) {
if ( callback != null ) {
callback.onFailure( code );
}
}
} );
}
@Override
public void init( Context context ) {
mContext = context;
int mode = DebugConfig.getNetMode();
if ( mode == DebugConfig.NET_MODE_DEMO ) {
// 演示环境用 qa 的
mode = DebugConfig.NET_MODE_QA;
}
ToCLoginManagerImpl.getInstance( context ).setNetEnviron( mode );
ToCLoginManagerImpl.getInstance( context ).showLoginView();
}
}

View File

@@ -0,0 +1,227 @@
package com.mogo.base.services.socket;
import android.content.Context;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.service.connection.IMogoMsgAckListener;
import com.mogo.service.connection.IMogoOnMessageListener;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.service.connection.MsgBody;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.utils.GsonUtil;
import com.zhidao.locupload.Platform;
import com.zhidao.ptech.connsvr.protocol.MogoConnsvr;
import com.zhidao.socket.Callback;
import com.zhidao.socket.CallbackManager;
import com.zhidao.socket.Environment;
import com.zhidao.socket.SocketConfig;
import com.zhidao.socket.SocketMessageDispatcher;
import com.zhidao.socket.utils.RequestUtil;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public
/**
* @author congtaowang
* @since 2020/7/16
*
* 长链
*/
@Keep
class SocketManager implements IMogoSocketManager, Callback {
private static final String TAG = "SocketManager-sdk";
private static volatile SocketManager sInstance;
private String mAppId;
public SocketManager( Context context ) {
CallbackManager.getInstance().register( this );
}
@Keep
public static SocketManager getInstance( Context context ) {
if ( sInstance == null ) {
synchronized ( SocketManager.class ) {
if ( sInstance == null ) {
sInstance = new SocketManager( context );
}
}
}
return sInstance;
}
/**
* 管理消息分发
* <p>
* key - msgType
*/
private Map< Integer, List< IMogoOnMessageListener > > mListeners = new ConcurrentHashMap<>();
/**
* 管理消息回执
* <p>
* key - msgId
*/
private Map< Long, IMogoMsgAckListener > mAckListeners = new ConcurrentHashMap<>();
public static final int MAX_CAP = 64; //保证充足的容量应对非常延时的推送
private ArrayList< Long > mReceivedMsgId = new ArrayList<>( MAX_CAP );
private int mCurrentIndex = 0;
@Override
public void init( Context context, String appId ) {
mAppId = appId;
SocketConfig.instance()
.setAppContext( context.getApplicationContext() )
.setEnvironment( getEnvironment() )
.setClient( Platform.getClient( Platform.car ) )
.setAppId( appId )
.setDebug( DebugConfig.isDebug() );
SocketMessageDispatcher.getInstance().start( context );
}
private Environment getEnvironment() {
switch ( DebugConfig.getNetMode() ) {
case 1:
return Environment.dev;
case 2:
case 4:
return Environment.qa;
case 3:
default:
return Environment.release;
}
}
@Override
public void update( @NonNull CallbackManager manager, @NonNull byte[] content, String appId, long msgId ) {
try {
MogoConnsvr.Payload payload = MogoConnsvr.Payload.parseFrom( content );
int msgType = payload.getMsgType();
Logger.d( TAG, "received msg type = %d", msgType );
List< IMogoOnMessageListener > listeners = mListeners.get( msgType );
if ( listeners != null && !listeners.isEmpty() ) {
Iterator< IMogoOnMessageListener > iterator = listeners.iterator();
if ( msgId != 0 ) { //兼容老版本
if ( mReceivedMsgId.contains( msgId ) ) { // 避免消息重发
return;
}
cacheLastReceivedMsgId( msgId );
}
Object object = null;
while ( iterator.hasNext() ) {
IMogoOnMessageListener listener = iterator.next();
if ( object == null ) {
object = GsonUtil.objectFromJson( payload.getPayload().toStringUtf8(), listener.target() );
}
if ( listener != null ) {
Logger.d( TAG, "received msgId = %s, content = %s", msgId, payload.getPayload().toStringUtf8() );
listener.onMsgReceived( object );
}
}
}
} catch ( InvalidProtocolBufferException e ) {
Logger.e( TAG, e, "parse msg error." );
}
}
@Override
public void onAck( @NonNull CallbackManager manager, @NonNull byte[] headerBytes, byte[] content ) {
try {
MogoConnsvr.Header header = MogoConnsvr.Header.parseFrom( headerBytes );
int msgType = header.getMsgType();
String appId = header.getAppId();
int productLine = header.getProductLine();
long msgId = header.getMsgId();
IMogoMsgAckListener listener = mAckListeners.remove( msgId );
if ( listener != null ) {
listener.onAck( msgId );
}
Logger.d( TAG, "send message success: msgType = %d, appId = %s, productLine = %d", msgType, appId, productLine );
} catch ( InvalidProtocolBufferException e ) {
e.printStackTrace();
}
}
private void cacheLastReceivedMsgId( long msgId ) {
if ( msgId == 0 ) {
return;
}
synchronized ( this ) {
mReceivedMsgId.add( mCurrentIndex % MAX_CAP, msgId );
mCurrentIndex++;
}
}
@Override
public void registerOnMessageListener( int msgType, IMogoOnMessageListener listener ) {
if ( mListeners.containsKey( msgType ) ) {
Logger.w( TAG, "msgType %d is exist.", msgType );
}
if ( !mListeners.containsKey( msgType ) ) {
mListeners.put( msgType, new ArrayList< IMogoOnMessageListener >() );
}
mListeners.get( msgType ).add( listener );
}
@Override
public void unregisterOnMessageListener( int msgType ) {
mListeners.remove( msgType );
}
@Override
public void unregisterOnMessageListener( int msgType, IMogoOnMessageListener listener ) {
if ( listener == null ) {
return;
}
if ( !mListeners.containsKey( msgType ) ) {
return;
}
List< IMogoOnMessageListener > listeners = mListeners.get( msgType );
if ( listeners != null && listeners.contains( listener ) ) {
listeners.remove( listener );
}
}
@Override
public void sendMsg( MsgBody body, IMogoMsgAckListener listener ) {
Logger.d( TAG, "sendMsg." );
final byte[] pb = convertToPBBytes( body.getMsgType(), objectToBytes( body.getContent() ) );
RequestUtil.sendPayloadData( mAppId, 2, pb, 1, true, System.currentTimeMillis() );
}
public byte[] objectToBytes( Object obj ) {
String jsonStr = GsonUtil.jsonFromObject( obj );
return jsonStr.getBytes();
}
private byte[] convertToPBBytes( int msgType, byte[] payloadBytes ) {
MogoConnsvr.Payload payloadData = MogoConnsvr.Payload.newBuilder()
.setMsgType( msgType )
.setPayload( ByteString.copyFrom( payloadBytes ) ).build();
return payloadData.toByteArray();
}
public synchronized void release() {
mListeners.clear();
mListeners = null;
sInstance = null;
}
@Override
public void init( Context context ) {
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.base.services;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals( 4, 2 + 2 );
}
}

View File

@@ -1,9 +1,7 @@
package com.mogo.commons;
import android.app.Application;
import android.content.Context;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
@@ -20,11 +18,7 @@ import com.mogo.commons.network.X509TrustManagerImpl;
import com.mogo.commons.storage.SpStorage;
import com.mogo.utils.ThreadPoolService;
import com.mogo.utils.TipToast;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.NetConfig;
import com.zhidao.account.sdk.AccountClientManager;
import com.zhidao.account.sdk.callback.TicketInfoCallback;
import com.zhidao.account.sdk.network.NetEnvironManager;
import java.io.IOException;
import java.security.SecureRandom;
@@ -98,7 +92,6 @@ public class AbsMogoApplication extends Application {
private void asyncInit() {
ThreadPoolService.execute( () -> {
initNetConfig();
initAccountSdk();
// 初始化toast
// 初始化埋点
Analytics.getInstance().start( sApp );
@@ -109,37 +102,42 @@ public class AbsMogoApplication extends Application {
AnalyticsConfig.getInstance( sApp ).shouldLog( DebugConfig.isDebug() );
Devices.init( getApp() );
Devices.checkBindState();
asyncInitImpl();
} );
}
private static void initAccountSdk() {
int mode = DebugConfig.getNetMode();
if ( mode == DebugConfig.NET_MODE_DEMO ) {
// 演示环境用 qa 的
mode = DebugConfig.NET_MODE_QA;
}
AccountClientManager.init( sApp, mode, NetEnvironManager.OS_2C, "os2.0-launcher" );
getTicket( new TicketInfoCallback() {
@Override
public void onSuccess( String ticket ) {
SpStorage.setTicket( ticket );
Logger.w( TAG, "request ticket success" );
}
protected void asyncInitImpl(){
@Override
public void onFailure( int code, String msg ) {
Logger.w( TAG, "request ticket error code = %d, msg = %s", code, msg );
}
} );
}
private static void getTicket( TicketInfoCallback callback ) {
if ( DebugConfig.isLauncher() ) {
AccountClientManager.getTicket( callback );
} else {
AccountClientManager.getAppTicket( callback );
}
}
// private static void initAccountSdk() {
// int mode = DebugConfig.getNetMode();
// if ( mode == DebugConfig.NET_MODE_DEMO ) {
// // 演示环境用 qa 的
// mode = DebugConfig.NET_MODE_QA;
// }
// AccountClientManager.init( sApp, mode, NetEnvironManager.OS_2C, "os2.0-launcher" );
// getTicket( new TicketInfoCallback() {
// @Override
// public void onSuccess( String ticket ) {
// SpStorage.setTicket( ticket );
// Logger.w( TAG, "request ticket success" );
// }
//
// @Override
// public void onFailure( int code, String msg ) {
// Logger.w( TAG, "request ticket error code = %d, msg = %s", code, msg );
// }
// } );
// }
//
// private static void getTicket( TicketInfoCallback callback ) {
// if ( DebugConfig.isLauncher() ) {
// AccountClientManager.getTicket( callback );
// } else {
// AccountClientManager.getAppTicket( callback );
// }
// }
private static void initNetConfig() {

View File

@@ -7,6 +7,7 @@ import android.telephony.CellLocation;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -55,11 +56,16 @@ public class Utils {
public static final String GET = "get";
public static final String GSM_SERIAL = "gsm.serial";
public static final String BYD_SERIAL = "ro.serialno";
public static final String FOTA_VERSION = "ro.fota.version";
public static final String PROPERTIES = "android.os.SystemProperties";
public static String getSn() {
return getSystemProperties( GSM_SERIAL );
String sn = getSystemProperties( GSM_SERIAL );
if ( TextUtils.isEmpty( sn ) ) {
sn = getSystemProperties( BYD_SERIAL );
}
return sn;
}
public static String getFotaVersion() {

View File

@@ -1,76 +0,0 @@
package com.mogo.connection.socket;
import com.zhidao.ptech.connsvr.commom.protocol.MogoCommon;
import com.zhidao.ptech.connsvr.protocol.MogoConnsvr;
/**
* @author congtaowang
* @since 2019-12-31
* <p>
* 描述
*/
public class MsgBody {
private int mMsgType;
/**
* 服务端分发,业务线
*/
private int mProductLine = MogoCommon.Product.mogoBussiness_VALUE;
/**
*
*/
private int mHeaderType = MogoConnsvr.MsgType.mogoMsgTypeDispatchSvrNoRspReq_VALUE;
/**
* 是否回执
*/
private boolean mAck = false;
/**
* 消息ID
*/
private final long mMsgId = System.currentTimeMillis();
private Object mContent;
public MsgBody msgType( int msgType ) {
this.mMsgType = msgType;
return this;
}
public MsgBody ack( boolean ack ) {
this.mAck = ack;
return this;
}
public MsgBody content( Object content ) {
this.mContent = content;
return this;
}
public int getMsgType() {
return mMsgType;
}
public int getProductLine() {
return mProductLine;
}
public int getHeaderType() {
return mHeaderType;
}
public boolean ismAck() {
return mAck;
}
public long getMsgId() {
return mMsgId;
}
public Object getContent() {
return mContent;
}
}

View File

@@ -57,7 +57,7 @@ MOGO_MODULE_MAIN_INDEPENDENT_VERSION = 1.2.1.17
## 工程外部模块
# 探路
MOGO_MODULE_TANLU_VERSION=1.3.0.3-byd
MOGO_MODULE_TANLU_VERSION=1.3.0.4-byd
# 车聊聊
CARCHATTING_VERSION=1.4.1
# 车聊聊接口
@@ -69,15 +69,15 @@ MOGO_MODULE_GUIDESHOW_PROVIDER_VERSION=1.0.2-SNAPSHOT
# 在线车辆F
MOGO_MODULE_ONLINECAR_VERSION=1.0.3.2
# v2x
MOGO_MODULE_V2X_VERSION=1.3.0
MOGO_MODULE_V2X_VERSION=1.3.1
# 推送
MOGO_MODULE_PUSH_VERSION=1.1.5.6
MOGO_MODULE_PUSH_VERSION=1.1.5.7
MOGO_MODULE_PUSH_BASE_VERSION=1.1.5.5
MOGO_MODULE_PUSH_NOOP_VERSION=1.1.5.5
MOGO_MODULE_PUSH_NOOP_VERSION=1.1.5.6
# 广告资源位
MOGO_MODULE_AD_CARD_VERSION=1.0.1
# 探路上报和分享模块
TANLULIB_VERSION=1.3.0.3-byd
TANLULIB_VERSION=1.3.0.4-byd
MOGO_MODULE_EVENT_PANEL_VERSION = 1.0.0-SNAPSHOT
MOGO_MODULE_EVENT_PANEL_NOOP_VERSION = 1.0.0-SNAPSHOT
#左侧面板模块
@@ -96,6 +96,10 @@ MOGO_MODULE_OBU_VERSION = 1.2.1.10-SNAPSHOT
MOGO_MODULE_SPLASH_VERSION = 1.0.0-SNAPSHOT
MOGO_MODULE_SPLASH_NOOP_VERSION = 1.0.0-SNAPSHOT
# 基础服务实现passport、socket、location
MOGO_BASE_SERVICES_APK_VERSION = 1.0.0
MOGO_BASE_SERVICES_SDK_VERSION = 1.0.0
## 产品库必备配置
applicationId=com.mogo.launcer
applicationName=IntelligentPilot

View File

@@ -66,7 +66,7 @@ public abstract class AMapNaviListenerAdapter implements AMapNaviListener {
public void onGetNavigationText( String s ) {
mLastSpeakWord = s;
Logger.d( TAG, s );
TTSSpeaker.getInstance().speakTTS( s );
// TTSSpeaker.getInstance().speakTTS( s );
}
@Override

View File

@@ -11,6 +11,7 @@ import com.amap.api.navi.enums.AimLessMode;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.NaviLatLng;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.voice.AIAssist;
import com.mogo.map.MogoLatLng;
import com.mogo.map.impl.amap.AMapWrapper;
@@ -78,7 +79,7 @@ public class NaviClient implements IMogoNavi {
mContext = context;
mAMapNavi = AMapNavi.getInstance( context );
mAMapNavi.setEmulatorNaviSpeed( 120 );
mAMapNavi.setUseInnerVoice( false, true );
mAMapNavi.setUseInnerVoice( DebugConfig.isUseCustomNavi(), true );
mAMapNaviListener = new NaviListenerAdapter( context, mAMapNavi, this );
mAimlessModeListener = new AimlessModeListenerAdapter() {
};

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="module_main_entrance_fragment_container_marginLeft">635px</dimen>
<dimen name="module_main_header_fragment_container_marginLeft">366px</dimen>
</resources>

View File

@@ -0,0 +1 @@
# 应用列表 + Launcher 模式下的左侧导航按钮

View File

@@ -4,15 +4,11 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import com.mogo.module.apps.model.AppEnum;
import com.mogo.module.apps.model.AppEnumHelper;
import com.mogo.module.common.utils.CarSeries;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author congtaowang

View File

@@ -10,12 +10,14 @@ import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.module.apps.adapter.AppIndicatorAdapter;
import com.mogo.module.apps.anim.AnimWrapper;
import com.mogo.module.apps.applaunch.AppLauncher;
import com.mogo.module.apps.applaunch.BaseAppLauncher;
import com.mogo.module.apps.applaunch.InternalFunctionLauncher;
import com.mogo.module.apps.model.AppEnum;
import com.mogo.module.apps.model.AppInfo;
import com.mogo.module.apps.model.NavigatorApps;
import com.mogo.module.apps.view.OnAiAssistClickListener;
@@ -128,7 +130,15 @@ public class AppNavigatorFragment extends MvpFragment< AppNavigatorView, AppNavi
properties.put( "appname", appLabel );
}
if ( !TextUtils.equals( "全部应用", app.getName() ) ) {
properties.put( "appversion", CommonUtils.getVersionName( getContext(), app.getPackageName() ) );
if ( TextUtils.equals( "com.zhidao.music", app.getPackageName() ) ) {
if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.KwMusic.getPkg() ) ) {
properties.put( "appversion", CommonUtils.getVersionName( getContext(), AppEnum.KwMusic.getPkg() ) );
} else if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.QQMusic.getPkg() ) ) {
properties.put( "appversion", CommonUtils.getVersionName( getContext(), AppEnum.QQMusic.getPkg() ) );
}
} else {
properties.put( "appversion", CommonUtils.getVersionName( getContext(), app.getPackageName() ) );
}
} else {
properties.put( "appversion", CommonUtils.getVersionName( getContext() ) );
}

View File

@@ -14,5 +14,7 @@ public interface AppLaunchFilter {
void launch( Context context, AppInfo appInfo );
void launch( Context context, String pkg );
void destroy();
}

View File

@@ -21,15 +21,7 @@ public class AppLauncher extends BaseAppLauncher {
@Override
public void launch( Context context, AppInfo appInfo ) {
try {
if ( LaunchUtils.getLaunchIntentForPackage( context, appInfo.getPackageName() ) != null ) {
AppServiceHandler.getApis().getAdasControllerApi().closeADAS();
}
LaunchUtils.launchByPkg( context, appInfo.getPackageName() );
} catch ( Exception e ) {
Logger.e( TAG, e, "error." );
TipToast.shortTip( R.string.module_apps_str_no_app );
}
launch( context, appInfo.getPackageName() );
}
@Override

View File

@@ -1,5 +1,13 @@
package com.mogo.module.apps.applaunch;
import android.content.Context;
import com.mogo.module.apps.AppServiceHandler;
import com.mogo.module.apps.R;
import com.mogo.utils.LaunchUtils;
import com.mogo.utils.TipToast;
import com.mogo.utils.logger.Logger;
/**
* @author congtaowang
* @since 2020-02-09
@@ -8,6 +16,8 @@ package com.mogo.module.apps.applaunch;
*/
public abstract class BaseAppLauncher implements AppLaunchFilter {
private static final String TAG = "BaseAppLauncher";
private AppLaunchFilter mNext;
public AppLaunchFilter getNext() {
@@ -17,4 +27,17 @@ public abstract class BaseAppLauncher implements AppLaunchFilter {
public void setNext( AppLaunchFilter next ) {
this.mNext = next;
}
@Override
public void launch( Context context, String pkg ) {
try {
if ( LaunchUtils.getLaunchIntentForPackage( context, pkg ) != null ) {
AppServiceHandler.getApis().getAdasControllerApi().closeADAS();
}
LaunchUtils.launchByPkg( context, pkg );
} catch ( Exception e ) {
Logger.e( TAG, e, "error." );
TipToast.shortTip( R.string.module_apps_str_no_app );
}
}
}

View File

@@ -5,12 +5,17 @@ import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.module.apps.AppServiceHandler;
import com.mogo.module.apps.AppsListActivity;
import com.mogo.module.apps.R;
import com.mogo.module.apps.model.AppEnum;
import com.mogo.module.apps.model.AppInfo;
import com.mogo.module.common.map.CustomNaviInterrupter;
import com.mogo.utils.AppUtils;
import com.mogo.utils.LaunchUtils;
import com.mogo.utils.TipToast;
import com.mogo.utils.logger.Logger;
/**
* @author congtaowang
@@ -32,7 +37,7 @@ public class InternalFunctionLauncher extends BaseAppLauncher {
case "com.autonavi.amapauto":
if ( CustomNaviInterrupter.getInstance().interrupt() ) {
try {
LaunchUtils.launchByPkg( context, "com.autonavi.amapauto" );
launch( context, AppEnum.AUTO_NAVI.getPkg() );
} catch ( Exception e ) {
e.printStackTrace();
}
@@ -50,6 +55,23 @@ public class InternalFunctionLauncher extends BaseAppLauncher {
startActivity( context, appInfo, "com.zhidao.bluetooth.ui.MainActivity" );
}
break;
case "com.zhidao.music":
if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.KwMusic.getPkg() ) ) {
try {
launch( context, AppEnum.KwMusic.getPkg() );
} catch ( Exception e ) {
e.printStackTrace();
}
} else if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.QQMusic.getPkg() ) ) {
try {
launch( context, AppEnum.QQMusic.getPkg() );
} catch ( Exception e ) {
e.printStackTrace();
}
} else {
TipToast.shortTip( R.string.module_apps_str_no_app );
}
break;
default:
if ( getNext() != null ) {
getNext().launch( context, appInfo );

View File

@@ -16,7 +16,7 @@ public class NavigatorApps {
private static AppInfo app = new AppInfo( "高德地图", "com.autonavi.amapauto", "", 0, null, R.drawable.module_apps_ic_navigator_navi, 1 );
private static AppInfo app_ = new AppInfo( "高德地图", "com.autonavi.amapauto", "", 0, null, R.drawable.module_apps_ic_navigator_navi_disable, 1 );
// private static AppInfo app2 = new AppInfo( "音乐", "com.tencent.wecarflow", "", 0, null, R.drawable.module_apps_ic_navigator_media, 2 );
private static AppInfo app2 = new AppInfo( "酷我音乐", "cn.kuwo.kwmusiccar", "", 0, null, R.drawable.module_apps_ic_navigator_media, 2 );
private static AppInfo app2 = new AppInfo( "音乐", "com.zhidao.music", "", 0, null, R.drawable.module_apps_ic_navigator_media, 2 );
private static AppInfo app3 = new AppInfo( "车聊聊", "com.zhidao.imdemo", "", 0, null, R.drawable.module_apps_ic_navigator_im, 6 );
private static AppInfo app4 = new AppInfo( "全部应用", "com.mogo.launcher.applist", "", 0, null, R.drawable.module_apps_ic_navigator_applist, 4 );

View File

@@ -18,6 +18,9 @@
<item>com.iflytek.inputmethod.pad</item>
<item>com.nwd.tools.reboot</item>
<item>com.android.car.setting</item>
<item>com.zhidao.bootmanager</item>
<item>com.zhidao.services</item>
<item>com.android.settings</item>
</string-array>
<string-array name="module_apps_array_filter_packages">
<item>com.mogo.launcher</item>

View File

@@ -0,0 +1 @@
# Launcher 模式下分体机F系列的返回桌面悬浮按钮 和 "返回桌面"语音指令

View File

@@ -0,0 +1,11 @@
# 基础框架
## 基于 WindowManger.addView 方式实现的弹窗
## 大而全数据定义
## 地图中心点控制策略
## 自研车机类型判断
## 模块加载类

View File

@@ -1,9 +1,9 @@
# launcher头部模块
## 小智语音
## 通知
## 天气
## 时间
## 时间
## 入口按钮高德SDK导航控制

View File

@@ -6,6 +6,7 @@ import android.transition.AutoTransition;
import android.transition.Transition;
import android.transition.TransitionManager;
import android.util.ArrayMap;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
@@ -394,6 +395,11 @@ public class TopViewAnimHelper {
constraintSet.connect(naviBg.getId(), ConstraintSet.TOP,
R.id.module_entrance_id_top_motion_layout, ConstraintSet.TOP,
computeNaviMarginTop(params.height));
// 动态改变相关字体大小
tvNextDistance.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_textSize_small));
tvNextDistanceUnit.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_unit_textSize_small));
}
constraintSet.applyTo(topMotionLayout);
ivTurnIcon.getLayoutParams().height =
@@ -487,6 +493,9 @@ public class TopViewAnimHelper {
remainDistanceGroup.setVisibility(View.VISIBLE);
remainTimeGroup.setVisibility(View.VISIBLE);
arriveTimeGroup.setVisibility(View.VISIBLE);
tvNextDistance.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_textSize));
tvNextDistanceUnit.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_unit_textSize));
}
constraintSet.clone(topMotionLayout);
@@ -547,6 +556,9 @@ public class TopViewAnimHelper {
remainDistanceGroup.setVisibility(View.VISIBLE);
remainTimeGroup.setVisibility(View.VISIBLE);
arriveTimeGroup.setVisibility(View.VISIBLE);
tvNextDistance.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_textSize));
tvNextDistanceUnit.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_unit_textSize));
// 调整约束
constraintSet.clone(topMotionLayout);
constraintSet.clear(tvNextDistance.getId(), ConstraintSet.BOTTOM);
@@ -576,6 +588,8 @@ public class TopViewAnimHelper {
remainDistanceGroup.setVisibility(View.GONE);
remainTimeGroup.setVisibility(View.GONE);
arriveTimeGroup.setVisibility(View.GONE);
tvNextDistance.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_textSize_small));
tvNextDistanceUnit.setTextSize(TypedValue.COMPLEX_UNIT_PX,getDimen(R.dimen.module_ext_navi_info_panel_next_info_distance_unit_textSize_small));
// 调整约束
constraintSet.clone(topMotionLayout);
constraintSet.connect(tvNextDistance.getId(), ConstraintSet.BOTTOM,
@@ -655,7 +669,7 @@ public class TopViewAnimHelper {
}
private float getDimen(int resId) {
return (int) topMotionLayout.getContext().getResources().getDimension(resId);
return (int) topMotionLayout.getContext().getResources().getDimensionPixelSize(resId);
}
private int computeNaviMarginTop(int height) {

View File

@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<View
android:id="@+id/module_map_id_navi_bg"
android:layout_width="match_parent"
android:layout_height="@dimen/module_ext_navi_info_panel_height"
android:background="@drawable/module_ext_dw_navi_info_panel_bkg"
android:focusable="true"
android:clickable="true"
android:focusable="true"
app:layout_constraintHorizontal_bias="0.501"
app:layout_constraintLeft_toLeftOf="@id/module_entrance_id_top_container"
app:layout_constraintRight_toRightOf="@id/module_entrance_id_top_container"
@@ -88,17 +89,17 @@
android:id="@+id/module_map_id_remaining_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_657"
app:layout_constraintLeft_toLeftOf="@id/module_map_id_navi_bg"
android:layout_marginStart="@dimen/dp_627"
android:text="3599"
android:textColor="#F1F1F1"
android:textSize="@dimen/module_ext_remaining_distance_textSize"
android:textStyle="bold"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintBottom_toTopOf="@+id/module_map_id_remaining_distance_notice"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintLeft_toLeftOf="@id/module_map_id_navi_bg"
app:layout_constraintRight_toLeftOf="@+id/module_map_id_remaining_time"
app:layout_constraintTop_toTopOf="@id/module_map_id_navi_bg"
app:layout_constraintVertical_chainStyle="packed"/>
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/module_map_id_remaining_distance_unit"
@@ -114,12 +115,13 @@
android:id="@+id/module_map_id_remaining_distance_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toTopOf="@+id/module_map_id_remaining_distance_notice"
android:src="@drawable/module_ext_ic_navi_info1"
app:layout_constraintBottom_toBottomOf="@+id/module_map_id_remaining_distance_notice"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="@id/module_map_id_remaining_distance"
app:layout_constraintRight_toLeftOf="@+id/module_map_id_remaining_distance_notice"
android:src="@drawable/module_ext_ic_navi_info1" />
app:layout_constraintTop_toTopOf="@+id/module_map_id_remaining_distance_notice" />
<TextView
android:id="@+id/module_map_id_remaining_distance_notice"
android:layout_width="wrap_content"
@@ -128,8 +130,8 @@
android:textColor="#7FFFFFFF"
android:textSize="@dimen/module_ext_remaining_distance_unit_textSize"
app:layout_constraintBottom_toBottomOf="@+id/module_map_id_navi_bg"
app:layout_constraintRight_toRightOf="@+id/module_map_id_remaining_distance_unit"
app:layout_constraintLeft_toRightOf="@id/module_map_id_remaining_distance_icon"
app:layout_constraintRight_toRightOf="@+id/module_map_id_remaining_distance_unit"
app:layout_constraintTop_toBottomOf="@id/module_map_id_remaining_distance" />
<androidx.constraintlayout.widget.Group
@@ -146,11 +148,11 @@
android:textColor="#F1F1F1"
android:textSize="@dimen/module_ext_remaining_time_textSize"
android:textStyle="bold"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintTop_toTopOf="@id/module_map_id_navi_bg"
app:layout_constraintRight_toLeftOf="@+id/module_map_id_arrive_time"
app:layout_constraintBottom_toTopOf="@id/module_map_id_remaining_time_notice"
app:layout_constraintLeft_toRightOf="@+id/module_map_id_remaining_distance"
app:layout_constraintBottom_toTopOf="@id/module_map_id_remaining_time_notice" />
app:layout_constraintRight_toLeftOf="@+id/module_map_id_arrive_time"
app:layout_constraintTop_toTopOf="@id/module_map_id_navi_bg"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/module_map_id_remaining_time_unit"
@@ -161,17 +163,18 @@
android:textSize="@dimen/module_ext_remaining_time_unit_textSize"
app:layout_constraintBaseline_toBaselineOf="@id/module_map_id_remaining_time"
app:layout_constraintLeft_toRightOf="@id/module_map_id_remaining_time" />
<ImageView
android:id="@+id/module_map_id_remaining_time_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_ext_ic_navi_info2"
app:layout_constraintBottom_toBottomOf="@id/module_map_id_remaining_time_notice"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="@id/module_map_id_remaining_time"
app:layout_constraintRight_toLeftOf="@id/module_map_id_remaining_time_notice"
app:layout_constraintTop_toTopOf="@id/module_map_id_remaining_time_notice"
app:layout_constraintBottom_toBottomOf="@id/module_map_id_remaining_time_notice"
/>
app:layout_constraintTop_toTopOf="@id/module_map_id_remaining_time_notice" />
<TextView
android:id="@+id/module_map_id_remaining_time_notice"
android:layout_width="wrap_content"
@@ -195,26 +198,28 @@
android:id="@+id/module_map_id_arrive_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_76"
android:text="3599"
android:textColor="#F1F1F1"
android:textSize="@dimen/module_ext_arrive_time_textSize"
android:layout_marginEnd="@dimen/dp_96"
android:textStyle="bold"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintTop_toTopOf="@id/module_map_id_navi_bg"
app:layout_constraintRight_toRightOf="@id/module_map_id_navi_bg"
app:layout_constraintBottom_toTopOf="@id/module_map_id_arrive_time_notice"
app:layout_constraintLeft_toRightOf="@+id/module_map_id_remaining_time"
app:layout_constraintBottom_toTopOf="@id/module_map_id_arrive_time_notice"/>
app:layout_constraintRight_toRightOf="@id/module_map_id_navi_bg"
app:layout_constraintTop_toTopOf="@id/module_map_id_navi_bg"
app:layout_constraintVertical_chainStyle="packed" />
<ImageView
android:id="@+id/module_map_id_arrive_time_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/module_map_id_arrive_time"
app:layout_constraintTop_toTopOf="@+id/module_map_id_arrive_time_notice"
android:src="@drawable/module_ext_ic_navi_info3"
app:layout_constraintBottom_toBottomOf="@+id/module_map_id_arrive_time_notice"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="@id/module_map_id_arrive_time"
app:layout_constraintRight_toLeftOf="@+id/module_map_id_arrive_time_notice"
android:src="@drawable/module_ext_ic_navi_info3" />
app:layout_constraintTop_toTopOf="@+id/module_map_id_arrive_time_notice" />
<TextView
android:id="@+id/module_map_id_arrive_time_notice"
android:layout_width="wrap_content"
@@ -222,8 +227,8 @@
android:text="到达"
android:textColor="#7FFFFFFF"
android:textSize="@dimen/module_ext_remaining_distance_unit_textSize"
app:layout_constraintBottom_toBottomOf="@+id/module_map_id_navi_bg"
app:layout_constraintLeft_toRightOf="@id/module_map_id_arrive_time_icon"
app:layout_constraintRight_toRightOf="@id/module_map_id_arrive_time"
app:layout_constraintBottom_toBottomOf="@+id/module_map_id_navi_bg"
app:layout_constraintTop_toBottomOf="@id/module_map_id_arrive_time" />
</merge>

View File

@@ -89,9 +89,11 @@
<dimen name="module_ext_navi_info_panel_turn_icon_marginTop">24px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_marginTop">40px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_textSize">60px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_textSize_small">50px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_marginLeft">12px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_marginBottom">10px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_textSize">40px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_textSize_small">30px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_road_textSize">34px</dimen>
<dimen name="module_ext_navi_info_panel__arrive_destination_estimate_info_marginTop">24px</dimen>
<dimen name="module_ext_navi_info_panel__arrive_destination_estimate_info_textSize">28px</dimen>

View File

@@ -89,9 +89,11 @@
<dimen name="module_ext_navi_info_panel_turn_icon_marginTop">24px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_marginTop">40px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_textSize">60px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_textSize_small">50px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_marginLeft">12px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_marginBottom">10px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_textSize">40px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_textSize_small">30px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_road_textSize">34px</dimen>
<dimen name="module_ext_navi_info_panel__arrive_destination_estimate_info_marginTop">24px</dimen>
<dimen name="module_ext_navi_info_panel__arrive_destination_estimate_info_textSize">28px</dimen>

View File

@@ -91,9 +91,11 @@
<dimen name="module_ext_navi_info_panel_turn_icon_marginTop">13px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_marginTop">20px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_textSize">32px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_textSize_small">32px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_marginLeft">7px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_marginBottom">5px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_textSize">22px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_distance_unit_textSize_small">22px</dimen>
<dimen name="module_ext_navi_info_panel_next_info_road_textSize">18px</dimen>
<dimen name="module_ext_navi_info_panel__arrive_destination_estimate_info_marginTop">24px
</dimen>

View File

@@ -0,0 +1 @@
# GPS 轨迹模拟接口 Debug 实现

View File

@@ -0,0 +1 @@
# GPS 轨迹模拟接口 Release 实现

View File

@@ -0,0 +1,5 @@
# GPS 轨迹模拟接口抽象
## 常量定义
## 接口

View File

@@ -0,0 +1,18 @@
# 主模块
## 子模块加载管理
## 加载地图
## 事件分发
## service 后台服务
开启定位、加载基础服务模块v2x、刷新策略、事件上报模块、初始化 ADAS 服务
## 应用内浮窗管理:车聊聊、音乐等
## 顶部弹窗管理
## scheme 跳转管理

View File

@@ -52,7 +52,6 @@ dependencies {
api rootProject.ext.dependencies.mogoservice
api rootProject.ext.dependencies.moduleservice
api rootProject.ext.dependencies.moduleapps
api rootProject.ext.dependencies.mogoconnection
api rootProject.ext.dependencies.moduleextensions
api rootProject.ext.dependencies.mogomoduleback
} else {
@@ -64,7 +63,6 @@ dependencies {
api project(':services:mogo-service-api')
api project(':services:mogo-service')
api project(':modules:mogo-module-apps')
api project(':foudations:mogo-connection')
api project(':modules:mogo-module-extensions')
api project(':modules:mogo-module-back')
}

View File

@@ -43,12 +43,10 @@
<!--快捷操作浮层-->
<FrameLayout
android:id="@+id/module_main_id_entrance_fragment_container"
android:layout_width="@dimen/module_main_entrance_fragment_container_width"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="right"
android:paddingRight="@dimen/module_main_entrance_fragment_container_padding"
android:paddingBottom="@dimen/module_main_entrance_fragment_container_padding"
android:paddingTop="@dimen/module_main_entrance_fragment_container_padding" />
android:layout_marginLeft="@dimen/module_main_id_entrance_fragment_container_marginLeft"
android:padding="@dimen/module_main_entrance_fragment_container_padding" />
<FrameLayout
android:id="@+id/module_main_id_event_panel_fragment_container"

View File

@@ -0,0 +1,8 @@
# 地图模块
## 地图 Fragment
## 地图状态和小智交互部分
## 语音控制地图

View File

@@ -0,0 +1,16 @@
# 地图导航搜索模块
## poi 搜索
## 导航设置
## 路径规划
## 家和公司设置
## 地图选点
## 存储家和公司地址
## 分类搜索

View File

@@ -0,0 +1,10 @@
# 刷新策略 + 地图事件点刷新
## 刷新策略:自动刷新、手动刷新、刷新接口
## 大而全数据:道路事件
## 在线车辆数据
## 大部分广播的接口小智语音广播、acc 状态

View File

@@ -15,6 +15,9 @@ import com.mogo.commons.debug.DebugConfig;
import com.mogo.map.MogoLatLng;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.navi.MogoTraffic;
import com.mogo.map.search.geo.IMogoGeoSearch;
import com.mogo.map.search.geo.IMogoGeoSearchListener;
import com.mogo.map.search.geo.MogoGeocodeResult;
@@ -154,6 +157,49 @@ public class MockIntentHandler implements IntentHandler {
case 13: {
double lat = intent.getFloatExtra( "lat", 0.0f );
double lon = intent.getFloatExtra( "lon", 0.0f );
boolean real = intent.getBooleanExtra( "real", false );
MarkerServiceHandler.getRegisterCenter().registerMogoNaviListener( TAG, new IMogoNaviListener() {
@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 onCalculateSuccess() {
MarkerServiceHandler.getRegisterCenter().unregisterMogoNaviListener( TAG );
MarkerServiceHandler.getNavi().startNavi( real );
}
@Override
public void onoCalculateFailed() {
}
@Override
public void onUpdateTraffic( MogoTraffic traffic ) {
}
} );
MarkerServiceHandler.getNavi().naviTo( new MogoLatLng( lat, lon ) );
}
case 14: {

View File

@@ -96,6 +96,8 @@ public class UserDataMarkerInfoWindowAdapter implements IMogoInfoWindowAdapter {
mContent = mInfoWindowView.findViewById( R.id.module_service_id_content );
mTag = mInfoWindowView.findViewById( R.id.module_service_id_tag );
mCall = mInfoWindowView.findViewById( R.id.module_service_id_call );
mCall.setVisibility( DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_BYD ? View.GONE : View.VISIBLE );
}
try {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#000" />
<size
android:width="@dimen/dp_100"
android:height="@dimen/dp_100" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient android:startColor="#256BFF" android:endColor="#5CC1FF" android:angle="45" />
<corners android:radius="@dimen/dp_46" />
<padding android:bottom="@dimen/dp_12" android:left="@dimen/dp_75" android:top="@dimen/dp_12" android:right="@dimen/dp_75" />
</shape>
</item>
</selector>

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -2,32 +2,37 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/module_byd_splash" />
<TextView
android:id="@+id/tvByd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#fff"
android:drawableTop="@drawable/binli"
android:drawablePadding="10dp"
android:gravity="center"
android:text="比亚迪"
android:textSize="40sp"
android:background="@drawable/byd_enter_btn_bg"
android:textColor="#0D172C"
android:text="开启行程"
android:textSize="@dimen/dp_48"
android:layout_marginStart="@dimen/dp_182"
android:layout_marginBottom="@dimen/dp_251"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/tvCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="5"
android:textColor="#000"
android:textSize="30sp"
android:gravity="center"
android:textColor="#fff"
android:textSize="@dimen/dp_54"
android:layout_marginTop="@dimen/dp_48"
android:layout_marginEnd="@dimen/dp_60"
android:background="@drawable/byd_count_down_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

1
modules/mogo-module-v2x/.gitignore vendored Normal file
View File

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

View File

@@ -0,0 +1,25 @@
#### 项目介绍
本项目是V2X模块必须依附于Launcher进行集成使用无法单独使用且需要车机安装AutopilotADAS一起使用。
#### 项目结构
- adapter --- 展示视图适配
- alarm --- 提醒计算
- entity --- 数据实体
- listener --- Socket监听
- manager --- 管理工具绘制marker绘制连接线记录状态
- marker --- 地图marker视图适配
- network --- 网络请求
- scenario --- 场景,可以简单的理解为每一种弹窗是一种场景
- scene
- animation --- 场景动画 H5 推送下来的
- fatigue --- 疲劳驾驶
- help --- 自车故障求助
- livecar --- 直播场景H5推送的和道路事件预警的
- park --- 违章停车
- push --- 推送的演示场景,取快递、政府公告、顺风车、行人点赞
- road --- 道路事件预警
- seek --- 他人故障求助预警
- test --- 测试页面,一堆按钮,自己点击触发以上场景
- utils --- 工具类
- view --- 自定义视图
- voice --- 语音注册

View File

@@ -0,0 +1,74 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.alibaba.arouter'
apply plugin: 'android-aspectjx'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
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()]
}
}
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.tencent.liteavsdk:LiteAVSDK_Smart:7.2.8927'
implementation 'ch.hsr:geohash:1.4.0'
implementation rootProject.ext.dependencies.flexbox
implementation "com.zhidao.auto.lib:sqlite:0.1.1"
compileOnly rootProject.ext.dependencies.kotlinstdlibjdk7
compileOnly rootProject.ext.dependencies.androidxccorektx
compileOnly rootProject.ext.dependencies.androidxrecyclerview
compileOnly rootProject.ext.dependencies.mogomap
compileOnly rootProject.ext.dependencies.mogoutils
compileOnly rootProject.ext.dependencies.mogocommons
compileOnly rootProject.ext.dependencies.mogoservice
compileOnly rootProject.ext.dependencies.mogoserviceapi
compileOnly rootProject.ext.dependencies.modulecommon
compileOnly rootProject.ext.dependencies.moduleservice
compileOnly rootProject.ext.dependencies.androidxappcompat
compileOnly rootProject.ext.dependencies.androidxconstraintlayout
compileOnly rootProject.ext.dependencies.arouter
compileOnly rootProject.ext.dependencies.carcallprovider
compileOnly rootProject.ext.dependencies.carcall
annotationProcessor rootProject.ext.dependencies.aroutercompiler
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,2 @@
-keep class com.tencent.** { *; }
-keep com.mogo.module.v2x.entity.** { *; }

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.module
POM_ARTIFACT_ID=module-v2x
VERSION_CODE=1

View File

@@ -0,0 +1,23 @@
# 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
-keep class com.tencent.* { *; }
-keep class com.mogo.module.v2x.entity.* { *; }

View File

@@ -0,0 +1,26 @@
package com.mogo.module.blackbox;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.mogo.module.blackbox.test", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.module.v2x">
<application>
<receiver android:name=".receiver.SceneBroadcastReceiver">
<intent-filter>
<action android:name="com.v2x.scene_handler_broadcast" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -0,0 +1,34 @@
package com.mogo.module.v2x;
import androidx.annotation.Keep;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/17 7:35 PM
* desc : 对外服务模块路径
* version: 1.0
* 使用方式:
* Arouter.getInstance().path("").navigate()
*/
@Keep
public class MoGoV2XServicePaths {
/**
* V2X 状态管理
*/
@Keep
public static final String PATH_V2X_STATUS_MANAGER = "/v2xStatusManager/api";
/**
* V2X 道路事件POI点
*/
@Keep
public static final String PATH_V2X_MARKER_MANAGER = "/v2xMarkerManager/api";
/**
* V2X 道路事件与车辆的连接线
*/
@Keep
public static final String PATH_V2X_POLYLINE_MANAGER = "/v2xPolylineManager/api";
}

View File

@@ -0,0 +1,107 @@
package com.mogo.module.v2x;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-2114:10
* desc : V2X使用到的常量
* version: 1.0
*/
public class V2XConst {
/**
* 类型
*/
public static final String MODULE_NAME = "V2X_UI";
/**
* V2X模块地址
*/
public static final String PATH_V2X_UI = "/v2x/ui";
public static final String SEEK_HELP_TIME = "seek_help_time";
/**
* V2X 场景广播 Action
*/
public static final String BROADCAST_SCENE_HANDLER_ACTION = "com.v2x.scene_handler_broadcast";
public static final String BROADCAST_SCENE_EXTRA_KEY = "V2XMessageEntity";
public static final String BROADCAST_SCENE_ACTION = "com.v2x.scene_local_broadcast";
public static final String V2X_ACC_ON_TIME_STR = "v2x_acc_on_time_str";
public static final String V2X_ACC_OFF_TIME_STR = "v2x_acc_off_time_str";
public static final String V2X_STRATEGY_PUSH = "v2x_strategy_push";
public static final int STATE_ERROR = -1;
public static final int STATE_IDLE = 0;
public static final int STATE_PREPARING = 1;
public static final int STATE_PREPARED = 2;
public static final int STATE_PLAYING = 3;
public static final int STATE_PAUSED = 4;
public static final int STATE_PLAYBACK_COMPLETED = 5;
public static final int STATE_SEEKING = 6;
/**
* V2X 埋点
*/
public static final String V2X_ROAD_SHOW = "v2x_road_show";
public static final String V2X_ROAD_EVET = "v2x_road_event";
/**
* V2X 道路事件操作类型
*/
public static final String V2X_ROAD_ZAN = "1";
public static final String V2X_ROAD_CHAT = "2";
public static final String V2X_ROAD_VIDEO = "3";
public static final String V2X_ROAD_NAVI = "4";
public static final String V2X_ROAD_REPORT_RIGHT = "5";
public static final String V2X_ROAD_REPORT_ERROR = "6";
/**
* V2X 地图上发出警告的POI
*/
public static final String V2X_ILLEGAL_PARK_POI = "V2X_ILLEGAL_PARK_POI";
/**
* V2X 地图上发出警告的POI
*/
public static final String V2X_EVENT_ALARM_POI = "V2X_EVENT_ALARM_POI";
/**
* V2X 探路数据
*/
public static final String V2X_CARD_TYPE_ROAD_CONDITION = "V2X_CARD_TYPE_ROAD_CONDITION";
/**
* V2X 用户数据
*/
public static final String V2X_CARD_TYPE_USER_DATA = "V2X_CARD_TYPE_USER_DATA";
/**
* V2X 新鲜事
*/
public static final String V2X_CARD_TYPE_NOVELTY = "V2X_CARD_TYPE_NOVELTY";
/**
* V2X 特殊车辆
*/
public static final String V2X_MARKER_SPECIAL_CAR = "V2X_MARKER_SPECIAL_CAR";
/**
* V2X 可直播车辆
*/
public static final String V2X_MARKER_LIVE_CAR = "V2X_MARKER_LIVE_CAR";
/**
* V2X 取快递
*/
public static final String V2X_MARKER_EXPRESS = "V2X_MARKER_EXPRESS";
/**
* V2X 顺风车
*/
public static final String V2X_MARKER_TAXI = "V2X_MARKER_TAXI";
/**
* V2X 政府推送消息
*/
public static final String V2X_MARKER_GOVERNMENT = "V2X_MARKER_GOVERNMENT";
}

View File

@@ -0,0 +1,139 @@
package com.mogo.module.v2x;
import android.content.Intent;
import android.text.TextUtils;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerUserInfo;
import com.mogo.module.v2x.entity.net.V2XDemoUserInfoRes;
import com.mogo.module.v2x.network.V2XRefreshCallback;
import com.mogo.module.v2x.utils.ChartingUtil;
import com.mogo.module.v2x.voice.V2XVoiceConstants;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.utils.logger.Logger;
import java.util.List;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/28 12:24 PM
* desc : 演示DEMO管理
* version: 1.0
*/
public class V2XDemoManager {
private List<V2XDemoUserInfoRes.ResultBean.UserListBean> userListBeanList;
private V2XDemoUserInfoRes.ResultBean.UserListBean mV2XDemoUserInfoEntity1;
private V2XDemoUserInfoRes.ResultBean.UserListBean mV2XDemoUserInfoEntity2;
private V2XDemoUserInfoRes.ResultBean.UserListBean mV2XDemoUserInfoEntity3;
private static V2XDemoManager mV2XDemoManager;
private V2XDemoManager() {
}
public static V2XDemoManager getInstance() {
if (mV2XDemoManager == null) {
synchronized (V2XDemoManager.class) {
if (mV2XDemoManager == null) {
mV2XDemoManager = new V2XDemoManager();
}
}
}
return mV2XDemoManager;
}
public void initData() {
// 获取演示车辆信息
V2XServiceManager
.getV2XRefreshModel()
.getMockUserInfos(new V2XRefreshCallback<V2XDemoUserInfoRes>() {
@Override
public void onSuccess(V2XDemoUserInfoRes result) {
userListBeanList = result.getResult().getUserList();
Logger.w(MODULE_NAME, "V2X演示用户数据" + userListBeanList);
for (V2XDemoUserInfoRes.ResultBean.UserListBean userListBean : userListBeanList) {
switch (userListBean.getSceneType()) {
case "1":
mV2XDemoUserInfoEntity1 = userListBean;
break;
case "2":
mV2XDemoUserInfoEntity2 = userListBean;
break;
case "3":
mV2XDemoUserInfoEntity3 = userListBean;
break;
}
}
// 呼叫前方车辆
V2XVoiceManager.INSTANCE.registerWakeCmd(
V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR,
(String command, Intent intent) -> {
String dataStr = intent.getStringExtra("data");
Logger.w(MODULE_NAME, "mData。。。。" + dataStr);
if (!TextUtils.isEmpty(dataStr)) {
if (dataStr.contains("address")) {
roadCallChart(mV2XDemoUserInfoEntity2);
}
} else {
roadCallChart(mV2XDemoUserInfoEntity1);
}
}
);
}
@Override
public void onFail(String msg) {
}
});
}
public void release() {
// 呼叫前方车辆
V2XVoiceManager.INSTANCE.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR);
}
/**
* 打电话
*/
private void roadCallChart(V2XDemoUserInfoRes.ResultBean.UserListBean mV2XDemoUserInfoEntity) {
Logger.w(MODULE_NAME, "正在拨打电话。。。。" + mV2XDemoUserInfoEntity);
try {
if (mV2XDemoUserInfoEntity != null) {
MarkerUserInfo mUserInfo = new MarkerUserInfo();
MarkerLocation location = new MarkerLocation();
location.setLon(mV2XDemoUserInfoEntity.getLocation().getLon());
location.setLat(mV2XDemoUserInfoEntity.getLocation().getLat());
mUserInfo.setSn(mV2XDemoUserInfoEntity.getUserInfo().getSn());
mUserInfo.setUserHead(mV2XDemoUserInfoEntity.getUserInfo().getUserHead());
mUserInfo.setUserName(mV2XDemoUserInfoEntity.getUserInfo().getUserName());
mUserInfo.setGender(mV2XDemoUserInfoEntity.getUserInfo().getGender());
mUserInfo.setAge(mV2XDemoUserInfoEntity.getUserInfo().getAge());
ChartingUtil.callChatting(mUserInfo, location);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 1-拨打前方车辆,
public V2XDemoUserInfoRes.ResultBean.UserListBean getV2XDemoUserInfoEntity1() {
return mV2XDemoUserInfoEntity1;
}
// 2-拨打中关村附近好友,
public V2XDemoUserInfoRes.ResultBean.UserListBean getV2XDemoUserInfoEntity2() {
return mV2XDemoUserInfoEntity2;
}
// 3-点击地图图标拨打电话
public V2XDemoUserInfoRes.ResultBean.UserListBean getV2XDemoUserInfoEntity3() {
return mV2XDemoUserInfoEntity3;
}
}

View File

@@ -0,0 +1,108 @@
package com.mogo.module.v2x;
import android.content.Context;
import android.os.Handler;
import com.mogo.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.v2x.listener.V2XLocationListener;
import com.mogo.module.v2x.network.V2XRefreshModel;
import com.mogo.utils.logger.Logger;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/6 5:37 PM
* desc :
* version: 1.0
*/
public class V2XMarkerService {
private final String TAG = "V2XMarkerService";
// 一分钟获取一次最新的路况信息
private final int refreshTime = 60_000;
private static V2XMarkerService mV2XMarkerService;
private V2XRefreshModel mV2XRefreshModel;
private Handler refreshHandler;
private Runnable refreshRunnable;
public synchronized static V2XMarkerService getInstance(Context context) {
if (mV2XMarkerService == null) {
mV2XMarkerService = new V2XMarkerService();
mV2XMarkerService.init(context);
}
return mV2XMarkerService;
}
private void init(Context context) {
mV2XRefreshModel = V2XRefreshModel.getInstance(context);
}
public V2XRefreshModel getV2XRefreshModel() {
return mV2XRefreshModel;
}
public void refreshMarkerData(MogoLocation location) {
try {
if (mV2XRefreshModel != null && location != null) {
//Logger.d(MODULE_NAME, "V2X道路事件执行气泡刷新操作。");
// 获取目前最新的周边的poi点
mV2XRefreshModel.querySnapshotAsync(
new MogoLatLng(location.getLatitude(), location.getLongitude()),
(int) getMapCameraFactWidth(),
999);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 地图视图对应的实际宽度
*/
private float getMapCameraFactWidth() {
return 1_000;
}
/**
* 关闭自动刷新
*/
public void stopAutoRefresh() {
Logger.w(MODULE_NAME, "V2X道路事件关闭V2X地图气泡自动刷新。");
V2XServiceManager
.getMogoRegisterCenter()
.unregisterMogoLocationListener(MODULE_NAME);
if (refreshHandler != null) {
refreshHandler.removeCallbacks(refreshRunnable);
}
refreshRunnable = null;
}
/**
* 开始刷新
*/
public void startAutoRefresh() {
// 设置地图定位监听
V2XServiceManager.getMogoRegisterCenter()
.registerMogoLocationListener(MODULE_NAME, V2XLocationListener.getInstance());
Logger.d(MODULE_NAME, "V2X道路事件开启V2X地图气泡自动绘制。");
if (refreshHandler == null) {
refreshHandler = new Handler();
}
if (refreshRunnable == null) {
refreshRunnable = new Runnable() {
@Override
public void run() {
refreshMarkerData(V2XLocationListener.getInstance().getLastCarLocation());
refreshHandler.postDelayed(this, refreshTime);
}
};
}
refreshHandler.post(refreshRunnable);
}
}

View File

@@ -0,0 +1,294 @@
package com.mogo.module.v2x;
import android.content.Context;
import android.content.IntentFilter;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.v2x.entity.net.V2XSeekHelpRes;
import com.mogo.module.v2x.entity.net.V2XStrategyPushRes;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.v2x.network.V2XRefreshCallback;
import com.mogo.module.v2x.receiver.SceneBroadcastReceiver;
import com.mogo.module.v2x.scenario.impl.V2XScenarioManager;
import com.mogo.module.v2x.scenario.scene.park.V2XIllegalParkScenario;
import com.mogo.module.v2x.scenario.scene.park.V2XIllegalParkWindow;
import com.mogo.module.v2x.scenario.scene.test.V2XTestConsoleWindow;
import com.mogo.module.v2x.utils.FatigueDrivingUtils;
import com.mogo.module.v2x.utils.TimeUtils;
import com.mogo.module.v2x.utils.V2XUtils;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.utils.GsonUtil;
import com.mogo.utils.storage.SharedPrefsMgr;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-2114:03
* desc : V2X的管理
* version: 2.0
*/
@Route(path = V2XConst.PATH_V2X_UI)
public class V2XModuleProvider implements
IMogoModuleProvider,
IMogoStatusChangedListener {
private final String TAG = "V2XMocduleProvider";
private Context mContext;
@Override
public Fragment createFragment(Context context, Bundle data) {
return null;
}
@Override
public View createView(Context context) {
return null;
}
@NonNull
@Override
public String getModuleName() {
return ServiceConst.TYPE;
}
@Override
public IMogoModuleLifecycle getCardLifecycle() {
return null;
}
@Override
public IMogoMapListener getMapListener() {
return null;
}
@Override
public int getType() {
return ModuleType.TYPE_SERVICE;
}
@Override
public IMogoNaviListener getNaviListener() {
return null;
}
@Override
public IMogoLocationListener getLocationListener() {
return null;
}
@Override
public IMogoMarkerClickListener getMarkerClickListener() {
return null;
}
@Override
public String getAppPackage() {
return null;
}
@Override
public String getAppName() {
return null;
}
@Override
public void init(Context context) {
Logger.e(MODULE_NAME, "V2X模块初始化。。。。");
mContext = context;
V2XUtils.init(context);
V2XServiceManager.init(context);
initVoice(context);
handleAdas();
initData();
// 注册广播接收场景弹窗使用的
SceneBroadcastReceiver localReceiver = new SceneBroadcastReceiver();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(V2XConst.BROADCAST_SCENE_HANDLER_ACTION);
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
// TODO 这是测试页面
V2XServiceManager
.getIMogoWindowManager()
.addView(new V2XTestConsoleWindow(context), 0, 0, false);
}
private void initVoice(Context context) {
V2XVoiceManager.INSTANCE.init(context);
}
private void initData() {
//初始化获得自车求助状态
initCarForHelpStatus();
try {
// 查询ACC状态
SharedPrefsMgr.getInstance(V2XUtils.getApp()).putBoolean("descriptor_ACC_STATUS", isAccOn());
if (isAccOn()) {
// 记录开机时间
FatigueDrivingUtils.refreshAccOnTime();
initCarForHelpStatus();
// 刷新配置文件
refreshStrategyConfig();
} else {
// 记录关机时间
SharedPrefsMgr.getInstance(V2XUtils.getApp())
.putString(V2XConst.V2X_ACC_OFF_TIME_STR, TimeUtils.getNowString());
}
} catch (Exception e) {
e.printStackTrace();
}
// 刷新配置文件
refreshStrategyConfig();
// 响应违章停车的POI点击
V2XServiceManager
.getMogoRegisterCenter()
.registerMogoMarkerClickListener(V2XConst.MODULE_NAME,
new IMogoMarkerClickListener() {
@Override
public boolean onMarkerClicked(IMogoMarker marker) {
try {
MarkerExploreWay markerExploreWay =
(MarkerExploreWay) ((MarkerShowEntity) marker.getObject()).getBindObj();
Logger.d(V2XConst.MODULE_NAME,
"V2X===违章停车:onMarkerClicked=" + markerExploreWay);
((V2XIllegalParkWindow) V2XIllegalParkScenario.getInstance()
.getV2XWindow())
.show(markerExploreWay, false);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
});
}
private void refreshStrategyConfig() {
// 获取疲劳驾驶的配置
V2XServiceManager
.getV2XRefreshModel()
.getStrategyPush(new V2XRefreshCallback<V2XStrategyPushRes>() {
@Override
public void onSuccess(V2XStrategyPushRes result) {
Logger.w(MODULE_NAME, "V2X疲劳驾驶配置数据更新" + GsonUtil.jsonFromObject(result));
V2XStrategyPushRes.ResultBean resultBean = result.getResult();
if (resultBean != null) {
// 更新本地的v2x提醒策略
SharedPrefsMgr.getInstance(V2XUtils.getApp())
.putString(V2XConst.V2X_STRATEGY_PUSH, GsonUtil.jsonFromObject(resultBean));
}
}
@Override
public void onFail(String msg) {
}
});
}
private void handleAdas() {
V2XServiceManager.getMoGoStatusManager()
.registerStatusChangedListener(MODULE_NAME, StatusDescriptor.ACC_STATUS, this);
V2XServiceManager.getMoGoStatusManager()
.registerStatusChangedListener(MODULE_NAME, StatusDescriptor.SEEK_HELPING, this);
// 注册V2X场景Socket
V2XServiceManager.getV2XSocketManager().registerSocketMessage();
// 开启自动刷新
V2XServiceManager.getV2XMarkerService().startAutoRefresh();
// 锁车就是将地图视图移植中心点,因为行驶中的车和地图要相对的跟随
V2XServiceManager.getMapUIController().recoverLockMode();
}
private void handleSeekHelp(boolean isTrue) {
V2XMessageEntity<Boolean> entity = new V2XMessageEntity<>();
entity.setType(V2XMessageEntity.V2XTypeEnum.ALERT_CAR_FOR_HELP);
entity.setContent(isTrue);
V2XScenarioManager.getInstance().handlerMessage(entity);
}
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
Logger.d(MODULE_NAME, "状态发生改变\ndescriptor:" + descriptor + "\nisTrue:" + isTrue);
// 记录状态更改
SharedPrefsMgr.getInstance(V2XUtils.getApp()).putBoolean("descriptor_" + descriptor, isTrue);
if (descriptor == StatusDescriptor.ACC_STATUS) {
if (isTrue) {
// 记录开机时间
FatigueDrivingUtils.refreshAccOnTime();
initCarForHelpStatus();
} else {
// 记录关机时间
SharedPrefsMgr.getInstance(V2XUtils.getApp())
.putString(V2XConst.V2X_ACC_OFF_TIME_STR, TimeUtils.getNowString());
}
} else if (descriptor == StatusDescriptor.SEEK_HELPING) {
handleSeekHelp(isTrue);
}
}
public boolean isAccOn() {
int accState = Settings.System.getInt(mContext.getContentResolver(), "mcu_state", -0x02);
Logger.d(MODULE_NAME, "状态发生改变\ndescriptor:ACC_STSTUS" + "\nisTrue:" + accState);
return accState == 1;
}
private void initCarForHelpStatus() {
//本地查询是否超时
V2XServiceManager.getV2XRefreshModel().getHelpSignal(new V2XRefreshCallback<V2XSeekHelpRes>() {
@Override
public void onSuccess(V2XSeekHelpRes result) {
if (result != null) {
V2XSeekHelpRes.ResultBean resultBean = result.getResult();
if (resultBean != null) {
int vehicleType = resultBean.getVehicleType();
//故障车
if (vehicleType == 4) {
if (!V2XServiceManager.getMoGoStatusManager().isSeekHelping()) {
handleSeekHelp(true);
V2XServiceManager.getMoGoStatusManager().setSeekHelping(MODULE_NAME, true);
}
} else {
if (V2XServiceManager.getMoGoStatusManager().isSeekHelping()) {
handleSeekHelp(false);
V2XServiceManager.getMoGoStatusManager().setSeekHelping(MODULE_NAME, false);
}
}
}
}
}
@Override
public void onFail(String msg) {
}
});
}
}

View File

@@ -0,0 +1,246 @@
package com.mogo.module.v2x;
import android.content.Context;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.map.location.IMogoLocationClient;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.navi.IMogoNavi;
import com.mogo.map.overlay.IMogoOverlayManager;
import com.mogo.map.search.geo.IMogoGeoSearch;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.carchattingprovider.ICarsChattingProvider;
import com.mogo.module.v2x.alarm.V2XCalculateServer;
import com.mogo.module.v2x.network.V2XRefreshModel;
import com.mogo.module.v2x.manager.IMoGoV2XMarkerManager;
import com.mogo.module.v2x.manager.IMoGoV2XPolylineManager;
import com.mogo.module.v2x.manager.IMoGoV2XStatusManager;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.adas.IMogoADASController;
import com.mogo.service.analytics.IMogoAnalytics;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.service.entrance.IMogoEntranceButtonController;
import com.mogo.service.imageloader.IMogoImageloader;
import com.mogo.service.intent.IMogoIntentManager;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.module.IMogoActionManager;
import com.mogo.service.module.IMogoMarkerService;
import com.mogo.service.module.IMogoRegisterCenter;
import com.mogo.service.module.IMogoSearchManager;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.strategy.IMogoRefreshStrategyController;
import com.mogo.service.windowview.IMogoTopViewManager;
import com.mogo.service.windowview.IMogoWindowManager;
import com.zhidao.carchattingprovider.CallChattingProviderConstant;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-2114:01
* desc : V2X 服务
* version: 1.0
*/
public class V2XServiceManager {
private static final String TAG = "V2XServiceManager";
private static Context mContext;
private static IMogoServiceApis mMogoServiceApis;
private static IMogoMapService mMapService;
private static IMogoMarkerManager mMarkerManager;
private static IMogoNavi mNavi;
private static IMogoMapUIController mMapUIController;
private static IMogoLocationClient mMogoLocationClient;
private static IMogoGeoSearch mIMogoGeoSearch;
private static IMogoSearchManager mIMogoSearchManager;
private static IMogoTopViewManager mMogoTopViewManager;
private static IMogoStatusManager mMogoStatusManager;
private static IMogoWindowManager mIMogoWindowManager;
private static IMogoImageloader mImageLoader;
private static IMogoSocketManager mMogoSocketManager;
private static IMogoAnalytics mMogoAnalytics;
private static IMogoOverlayManager mMogoOverlayManager;
private static IMogoRegisterCenter mMogoRegisterCenter;
private static IMogoRefreshStrategyController mIMogoRefreshStrategyController;
private static IMogoMarkerService mIMogoMarkerService;
private static IMogoActionManager mMogoActionManager;
private static ICarsChattingProvider mCarsChattingProvider;
private static IMogoADASController mIMogoADASController;
private static IMogoIntentManager mMogoIntentManager;
private static IMogoEntranceButtonController mMogoEntranceButtonController;
private static V2XRefreshModel mV2XRefreshModel;
private static V2XMarkerService mV2XMarkerService;
private static V2XStatusManager mV2XStatusManager;
private static V2XSocketManager mV2XSocketManager;
private static V2XCalculateServer mV2XCalculateServer;
// 下面的是重构后的代码,建议
private static IMoGoV2XMarkerManager moGoV2XMarkerManager;
private static IMoGoV2XPolylineManager moGoV2XPolylineManager;
private static IMoGoV2XStatusManager moGoV2XStatusManager;
public static void init(final Context context) {
mContext = context;
mMogoServiceApis = (IMogoServiceApis) ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(context);
mMapService = mMogoServiceApis.getMapServiceApi();
mImageLoader = mMogoServiceApis.getImageLoaderApi();
mMogoStatusManager = mMogoServiceApis.getStatusManagerApi();
mMogoSocketManager = mMogoServiceApis.getSocketManagerApi(context);
mMogoAnalytics = mMogoServiceApis.getAnalyticsApi();
mIMogoWindowManager = mMogoServiceApis.getWindowManagerApi();
mMogoRegisterCenter = mMogoServiceApis.getRegisterCenterApi();
mIMogoRefreshStrategyController = mMogoServiceApis.getRefreshStrategyControllerApi();
mIMogoADASController = mMogoServiceApis.getAdasControllerApi();
mMogoEntranceButtonController = mMogoServiceApis.getEntranceButtonController();
mMogoActionManager = mMogoServiceApis.getActionManagerApi();
mMogoTopViewManager = mMogoServiceApis.getTopViewManager();
mIMogoSearchManager = mMogoServiceApis.getSearchManagerApi();
mIMogoMarkerService = mMogoServiceApis.getMarkerService();
mMarkerManager = mMapService.getMarkerManager(context);
mNavi = mMapService.getNavi(context);
mMapUIController = mMapService.getMapUIController();
mMogoLocationClient = mMapService.getSingletonLocationClient(context);
mMogoOverlayManager = mMapService.getOverlayManager(context);
mIMogoGeoSearch = mMapService.getGeoSearch(context);
mCarsChattingProvider = (ICarsChattingProvider) ARouter.getInstance().build(CallChattingProviderConstant.CAR_CALL_PROVIDER).navigation();
mMogoIntentManager = mMogoServiceApis.getIntentManagerApi();
mV2XRefreshModel = V2XRefreshModel.getInstance(context);
mV2XMarkerService = V2XMarkerService.getInstance(context);
mV2XStatusManager = V2XStatusManager.getInstance();
mV2XSocketManager = V2XSocketManager.getInstance();
mV2XCalculateServer = V2XCalculateServer.getInstance();
moGoV2XMarkerManager = (IMoGoV2XMarkerManager) ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_MARKER_MANAGER).navigation(context);
moGoV2XPolylineManager = (IMoGoV2XPolylineManager) ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_POLYLINE_MANAGER).navigation(context);
moGoV2XStatusManager = (IMoGoV2XStatusManager) ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_STATUS_MANAGER).navigation(context);
}
public static Context getContext() {
return mContext;
}
public static IMogoTopViewManager getMogoTopViewManager() {
return mMogoTopViewManager;
}
public static IMogoEntranceButtonController getMogoEntranceButtonController() {
return mMogoEntranceButtonController;
}
public static IMogoMapService getMapService() {
return mMapService;
}
public static IMogoOverlayManager getMogoOverlayManager() {
return mMogoOverlayManager;
}
public static IMogoRegisterCenter getMogoRegisterCenter() {
return mMogoRegisterCenter;
}
public static IMogoMarkerManager getMarkerManager() {
return mMarkerManager;
}
public static IMogoNavi getNavi() {
return mNavi;
}
public static IMogoMapUIController getMapUIController() {
return mMapUIController;
}
public static IMogoLocationClient getMogoLocationClient() {
return mMogoLocationClient;
}
public static IMogoImageloader getImageLoader() {
return mImageLoader;
}
public static IMogoSocketManager getMoGoSocketManager() {
return mMogoSocketManager;
}
public static IMogoStatusManager getMoGoStatusManager() {
return mMogoStatusManager;
}
public static IMogoWindowManager getIMogoWindowManager() {
return mIMogoWindowManager;
}
public static ICarsChattingProvider getCarsChattingProvider() {
return mCarsChattingProvider;
}
public static IMogoIntentManager getMogoIntentManager() {
return mMogoIntentManager;
}
public static V2XMarkerService getV2XMarkerService() {
return mV2XMarkerService;
}
public static V2XRefreshModel getV2XRefreshModel() {
return mV2XRefreshModel;
}
public static V2XStatusManager getV2XStatusManager() {
return mV2XStatusManager;
}
public static V2XSocketManager getV2XSocketManager() {
return mV2XSocketManager;
}
public static IMoGoV2XMarkerManager getMoGoV2XMarkerManager() {
return moGoV2XMarkerManager;
}
public static IMoGoV2XPolylineManager getMoGoV2XPolylineManager() {
return moGoV2XPolylineManager;
}
public static IMoGoV2XStatusManager getMoGoV2XStatusManager() {
return moGoV2XStatusManager;
}
public static IMogoActionManager getMogoActionManager() {
return mMogoActionManager;
}
public static IMogoGeoSearch getMogoGeoSearch() {
return mIMogoGeoSearch;
}
public static IMogoSearchManager getSearchManager() {
return mIMogoSearchManager;
}
public static IMogoRefreshStrategyController getIMogoRefreshStrategyController() {
return mIMogoRefreshStrategyController;
}
public static IMogoAnalytics getMogoAnalytics() {
return mMogoAnalytics;
}
public static IMogoMarkerService getIMogoMarkerService() {
return mIMogoMarkerService;
}
public static V2XCalculateServer getV2XCalculateServer() {
return mV2XCalculateServer;
}
}

View File

@@ -0,0 +1,209 @@
package com.mogo.module.v2x;
import com.mogo.module.v2x.listener.V2XMessageListener_401003;
import com.mogo.module.v2x.listener.V2XMessageListener_401005;
import com.mogo.module.v2x.listener.V2XMessageListener_401006;
import com.mogo.module.v2x.listener.V2XMessageListener_401007;
import com.mogo.module.v2x.listener.V2XMessageListener_401009;
import com.mogo.module.v2x.listener.V2XMessageListener_401010;
import com.mogo.module.v2x.listener.V2XMessageListener_401011;
import com.mogo.utils.logger.Logger;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/31 5:59 PM
* desc : V2X报警事件管理这里进行报警事件的分发处理TODO 这里是准备重构使用的
* version: 1.0
*/
public class V2XSocketManager {
private static V2XSocketManager mV2XSocketManager;
private V2XMessageListener_401011 v2XMessageListener_401001;
private V2XMessageListener_401003 v2XMessageListener_401003;
private V2XMessageListener_401005 v2XMessageListener_401005;
private V2XMessageListener_401006 v2XMessageListener_401006;
private V2XMessageListener_401007 v2XMessageListener_401007;
private V2XMessageListener_401009 v2XMessageListener_401009;
private V2XMessageListener_401010 v2XMessageListener_401010;
private V2XSocketManager() {
}
/**
* 获取操作实体
*/
public static synchronized V2XSocketManager getInstance() {
synchronized (V2XSocketManager.class) {
if (mV2XSocketManager == null) {
mV2XSocketManager = new V2XSocketManager();
}
}
return mV2XSocketManager;
}
/**
* 注册长链接消息处理
*/
public void registerSocketMessage() {
Logger.d(MODULE_NAME, "开始注册Socket通道....");
register401011();
register401005();
register401007();
register401009();
// TODO 这里是前瞻需求,量产版本需要注释
//register401003();
// TODO 旧版本的一种V2X预警形式已经废弃了
//register401006();
}
/**
* 反注册消息通道,不再进行接受
*/
public void unregisterSocketMessage() {
Logger.w(MODULE_NAME, "反注册Socket通道....");
if (v2XMessageListener_401001 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(401011, v2XMessageListener_401001);
}
if (v2XMessageListener_401003 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(401003, v2XMessageListener_401003);
}
if (v2XMessageListener_401005 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(401005, v2XMessageListener_401005);
}
if (v2XMessageListener_401006 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(401006, v2XMessageListener_401006);
}
if (v2XMessageListener_401007 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(401007, v2XMessageListener_401007);
}
if (v2XMessageListener_401009 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(401009, v2XMessageListener_401009);
}
}
/**
* 道路事件,在线车辆绘制
*/
private void register401011() {
v2XMessageListener_401001 = new V2XMessageListener_401011();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401011,
v2XMessageListener_401001
);
}
/**
* ADAS & V2X 场景触发push
* TODO 这里是后台下发 http://h5service.zhidaohulian.com/v2x_remoteControl/#/
*/
private void register401003() {
v2XMessageListener_401003 = new V2XMessageListener_401003();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401003,
v2XMessageListener_401003
);
}
/**
* 特殊车辆推送绘制
*/
private void register401005() {
v2XMessageListener_401005 = new V2XMessageListener_401005();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401005,
v2XMessageListener_401005
);
}
/**
* * 3.2.1、前方静止or慢速车辆报警
* * 3.2.2、道路危险状况告警 / 前方拥堵告警
*/
@Deprecated
private void register401006() {
v2XMessageListener_401006 = new V2XMessageListener_401006();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401006,
v2XMessageListener_401006
);
}
/**
* 限行通知
*/
private void register401007() {
v2XMessageListener_401007 = new V2XMessageListener_401007();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401007,
v2XMessageListener_401007
);
}
/**
* * 2.0.2
* * http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=35786774
* * 注册点赞通信接收
*/
public void register401009() {
v2XMessageListener_401009 = new V2XMessageListener_401009();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401009,
v2XMessageListener_401009
);
}
/**
* * 2.0.3
* * http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=35788659
* * TODO 停车场、加油站推送心跳,这里是前瞻的功能,目前仅在分体机使用,
*/
@Deprecated
private void register401010() {
v2XMessageListener_401010 = new V2XMessageListener_401010();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
401010,
v2XMessageListener_401010
);
}
}

View File

@@ -0,0 +1,62 @@
package com.mogo.module.v2x;
import com.mogo.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.common.entity.V2XRoadEventEntity;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/3 2:34 PM
* desc : V2X状态管理
* version: 1.0
*/
@Deprecated
public class V2XStatusManager {
private static V2XStatusManager mV2XStatusManager;
// 正在进行的告警事件详情
private V2XRoadEventEntity mAlarmInfo;
private MogoLocation mLocation;
private V2XStatusManager() {
}
/**
* 获取操作实体
*/
public static synchronized V2XStatusManager getInstance() {
synchronized (V2XStatusManager.class) {
if (mV2XStatusManager == null) {
mV2XStatusManager = new V2XStatusManager();
}
}
return mV2XStatusManager;
}
public void setAlarmInfo(V2XRoadEventEntity eventEntity) {
this.mAlarmInfo = eventEntity;
}
// 获取目标事件经纬度
public MogoLatLng getTargetMoGoLatLng() {
if (mAlarmInfo != null) {
return new MogoLatLng(
mAlarmInfo.getLocation().getLat(),
mAlarmInfo.getLocation().getLon()
);
}
return null;
}
public MogoLocation getLocation() {
if (mLocation == null) {
mLocation = new MogoLocation();
}
return mLocation;
}
public void setLocation(MogoLocation mLocation) {
this.mLocation = mLocation;
}
}

View File

@@ -0,0 +1,49 @@
package com.mogo.module.v2x.adapter;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.module.v2x.adapter.holder.V2XPushEventDetailVH;
import com.mogo.module.common.entity.V2XPushMessageEntity;
import java.util.List;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:05 PM
* desc : V2X 场景事件列表中的数据适配器
* version: 1.0
*/
public class V2XPushEventAdapter extends RecyclerView.Adapter<V2XPushEventDetailVH> {
private List<V2XPushMessageEntity> itemList;
public V2XPushEventAdapter(List<V2XPushMessageEntity> itemList) {
this.itemList = itemList;
}
@NonNull
@Override
public V2XPushEventDetailVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new V2XPushEventDetailVH(parent);
}
@Override
public void onBindViewHolder(@NonNull V2XPushEventDetailVH holder, int position) {
holder.initView(itemList.get(position));
}
@Override
public int getItemViewType(int position) {
return itemList.get(position).getViewType();
}
@Override
public int getItemCount() {
return itemList == null ? 0 : itemList.size();
}
}

View File

@@ -0,0 +1,67 @@
package com.mogo.module.v2x.adapter;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.module.common.entity.V2XEventShowEntity;
import com.mogo.module.v2x.adapter.holder.V2XLiveVideoVH;
import com.mogo.module.v2x.adapter.holder.V2XRoadEventDetailVH;
import com.mogo.module.common.entity.V2XWindowTypeEnum;
import java.util.List;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:05 PM
* desc : V2X 场景事件列表中的数据适配器
* version: 1.0
*/
public class V2XRoadEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<V2XEventShowEntity> itemList;
public V2XRoadEventAdapter(List<V2XEventShowEntity> itemList) {
this.itemList = itemList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder;
switch (viewType) {
case V2XWindowTypeEnum.LIVE_CAR_WINDOW:
holder = new V2XLiveVideoVH(parent);
break;
case V2XWindowTypeEnum.ROAD_EVENT_WINDOW:
holder = new V2XRoadEventDetailVH(parent);
break;
default:
holder = new V2XRoadEventDetailVH(parent);
}
return holder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof V2XLiveVideoVH) {
((V2XLiveVideoVH) holder).initView(itemList.get(position));
}
if (holder instanceof V2XRoadEventDetailVH) {
((V2XRoadEventDetailVH) holder).initView(itemList.get(position));
}
}
@Override
public int getItemViewType(int position) {
return itemList.get(position).getViewType();
}
@Override
public int getItemCount() {
return itemList == null ? 0 : itemList.size();
}
}

View File

@@ -0,0 +1,217 @@
package com.mogo.module.v2x.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
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.recyclerview.widget.RecyclerView;
import com.mogo.module.carchattingprovider.ICarsChattingProvider;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XConst;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.entity.net.V2XSpecialCarRes.V2XMarkerEntity;
import com.mogo.module.v2x.utils.ChartingUtil;
import com.mogo.module.v2x.utils.V2XUtils;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.utils.logger.Logger;
import com.zhidao.carchattingprovider.ICallChatResponse;
import org.jetbrains.annotations.Nullable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
/**
* author : fenghualong
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:05 PM
* desc : V2X 其他车辆发起的故障求助
* version: 1.0
*/
public class V2XSeekHelpAdapter extends RecyclerView.Adapter<V2XSeekHelpAdapter.MyViewHolder> {
private static final String TAG = V2XSeekHelpAdapter.class.getSimpleName();
private List<V2XMarkerEntity> itemList;
private LayoutInflater mInflater;
public V2XSeekHelpAdapter(Context context) {
itemList = new ArrayList<>();
mInflater = LayoutInflater.from(context);
}
public void addDataList(List<V2XMarkerEntity> list) {
if (itemList == null) {
itemList = new ArrayList<>();
}
itemList.addAll(list);
}
public void addData(V2XMarkerEntity entity) {
if (itemList == null) {
itemList = new ArrayList<>();
}
itemList.add(entity);
}
public void removeData(V2XMarkerEntity entity) {
if (itemList != null) {
itemList.remove(entity);
}
}
public void removeData(int position) {
if (isPositionValid(position)) {
itemList.remove(position);
}
}
public void clearData() {
if (itemList != null) {
itemList.clear();
}
}
public boolean isPositionValid(int position) {
return position > -1 && itemList != null && itemList.size() > position;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.item_v2x_fault_help, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
if (isPositionValid(position)) {
V2XMarkerEntity entity = itemList.get(position);
if (entity != null) {
V2XMarkerEntity.UserInfoBean infoBean = entity.getUserInfo();
if (infoBean != null) {
long time = entity.getCreateTime();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.CHINA);
String eventDistance = String.format("距离%d m", entity.getDistance());
String eventTime = String.format("%s发布求助信息", sdf.format(new Date(time)));
holder.initView(infoBean.getHeadImgUrl(), infoBean.getDisplayName(), eventDistance, eventTime);
}
}
Log.d(TAG, "onBindViewHolder position=$position, entity= " + entity);
setCallData(holder.ivCall, entity);
//setCallDataWait(holder.ivCall, entity);
holder.ivNavi.setOnClickListener(v -> {
if (mListener != null && !V2XUtils.isFastClick()) {
mListener.onViewNaviClick(entity.getLat(), entity.getLon());
}
});
}
}
private void setCallData(ImageView ivCall, V2XMarkerEntity entity) {
ICarsChattingProvider provider = V2XServiceManager.getCarsChattingProvider();
// 判断是否可以打电话
ChartingUtil.isCanCall(b -> {
if (b) {
// 判断是否可以打电话
ChartingUtil.isOnLine(entity.getSn(), b1 -> {
if (b1) {
ivCall.setVisibility(VISIBLE);
} else {
ivCall.setVisibility(GONE);
}
});
} else {
ivCall.setVisibility(GONE);
}
});
ivCall.setOnClickListener(v -> {
if (!V2XUtils.isFastClick()) {
provider.isOnLine(V2XConst.MODULE_NAME, ivCall.getContext(), entity.getSn(), new ICallChatResponse() {
@Override
public void isOnLine(boolean isOnline, @Nullable String s) {
provider.canCall(V2XConst.MODULE_NAME, ivCall.getContext(), new ICallChatResponse() {
@Override
public void canCall(boolean canCall) {
Logger.d(TAG, "调用车聊聊,查询状态! SN=" + entity.getSn() + " is online: " + isOnline + " canCall: " + canCall + ", thread: " + Thread.currentThread().getName());
V2XUtils.runOnUiThread(() -> {
if (mListener != null && isOnline && canCall) {
mListener.onViewChatClick(entity);
}
});
}
});
}
}
);
}
});
}
@Override
public int getItemCount() {
return itemList != null ? itemList.size() : 0;
}
static class MyViewHolder extends RecyclerView.ViewHolder {
MogoImageView ivHead;
TextView tvName;
TextView tvDistance;
TextView tvEventTime;
ImageView ivCall;
ImageView ivNavi;
MyViewHolder(@NonNull View itemView) {
super(itemView);
ivHead = itemView.findViewById(R.id.ivFaultHelpHead);
tvName = itemView.findViewById(R.id.tvFaultHelpName);
tvDistance = itemView.findViewById(R.id.tvFaultHelpDistance);
tvEventTime = itemView.findViewById(R.id.tvFaultHelpEventTime);
ivCall = itemView.findViewById(R.id.ivFaultHelpEventCall);
ivNavi = itemView.findViewById(R.id.ivFaultHelpEventNavi);
}
void initView(String headUrl, String name, String distance, String eventTime) {
if (!TextUtils.isEmpty(headUrl)) {
V2XServiceManager.getImageLoader()
.displayImage(headUrl, ivHead);
}
tvName.setText(name);
tvDistance.setText(distance);
tvEventTime.setText(eventTime);
}
}
private OnViewClickListener mListener;
public void setOnViewClickListener(OnViewClickListener listener) {
mListener = listener;
}
public interface OnViewClickListener {
/**
* 点击事件,打电话给车聊聊
*
* @param entity
*/
void onViewChatClick(V2XMarkerEntity entity);
/**
* 点击事件,导航去故障车位置
*/
void onViewNaviClick(double lat, double lng);
}
}

View File

@@ -0,0 +1,244 @@
package com.mogo.module.v2x.adapter.holder;
import android.content.Intent;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.voice.AIAssist;
import com.mogo.module.common.entity.MarkerCarInfo;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerUserInfo;
import com.mogo.module.common.entity.V2XEventShowEntity;
import com.mogo.module.common.entity.V2XRoadEventEntity;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XConst;
import com.mogo.module.common.entity.V2XLiveCarInfoEntity;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.entity.net.V2XUserInfoRes;
import com.mogo.module.v2x.network.V2XRefreshCallback;
import com.mogo.module.v2x.scenario.scene.road.V2XRoadEventScenario;
import com.mogo.module.v2x.utils.ChartingUtil;
import com.mogo.module.v2x.utils.ToastUtils;
import com.mogo.module.v2x.utils.TrackUtils;
import com.mogo.module.v2x.utils.V2XUtils;
import com.mogo.module.v2x.view.V2XLiveGSYVideoView;
import com.mogo.module.v2x.voice.V2XVoiceCallbackListener;
import com.mogo.module.v2x.voice.V2XVoiceConstants;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.utils.logger.Logger;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:35 PM
* desc : 直播类型的卡片
* version: 1.0
*/
public class V2XLiveVideoVH extends RecyclerView.ViewHolder {
private V2XLiveGSYVideoView videoPlayer;
private MogoImageView ivReportHead;
// 控制按钮
private ImageView ivRoadCallChart;
private ImageView ivRoadEventLike;
// 上传事件的用户信息
private MarkerUserInfo mUserInfo = new MarkerUserInfo();
// 直播车机数据
private V2XLiveCarInfoEntity mV2XLiveCarEntity;
// 预警的道路事件数据
private V2XRoadEventEntity mV2XRoadEventEntity;
// 拨打车聊聊语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackCallListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
if (mUserInfo != null && !TextUtils.isEmpty(mUserInfo.getSn())) {
roadCallChart();
}
}
};
// 点赞语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackLickListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
if (mV2XLiveCarEntity != null) {
handlerZan(mV2XLiveCarEntity.getSn());
}
}
};
public V2XLiveVideoVH(ViewGroup viewGroup) {
super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_v2x_live_video, viewGroup, false));
videoPlayer = itemView.findViewById(R.id.videoPlayer);
ivReportHead = itemView.findViewById(R.id.ivReportHead);
ivRoadCallChart = itemView.findViewById(R.id.ivRoadCallChart);
ivRoadEventLike = itemView.findViewById(R.id.ivRoadEventLike);
// 设置视图状态监听
itemView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
//Logger.w(MODULE_NAME, "列表View V2XLiveVideoVH 触发 onViewAttachedToWindow");
// 注册语音交互
V2XVoiceManager.INSTANCE
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_CHATTING,
v2XVoiceCallbackCallListener)
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_ZAN,
v2XVoiceCallbackLickListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CHAT_MORE_UN_WAKEUP,
v2XVoiceCallbackCallListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_ZAN_UN_WAKEUP,
v2XVoiceCallbackLickListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
//Logger.w(MODULE_NAME, "列表View V2XLiveVideoVH 触发 onViewDetachedFromWindow");
}
});
}
public void initView(V2XEventShowEntity v2XLiveCarEntity) {
mV2XRoadEventEntity = v2XLiveCarEntity.getV2XRoadEventEntity();
mV2XLiveCarEntity = v2XLiveCarEntity.getV2XLiveCarInfoRes();
initView(mV2XLiveCarEntity);
}
public void initView(V2XLiveCarInfoEntity v2XLiveCarEntity) {
mV2XLiveCarEntity = v2XLiveCarEntity;
// 由于车机自身推流的原因这里为了浪费用户不必要的流量用户滑动到了那个view展示了再进行直播信息的获取及展示
MarkerCarInfo.CarLiveInfo carLiveInfo = new MarkerCarInfo.CarLiveInfo();
carLiveInfo.setVideoSn(v2XLiveCarEntity.getSn());
videoPlayer.setCarLiveInfo(carLiveInfo);
ivRoadEventLike.setVisibility(VISIBLE);
ivRoadCallChart.setOnClickListener(v -> {
ivRoadCallChart.setVisibility(GONE);
roadCallChart();
});
ivRoadEventLike.setOnClickListener(v -> {
handlerZan(v2XLiveCarEntity.getSn());
});
requestUserInfo(v2XLiveCarEntity);
}
private void roadCallChart() {
MarkerLocation location = new MarkerLocation();
ChartingUtil.callChatting(mUserInfo, location);
}
/**
* 请求用户信息
*
* @param v2XLiveCarEntity 直播信息
*/
private void requestUserInfo(V2XLiveCarInfoEntity v2XLiveCarEntity) {
Logger.d(MODULE_NAME, "上报事件的用户SN" + v2XLiveCarEntity.getSn());
TrackUtils.trackV2xRoadEvent(mV2XRoadEventEntity.getNoveltyInfo().getInfoId(), v2XLiveCarEntity.getSn(), V2XConst.V2X_ROAD_VIDEO);
// 获取道路事件周边的直播车机
if (!TextUtils.isEmpty(v2XLiveCarEntity.getSn())) {
V2XServiceManager
.getV2XRefreshModel()
.queryUserInfoBySn(
v2XLiveCarEntity.getSn(),
new V2XRefreshCallback<V2XUserInfoRes>() {
@Override
public void onSuccess(V2XUserInfoRes result) {
//Logger.d(MODULE_NAME, "上报事件的用户:" + result);
if (result != null &&
result.getResult() != null &&
result.getResult().getInfo() != null) {
V2XUserInfoRes.Result.Info infoBean = result.getResult().getInfo();
if (mUserInfo == null) {
mUserInfo = new MarkerUserInfo();
}
mUserInfo.setSn(infoBean.getSn());
try {
if (!TextUtils.isEmpty(infoBean.getCardIdAge())) {
mUserInfo.setAge(Integer.parseInt(infoBean.getCardIdAge()));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
mUserInfo.setUserName(infoBean.getUserNickName());
mUserInfo.setUserHead(infoBean.getHeadImgUrl());
mUserInfo.setGender(infoBean.getCardIdSex());
if (DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_SELF_INNOVATE) {
// 判断是否可以打电话
ChartingUtil.isCanCall(b -> {
if (b) {
// 判断是否可以打电话
ChartingUtil.isOnLine(mUserInfo.getSn(), b1 -> {
if (b1) {
ivRoadCallChart.setVisibility(VISIBLE);
} else {
ivRoadCallChart.setVisibility(GONE);
}
});
} else {
ivRoadCallChart.setVisibility(GONE);
}
});
}
if (!TextUtils.isEmpty(mUserInfo.getUserHead())) {
V2XServiceManager.getImageLoader()
.displayImage(mUserInfo.getUserHead(), ivReportHead);
}
}
}
@Override
public void onFail(String msg) {
ivRoadCallChart.setVisibility(GONE);
}
});
}
}
private void handlerZan(String sn) {
try {
AIAssist.getInstance(V2XUtils.getApp()).speakTTSVoice("已点赞", null);
showTip("已点赞");
V2XServiceManager.getV2XMarkerService()
.getV2XRefreshModel()
.giveLikeLiveVideo(null, sn);
ivReportHead.postDelayed(new Runnable() {
@Override
public void run() {
V2XRoadEventScenario.getInstance().close();
}
}, 2000);
} catch (Exception e) {
e.printStackTrace();
}
}
private void showTip(String msg) {
ToastUtils.setGravity(Gravity.CENTER, 0, 0);
View toastView = LayoutInflater.from(V2XServiceManager.getContext()).inflate(R.layout.toast_view, null);
TextView msgView = toastView.findViewById(R.id.tvFeedbackContent);
msgView.setText(msg);
ToastUtils.showCustomShort(toastView);
}
}

View File

@@ -0,0 +1,297 @@
package com.mogo.module.v2x.adapter.holder;
import android.content.Intent;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.commons.voice.AIAssist;
import com.mogo.map.MogoLatLng;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.navi.MogoTraffic;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerUserInfo;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.common.entity.V2XPushMessageEntity;
import com.mogo.module.v2x.scenario.scene.push.V2XPushEventScenario;
import com.mogo.module.v2x.utils.ChartingUtil;
import com.mogo.module.v2x.utils.ToastUtils;
import com.mogo.module.v2x.utils.V2XUtils;
import com.mogo.module.v2x.voice.V2XVoiceCallbackListener;
import com.mogo.module.v2x.voice.V2XVoiceConstants;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.utils.logger.Logger;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:35 PM
* desc : TODO 这里是前瞻演示需求,推送的消息,
* version: 1.0
*/
public class V2XPushEventDetailVH extends RecyclerView.ViewHolder implements IMogoNaviListener {
private MogoImageView ivImg;
private MogoImageView ivReportHead;
// 控制按钮
private ImageView ivRoadReportTrue;
private ImageView ivRoadReportErr;
private ImageView ivRoadCallChart;
private ImageView ivRoadEventNav;
private ImageView ivRoadEventLike;
// 上传事件的用户信息
private MarkerUserInfo mUserInfo = new MarkerUserInfo();
private V2XPushMessageEntity mV2XRoadEventEntity;
// 语音控制导航
private V2XVoiceCallbackListener mNaviCb = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
startNavi();
}
};
// 语音控制拨打电话
private V2XVoiceCallbackListener mCallChartingCb = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
roadCallChart();
}
};
// 点赞语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackLickListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
handlerZan();
}
};
public V2XPushEventDetailVH(ViewGroup viewGroup) {
super(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_v2x_push_event_detail, viewGroup, false));
ivImg = itemView.findViewById(R.id.ivImg);
ivReportHead = itemView.findViewById(R.id.ivReportHead);
ivRoadReportTrue = itemView.findViewById(R.id.ivRoadReportTrue);
ivRoadReportErr = itemView.findViewById(R.id.ivRoadReportErr);
ivRoadCallChart = itemView.findViewById(R.id.ivRoadCallChart);
ivRoadEventNav = itemView.findViewById(R.id.ivRoadEventNav);
ivRoadEventLike = itemView.findViewById(R.id.ivRoadEventLike);
ivRoadEventNav.getParent().getParent().requestDisallowInterceptTouchEvent(true);
ivRoadEventNav.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startNavi();
}
});
ivRoadCallChart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
roadCallChart();
}
});
ivRoadEventLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handlerZan();
}
});
// 设置视图状态监听
itemView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
//Logger.w(MODULE_NAME, "列表View V2XPushEventDetailVH 触发 onViewAttachedToWindow");
// 注册语音交互
V2XVoiceManager.INSTANCE
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_NAVI,
mNaviCb)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_NAVI_UN_WAKEUP,
mNaviCb)
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_CHATTING,
mCallChartingCb)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CHAT_MORE_UN_WAKEUP,
mCallChartingCb)
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_ZAN,
v2XVoiceCallbackLickListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_ZAN_UN_WAKEUP,
v2XVoiceCallbackLickListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
//Logger.w(MODULE_NAME, "列表View V2XPushEventDetailVH 触发 onViewDetachedFromWindow");
V2XServiceManager.getMogoRegisterCenter().unregisterMogoNaviListener(MODULE_NAME);
// 反注册语音交互
V2XVoiceManager.INSTANCE
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CLOSE_WINDOW)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CLOSE_WINDOW_UN_WAKEUP)
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_CHATTING)
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_ZAN)
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REPORT)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CHAT_MORE_UN_WAKEUP)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_ZAN_UN_WAKEUP)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_FEEDBACK_TRUE)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_FEEDBACK_ERROR)
.unRegisterPagingCallback();
}
});
}
public void initView(V2XPushMessageEntity v2XRoadEventEntity) {
mV2XRoadEventEntity = v2XRoadEventEntity;
if (!TextUtils.isEmpty(v2XRoadEventEntity.getMsgImgUrl())) {
V2XServiceManager.getImageLoader()
.displayImage(v2XRoadEventEntity.getMsgImgUrl(), ivImg);
}
if (!TextUtils.isEmpty(v2XRoadEventEntity.getHeadImgUrl())) {
V2XServiceManager.getImageLoader()
.displayImage(v2XRoadEventEntity.getHeadImgUrl(), ivReportHead);
}
switch (v2XRoadEventEntity.getSceneId()) {
case "100015"://取快递
case "100016"://顺风车
ivRoadEventNav.setVisibility(View.VISIBLE);
ivRoadCallChart.setVisibility(View.VISIBLE);
ivRoadReportTrue.setVisibility(View.GONE);
ivRoadReportErr.setVisibility(View.GONE);
ivRoadEventLike.setVisibility(View.GONE);
break;
case "100017"://政府公告
ivRoadEventLike.setVisibility(View.VISIBLE);
ivRoadCallChart.setVisibility(View.GONE);
ivRoadEventNav.setVisibility(View.GONE);
ivRoadReportTrue.setVisibility(View.GONE);
ivRoadReportErr.setVisibility(View.GONE);
break;
}
}
/**
* 打电话
*/
private void roadCallChart() {
Logger.w(MODULE_NAME, "正在拨打电话。。。。");
if (mV2XRoadEventEntity != null) {
MarkerLocation location = new MarkerLocation();
location.setLon(mV2XRoadEventEntity.getLon());
location.setLat(mV2XRoadEventEntity.getLat());
mUserInfo.setSn(mV2XRoadEventEntity.getSn());
mUserInfo.setUserHead(mV2XRoadEventEntity.getHeadImgUrl());
mUserInfo.setUserName("蘑菇用户");
mUserInfo.setGender("");
mUserInfo.setAge(30);
ChartingUtil.callChatting(mUserInfo, location);
delayedCloseWindow();
}
}
/**
* 点赞
*/
private void handlerZan() {
try {
AIAssist.getInstance(V2XUtils.getApp()).speakTTSVoice("已点赞", null);
showTip("已点赞");
if (mV2XRoadEventEntity != null) {
V2XServiceManager.getV2XMarkerService()
.getV2XRefreshModel()
.giveLikeLiveVideo(null, mV2XRoadEventEntity.getSn());
}
delayedCloseWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 延迟关闭窗体
*/
private void delayedCloseWindow() {
itemView.postDelayed(new Runnable() {
@Override
public void run() {
V2XPushEventScenario.getInstance().close();
}
}, 1000);
}
/**
* 导航规划路线
*/
private void startNavi() {
if (mV2XRoadEventEntity != null) {
MogoLatLng endPoint = new MogoLatLng(mV2XRoadEventEntity.getLat(), mV2XRoadEventEntity.getLon());
V2XServiceManager.getNavi().naviTo(endPoint);
V2XServiceManager.getMogoRegisterCenter().unregisterMogoNaviListener(MODULE_NAME);
V2XServiceManager.getMogoRegisterCenter().registerMogoNaviListener(MODULE_NAME, this);
delayedCloseWindow();
}
}
private void showTip(String msg) {
ToastUtils.setGravity(Gravity.CENTER, 0, 0);
View toastView = LayoutInflater.from(V2XServiceManager.getContext()).inflate(R.layout.toast_view, null);
TextView msgView = toastView.findViewById(R.id.tvFeedbackContent);
msgView.setText(msg);
ToastUtils.showCustomShort(toastView);
}
@Override
public void onCalculateSuccess() {
V2XServiceManager.getNavi().startNavi(true);
}
@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 onoCalculateFailed() {
}
@Override
public void onUpdateTraffic(MogoTraffic traffic) {
}
}

View File

@@ -0,0 +1,435 @@
package com.mogo.module.v2x.adapter.holder;
import android.content.Intent;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.elegant.utils.ArrayUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.voice.AIAssist;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerUserInfo;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XConst;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.entity.net.V2XUserInfoRes;
import com.mogo.module.common.entity.V2XEventShowEntity;
import com.mogo.module.common.entity.V2XLiveCarInfoEntity;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.common.entity.V2XRoadEventEntity;
import com.mogo.module.common.entity.V2XWindowTypeEnum;
import com.mogo.module.v2x.network.V2XRefreshCallback;
import com.mogo.module.v2x.scenario.scene.livecar.V2XRoadLiveCarScenario;
import com.mogo.module.v2x.scenario.scene.road.V2XRoadEventScenario;
import com.mogo.module.v2x.scenario.scene.road.V2XRoadEventWindow;
import com.mogo.module.v2x.utils.ChartingUtil;
import com.mogo.module.v2x.utils.EventTypeUtils;
import com.mogo.module.v2x.utils.RoadConditionUtils;
import com.mogo.module.v2x.utils.ToastUtils;
import com.mogo.module.v2x.utils.TrackUtils;
import com.mogo.module.v2x.utils.V2XUtils;
import com.mogo.module.v2x.voice.V2XVoiceCallbackListener;
import com.mogo.module.v2x.voice.V2XVoiceConstants;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.utils.DateTimeUtils;
import com.mogo.utils.logger.Logger;
import com.zhidao.utils.common.GsonUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:35 PM
* desc : 道路事件详情
* version: 1.0
*/
public class V2XRoadEventDetailVH extends RecyclerView.ViewHolder {
private MogoImageView ivEventImg;
private MogoImageView ivReportHead;
private ImageView ivEventPlay;
// 控制按钮
private TextView tvEventTypeTitle;
private TextView tvEventAddress;
private TextView tvEventDistance;
private TextView tvEventTime;
private ImageView ivEventLive;
private ImageView ivEventCallChart;
private ImageView ivEventReportTrue;
private ImageView ivEventReportErr;
private ImageView ivEventZan;
// 上传事件的用户信息
private MarkerUserInfo mUserInfo = new MarkerUserInfo();
// 当前的新鲜事儿信息
private MarkerExploreWay mNoveltyInfo;
private V2XRoadEventEntity mV2XRoadEventEntity;
private V2XEventShowEntity mV2XEventShowEntity;
// 拨打车聊聊语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackCallListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
roadCallChart(mNoveltyInfo);
}
};
// 点赞语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackLickListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
handlerZan(mNoveltyInfo);
}
};
// 反馈"正确"语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackReportTrueListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
roadReportTrue(mNoveltyInfo);
}
};
// 反馈"错误"语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackReportErrorListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
roadReportErr(mNoveltyInfo);
}
};
// 反馈"错误"语音回调
private V2XVoiceCallbackListener v2XVoiceOpenLiveListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
showLiveCar(mV2XEventShowEntity);
}
};
private void init(View itemView) {
ivEventImg = itemView.findViewById(R.id.ivEventImg);
ivReportHead = itemView.findViewById(R.id.ivEventHead);
ivEventPlay = itemView.findViewById(R.id.ivEventPlay);
tvEventTypeTitle = itemView.findViewById(R.id.tvEventTypeTitle);
tvEventAddress = itemView.findViewById(R.id.tvEventAddress);
tvEventDistance = itemView.findViewById(R.id.tvEventDistance);
tvEventTime = itemView.findViewById(R.id.tvEventTime);
ivEventLive = itemView.findViewById(R.id.ivEventLive);
ivEventCallChart = itemView.findViewById(R.id.ivEventCallChart);
ivEventZan = itemView.findViewById(R.id.ivEventZan);
ivEventReportTrue = itemView.findViewById(R.id.ivEventReportTrue);
ivEventReportErr = itemView.findViewById(R.id.ivEventReportErr);
}
public V2XRoadEventDetailVH(ViewGroup viewGroup) {
super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_v2x_event_detail, viewGroup, false));
init(itemView);
// 设置视图状态监听
itemView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
// Logger.w(MODULE_NAME, "列表View V2XRoadEventDetailVH 触发 onViewAttachedToWindow");
// 注册语音交互
V2XVoiceManager.INSTANCE
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_CHATTING,
v2XVoiceCallbackCallListener)
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_ZAN,
v2XVoiceCallbackLickListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CHAT_MORE_UN_WAKEUP,
v2XVoiceCallbackCallListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_ZAN_UN_WAKEUP,
v2XVoiceCallbackLickListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_FEEDBACK_TRUE,
v2XVoiceCallbackReportTrueListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_FEEDBACK_ERROR,
v2XVoiceCallbackReportErrorListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
// Logger.w(MODULE_NAME, "列表View V2XRoadEventDetailVH 触发 onViewDetachedFromWindow");
}
});
}
public void initView(V2XEventShowEntity v2XEventShowEntity) {
try {
if (v2XEventShowEntity == null) {
return;
}
mV2XEventShowEntity = v2XEventShowEntity;
mV2XRoadEventEntity = v2XEventShowEntity.getV2XRoadEventEntity();
if (mV2XRoadEventEntity == null) {
return;
}
mNoveltyInfo = mV2XRoadEventEntity.getNoveltyInfo();
if (mNoveltyInfo != null) {
//Logger.d(MODULE_NAME, "mContentData" + mContentData);
if (!ArrayUtils.isEmpty(mNoveltyInfo.getItems())) {
String imgUrl = mNoveltyInfo.getItems().get(0).getThumbnail();
if (TextUtils.isEmpty(imgUrl)) {
imgUrl = mNoveltyInfo.getItems().get(0).getUrl();
}
if (!TextUtils.isEmpty(imgUrl)) {
V2XServiceManager.getImageLoader()
.displayImage(imgUrl, ivEventImg);
}
}
if (mNoveltyInfo.getUserInfo() != null &&
!TextUtils.isEmpty(mNoveltyInfo.getUserInfo().getUserHead())) {
V2XServiceManager.getImageLoader()
.displayImage(mNoveltyInfo.getUserInfo().getUserHead(), ivReportHead);
}
String poiType = EventTypeUtils.getPoiTypeStr(mNoveltyInfo.getPoiType());
if (!TextUtils.isEmpty(poiType)) {
tvEventTypeTitle.setText(poiType);
tvEventTypeTitle.setBackgroundResource(EventTypeUtils.getPoiTypeBg(mNoveltyInfo.getPoiType()));
}
tvEventAddress.setText(mNoveltyInfo.getAddr());
tvEventDistance.setText("距离 " + (int) mNoveltyInfo.getDistance() + "M");
Calendar c = Calendar.getInstance();
c.setTimeInMillis(mNoveltyInfo.getGenerateTime());
String eventTime = DateTimeUtils.printCalendarByPattern(c, "yyyy/MM/dd HH:mm");
if (!TextUtils.isEmpty(eventTime)) {
tvEventTime.setText(eventTime);
}
// 事件距离车辆小于50米的时候可以用户纠错
if (mV2XRoadEventEntity.getDistance() < 50) {
ivEventReportTrue.setVisibility(VISIBLE);
ivEventReportErr.setVisibility(VISIBLE);
ivEventLive.setVisibility(GONE);
ivEventZan.setVisibility(GONE);
} else {
if (!ArrayUtils.isEmpty(mV2XEventShowEntity.getV2XLiveCarList())) {
ivEventLive.setVisibility(VISIBLE);
V2XVoiceManager.INSTANCE
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_LIVE_ROAD,
v2XVoiceOpenLiveListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_LIVE_UN_WAKEUP,
v2XVoiceOpenLiveListener);
ivEventLive.setOnClickListener(v -> {
showLiveCar(v2XEventShowEntity);
});
} else {
ivEventLive.setVisibility(GONE);
}
ivEventReportTrue.setVisibility(GONE);
ivEventReportErr.setVisibility(GONE);
ivEventZan.setVisibility(VISIBLE);
// 用户上报的才会展示拨打电话
if (!TextUtils.isEmpty(mNoveltyInfo.getUploadType())
&& mNoveltyInfo.getUploadType().equals("1")) {
requestUserInfo(mNoveltyInfo);
}
}
ivEventReportTrue.setOnClickListener(v -> {
roadReportTrue(mNoveltyInfo);
});
ivEventReportErr.setOnClickListener(v -> {
roadReportErr(mNoveltyInfo);
});
ivEventCallChart.setOnClickListener(v -> {
ivEventCallChart.setVisibility(GONE);
roadCallChart(mNoveltyInfo);
});
ivEventZan.setOnClickListener(v -> {
handlerZan(mNoveltyInfo);
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 展示直播信息
*
* @param v2XEventShowEntity
*/
private void showLiveCar(V2XEventShowEntity v2XEventShowEntity) {
if (v2XEventShowEntity != null) {
// 展示周边的直播车辆
List<V2XEventShowEntity> eventShowEntityArrayList = new ArrayList<>();
for (V2XLiveCarInfoEntity v2XLiveCarInfoRes : v2XEventShowEntity.getV2XLiveCarList()) {
V2XEventShowEntity showEntity = new V2XEventShowEntity();
showEntity.setViewType(V2XWindowTypeEnum.LIVE_CAR_WINDOW);
showEntity.setV2XLiveCarInfoRes(v2XLiveCarInfoRes);
showEntity.setV2XRoadEventEntity(mV2XRoadEventEntity);
eventShowEntityArrayList.add(showEntity);
}
Logger.d(MODULE_NAME, "要展示的直播:" + GsonUtil.jsonFromObject(eventShowEntityArrayList));
V2XMessageEntity<List<V2XEventShowEntity>> v2XMessageEntity = new V2XMessageEntity<>();
v2XMessageEntity.setType(V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_LIVE_CAR_WARNING);
v2XMessageEntity.setContent(eventShowEntityArrayList);
v2XMessageEntity.setShowState(true);
V2XRoadLiveCarScenario.getInstance().init(v2XMessageEntity);
// 打开直播后,窗口倒计时暂停关闭,直播被关闭后继续倒计时
V2XRoadEventWindow window = (V2XRoadEventWindow) V2XRoadEventScenario.getInstance().getV2XWindow();
window.stopCountDown();
}
}
private void requestUserInfo(MarkerExploreWay noveltyInfo) {
Logger.d(MODULE_NAME, "上报事件的用户SN" + noveltyInfo.getSn());
// 获取道路事件周边的直播车机
if (!TextUtils.isEmpty(noveltyInfo.getSn())) {
V2XServiceManager
.getV2XRefreshModel()
.queryUserInfoBySn(
noveltyInfo.getSn(),
new V2XRefreshCallback<V2XUserInfoRes>() {
@Override
public void onSuccess(V2XUserInfoRes result) {
if (result != null && result.getResult() != null && result.getResult().getInfo() != null) {
V2XUserInfoRes.Result.Info infoBean = result.getResult().getInfo();
if (mUserInfo == null) {
mUserInfo = new MarkerUserInfo();
}
mUserInfo.setSn(infoBean.getSn());
try {
if (!TextUtils.isEmpty(infoBean.getCardIdAge())) {
mUserInfo.setAge(Integer.parseInt(infoBean.getCardIdAge()));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
mUserInfo.setUserName(infoBean.getUserNickName());
mUserInfo.setUserHead(infoBean.getHeadImgUrl());
mUserInfo.setGender(infoBean.getCardIdSex());
if (DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_SELF_INNOVATE) {
// 判断是否可以打电话
ChartingUtil.isCanCall(b -> {
if (b) {
// 判断是否可以打电话
ChartingUtil.isOnLine(mUserInfo.getSn(), b1 -> {
if (b1) {
ivEventCallChart.setVisibility(VISIBLE);
} else {
ivEventCallChart.setVisibility(GONE);
}
});
} else {
ivEventCallChart.setVisibility(GONE);
}
});
}
}
}
@Override
public void onFail(String msg) {
ivEventCallChart.setVisibility(GONE);
}
});
}
}
/**
* 打电话
*/
private void roadCallChart(MarkerExploreWay noveltyInfo) {
MarkerLocation location = new MarkerLocation();
mUserInfo.setSn(noveltyInfo.getSn());
ChartingUtil.callChatting(mUserInfo, location);
TrackUtils.trackV2xRoadEvent(noveltyInfo.getInfoId(), noveltyInfo.getUserInfo().getSn(), V2XConst.V2X_ROAD_CHAT);
}
/**
* 反馈路况错误
*/
private void roadReportErr(MarkerExploreWay noveltyInfo) {
if (noveltyInfo != null) {
RoadConditionUtils.sendDataErrorReceiverInfo(
noveltyInfo.getPoiType(),
noveltyInfo.getInfoId(),
"1");
TrackUtils.trackV2xRoadEvent(noveltyInfo.getInfoId(), noveltyInfo.getUserInfo().getSn(), V2XConst.V2X_ROAD_REPORT_ERROR);
}
delayedCloseWindow();
}
/**
* 反馈路况正确
*/
private void roadReportTrue(MarkerExploreWay noveltyInfo) {
if (noveltyInfo != null) {
RoadConditionUtils.sendDataErrorReceiverInfo(
noveltyInfo.getPoiType(),
noveltyInfo.getInfoId(),
"2");
TrackUtils.trackV2xRoadEvent(noveltyInfo.getInfoId(), noveltyInfo.getUserInfo().getSn(), V2XConst.V2X_ROAD_REPORT_RIGHT);
}
delayedCloseWindow();
}
/**
* 点赞
*/
private void handlerZan(MarkerExploreWay noveltyInfo) {
try {
AIAssist.getInstance(V2XUtils.getApp()).speakTTSVoice("已点赞", null);
showTip("已点赞");
if (noveltyInfo != null) {
V2XServiceManager.getV2XMarkerService()
.getV2XRefreshModel()
.giveLikeLiveVideo(null, noveltyInfo.getSn());
}
delayedCloseWindow();
} catch (Exception e) {
e.printStackTrace();
}
TrackUtils.trackV2xRoadEvent(noveltyInfo.getInfoId(), noveltyInfo.getUserInfo().getSn(), V2XConst.V2X_ROAD_ZAN);
}
/**
* 延迟关闭窗体
*/
private void delayedCloseWindow() {
itemView.postDelayed(new Runnable() {
@Override
public void run() {
// 移除窗体
V2XServiceManager
.getIMogoWindowManager()
.removeView(V2XRoadEventScenario.getInstance().getV2XWindow().getView());
V2XRoadEventScenario.getInstance().close();
}
}, 1000);
}
private void showTip(String msg) {
ToastUtils.setGravity(Gravity.CENTER, 0, 0);
View toastView = LayoutInflater.from(V2XServiceManager.getContext()).inflate(R.layout.toast_view, null);
TextView msgView = toastView.findViewById(R.id.tvFeedbackContent);
msgView.setText(msg);
ToastUtils.showCustomShort(toastView);
}
}

View File

@@ -0,0 +1,408 @@
package com.mogo.module.v2x.alarm;
import android.text.TextUtils;
import com.mogo.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.search.geo.IMogoGeoSearchListener;
import com.mogo.map.search.geo.MogoGeocodeResult;
import com.mogo.map.search.geo.MogoPoiItem;
import com.mogo.map.search.geo.MogoRegeocodeResult;
import com.mogo.map.search.poisearch.IMogoPoiSearch;
import com.mogo.map.search.poisearch.IMogoPoiSearchListener;
import com.mogo.map.search.poisearch.MogoPoiResult;
import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.V2XPoiTypeEnum;
import com.mogo.module.common.entity.V2XPushMessageEntity;
import com.mogo.module.common.entity.V2XRoadEventEntity;
import com.mogo.module.service.Utils;
import com.mogo.module.v2x.V2XConst;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.entity.net.V2XStrategyPushRes;
import com.mogo.module.v2x.utils.DrivingDirectionUtils;
import com.mogo.module.v2x.utils.FatigueDrivingUtils;
import com.mogo.module.v2x.utils.LocationUtils;
import com.mogo.module.v2x.utils.TimeConstants;
import com.mogo.module.v2x.utils.TimeUtils;
import com.mogo.module.v2x.utils.V2XUtils;
import com.mogo.utils.ArrayUtils;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.storage.SharedPrefsMgr;
import com.zhidao.utils.common.GsonUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.CopyOnWriteArrayList;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/13 11:02 AM
* desc :
* 这里是车机端自己实现预警信息的触发操作首先获取当前车位置周围2公里范围的道路事件
* 普通模式根据当前「车辆位置」及「行驶方向」判断「车辆前方」「500米」是否有道路事件需要触发。
* 导航模式根据当前「路径规划」及「行驶方向」判断「路径前方」「500米」是否有道路事件需要触发。
* version: 1.0
*/
public class V2XAlarmServer {
// 记录道路播报的事件
private static HashMap<V2XRoadEventEntity, String> mAlertRoadEventList = new HashMap<>();
private static HashSet<V2XRoadEventEntity> mAlertRoadEventCorrectionList = new HashSet<>();
// 记录违章停车播报事件
private static HashMap<MarkerExploreWay, String> mAlertIllegalParkEventList = new HashMap<>();
// 记录疲劳驾驶播报的事件
private static HashSet<String> mV2XFatigueDrivingEventLevel = new HashSet<>();
/**
* 获取当前车辆前方距离最近的道路事件
*/
public static V2XRoadEventEntity getDriveFrontAlarmEvent(
CopyOnWriteArrayList<V2XRoadEventEntity> v2XRoadEventEntityList,
MogoLocation currentLocation) {
try {
// Logger.w(MODULE_NAME, "V2X预警--车辆状态:" + currentLocation);
// Logger.w(MODULE_NAME, "V2X预警--车辆速度:" + currentLocation.getSpeed());
// Logger.w(MODULE_NAME, "V2X预警--v2XRoadEventEntityList" + GsonUtil.jsonFromObject(v2XRoadEventEntityList));
// 60(km/h)
if (currentLocation != null && v2XRoadEventEntityList != null) {
// 因为集合是按照距离排序后的所以这里检索出来第一个就发出警告
for (V2XRoadEventEntity v2XRoadEventEntity : v2XRoadEventEntityList) {
// 先计算当前车辆的车头朝向是否与事件方向相同这里采用的是区间值只要在20度上下即可使用
// 道路事件必须有朝向,角度>=0;
//Logger.w(MODULE_NAME,
// "V2X预警--车辆与事件信息:" +
// "\n事件名称" + markerNoveltyInfo.getNoveltyInfo().getContentData().getTitle() +
// "\n事件角度" + markerNoveltyInfo.getLocation().getAngle() +
// "\n车头角度" + currentLocation.getAngle() +
// "\n角度差值" + Math.abs(currentLocation.getAngle() - markerNoveltyInfo.getLocation().getAngle()));
if (v2XRoadEventEntity.getLocation().getAngle() >= 0 &&
Math.abs(currentLocation.getBearing() - v2XRoadEventEntity.getLocation().getAngle()) <= 10) {
// 计算车辆距离指定气泡的距离
MarkerLocation eventLocation = v2XRoadEventEntity.getLocation();
// 判断是否到达了触发距离,20 ~ 500,
if (v2XRoadEventEntity.getDistance() <= 500) {
double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
currentLocation.getLongitude(),
currentLocation.getLatitude(),
eventLocation.getLon(),
eventLocation.getLat(),
(int) currentLocation.getBearing()
);
// Logger.w(MODULE_NAME, "V2X预警--事件位置===" + eventLocation);
if (0 <= eventAngle && eventAngle <= 20) {
// 判断是否已经提示过道路事件
boolean isAlreadyAlert = false;
String lastTime = mAlertRoadEventList.get(v2XRoadEventEntity);
if (!TextUtils.isEmpty(lastTime)) {
long timeSpan = TimeUtils.getTimeSpanByNow(lastTime, TimeConstants.MIN);
// Logger.w(MODULE_NAME,
// "V2X预警--事件ID" + v2XRoadEventEntity.getNoveltyInfo().getInfoId() +
// "\n上一次预警时间" + lastTime +
// "\n距离当前时间" + timeSpan);
// 5分钟内不重复提醒
if (timeSpan < 5) {
isAlreadyAlert = true;
}
}
// 判断是否是纠错,如果是纠错就忽略掉带有时间段的道路提醒
if (v2XRoadEventEntity.getDistance() <= 50) {
if (!mAlertRoadEventCorrectionList.contains(v2XRoadEventEntity)) {
mAlertRoadEventCorrectionList.add(v2XRoadEventEntity);
isAlreadyAlert = false;
}
}
// Logger.w(MODULE_NAME, "V2X预警--车辆与事件信息:" +
// "\n距离" + v2XRoadEventEntity.getDistance() + "米" +
// "\n是否已经提醒" + isAlreadyAlert +
// "\n事件ID" + v2XRoadEventEntity.getNoveltyInfo().getInfoId() +
// "\n事件详情" + GsonUtil.jsonFromObject(v2XRoadEventEntity.getNoveltyInfo())
// );
// 进行提醒
if (!isAlreadyAlert) {
mAlertRoadEventList.put(v2XRoadEventEntity, TimeUtils.getNowString());
return v2XRoadEventEntity;
}
return null;
} else {
// Logger.w(MODULE_NAME, "V2X预警--车辆与事件信息:" +
// "\n角度" + eventAngle + " 度" +
// "\n事件详情" + v2XRoadEventEntity.getNoveltyInfo().getInfoId()
// );
}
} else {
// Logger.w(MODULE_NAME, "V2X预警--车辆与事件信息:" +
// "\n距离" + v2XRoadEventEntity.getDistance() + "米" +
// "\n事件详情" + v2XRoadEventEntity.getNoveltyInfo().getInfoId()
// );
}
} else {
// Logger.w(MODULE_NAME,
// "车头方向: " + currentLocation.getAngle() +
// "\n事件方向" + v2XRoadEventEntity.getLocation().getAngle()
// );
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 疲劳驾驶的展示数据
* 分级说明:
* 1驾驶时段 0-2小时为正常状态
* 2驾驶时段2-3小时为轻度疲劳
* 3驾驶时段3-4小时为中度疲劳
* 4驾驶时段4小时以上为重度疲劳
*/
public static void getFatigueDrivingShow(MogoLocation location, OnFatigueDrivingListener onFatigueDrivingListener) {
try {
long drivingTime = FatigueDrivingUtils.getDrivingTime();
//Logger.i(V2XConst.MODULE_NAME, "车机已经开机: " + drivingTime + " 分钟");
V2XStrategyPushRes.ResultBean strategyPushEntity =
GsonUtil.objectFromJson(SharedPrefsMgr.getInstance(V2XUtils.getApp())
.getString(V2XConst.V2X_STRATEGY_PUSH), V2XStrategyPushRes.ResultBean.class);
V2XPushMessageEntity drivingShowEntity = new V2XPushMessageEntity();
drivingShowEntity.setSceneId(V2XPoiTypeEnum.ALERT_FATIGUE_DRIVING);
if (strategyPushEntity != null &&
!ArrayUtils.isEmpty(strategyPushEntity.getLevelList())) {
for (V2XStrategyPushRes.ResultBean.LevelListBean levelListBean :
strategyPushEntity.getLevelList()) {
// 找到当前驾驶时常对应的疲劳等级
if (drivingTime >= levelListBean.getMinMinute()
&& drivingTime < levelListBean.getMaxMinute()) {
//疲劳等级NORMAL-正常、SLIGHT-轻度、MODERATE-中度、SEVERE-重度
switch (levelListBean.getLevel()) {
//正常
case "NORMAL":
Logger.d(MODULE_NAME, "驾驶疲劳程度: 正常");
break;
//轻度
case "SLIGHT":
Logger.w(MODULE_NAME, "驾驶疲劳程度: 轻度");
if (!mV2XFatigueDrivingEventLevel.contains("SLIGHT")) {
mV2XFatigueDrivingEventLevel.add("SLIGHT");
drivingShowEntity.setShowWindow(false);
drivingShowEntity.setAlarmContent(levelListBean.getContent());
drivingShowEntity.setTts(levelListBean.getTts());
drivingShowEntity.setExpireTime(levelListBean.getShowSeconds());
// 回调提醒
if (onFatigueDrivingListener != null) {
onFatigueDrivingListener.onAlarmMessage(drivingShowEntity);
}
}
break;
//中度
case "MODERATE":
Logger.e(MODULE_NAME, "驾驶疲劳程度: 中度");
warningParkPoi(location, onFatigueDrivingListener, drivingShowEntity, levelListBean);
break;
//重度
case "SEVERE":
Logger.e(MODULE_NAME, "驾驶疲劳程度: 重度");
break;
default:
Logger.e(MODULE_NAME, "驾驶疲劳程度: 超出定义范围");
break;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 提醒停车
private static void warningParkPoi(MogoLocation location,
OnFatigueDrivingListener onFatigueDrivingListener,
V2XPushMessageEntity drivingShowEntity,
V2XStrategyPushRes.ResultBean.LevelListBean levelListBean) {
if (!mV2XFatigueDrivingEventLevel.contains("MODERATE")) {
mV2XFatigueDrivingEventLevel.add("MODERATE");
// 定位当前位置是否是高速
LocationUtils.geoCodeSearch(location, new IMogoGeoSearchListener() {
@Override
public void onRegeocodeSearched(MogoRegeocodeResult regeocodeResult) {
Logger.i(MODULE_NAME, "根据经纬度查询结果为:" + regeocodeResult.getRegeocodeAddress().getFormatAddress());
String keyword = "停车场";
boolean isHighWay = false;
// 如果当前位置是高速则推荐服务区
if (regeocodeResult.getRegeocodeAddress().getFormatAddress().contains("高速")) {
keyword = "停车场|服务区";
isHighWay = true;
}
MogoPoiSearchQuery poiSearchQuery = new MogoPoiSearchQuery(keyword, keyword);
poiSearchQuery.setPageSize(5);
poiSearchQuery.setLocation(LocationUtils.getCurrentLatLon());
IMogoPoiSearch poiSearch = V2XServiceManager.getMapService().getPoiSearch(V2XUtils.getApp(), poiSearchQuery);
boolean finalIsHighWay = isHighWay;
poiSearch.setPoiSearchListener(new IMogoPoiSearchListener() {
@Override
public void onPoiSearched(MogoPoiResult result, int errorCode) {
Logger.i(MODULE_NAME, "附近的停车场/服务区:" + GsonUtil.jsonFromObject(result));
drivingShowEntity.setAlarmContent(levelListBean.getContent());
ArrayList<MogoPoiItem> pois = result.getPois();
if (pois.size() > 0) {
MogoPoiItem mogoPoiItem = getFrontPoi(finalIsHighWay, pois, location);
Logger.e(MODULE_NAME, "推荐车头前方最近的停车场/服务区:" + GsonUtil.jsonFromObject(mogoPoiItem));
if (mogoPoiItem != null) {
drivingShowEntity.setExpireTime(levelListBean.getShowSeconds());
drivingShowEntity.setShowWindow(true);
drivingShowEntity.setTts(levelListBean.getTts());
drivingShowEntity.setLon(mogoPoiItem.getPoint().getLon());
drivingShowEntity.setLat(mogoPoiItem.getPoint().getLat());
drivingShowEntity.setAddress(mogoPoiItem.getTitle());
float calculateDistance = Utils.calculateLineDistance(
new MogoLatLng(mogoPoiItem.getPoint().getLat(), mogoPoiItem.getPoint().getLon()),
LocationUtils.getCurrentLatLon()
);
drivingShowEntity.setDistance(calculateDistance);
} else {
drivingShowEntity.setShowWindow(false);
drivingShowEntity.setTts(levelListBean.getNoReTts());
}
} else {
drivingShowEntity.setShowWindow(false);
drivingShowEntity.setTts(levelListBean.getNoReTts());
}
// 回调提醒
if (onFatigueDrivingListener != null) {
onFatigueDrivingListener.onAlarmMessage(drivingShowEntity);
}
}
@Override
public void onPoiItemSearched(MogoPoiItem item, int errorCode) {
}
});
poiSearch.searchPOIAsyn();
}
@Override
public void onGeocodeSearched(MogoGeocodeResult geocodeResult) {
}
});
}
}
public interface OnFatigueDrivingListener {
void onAlarmMessage(V2XPushMessageEntity drivingShowEntity);
}
// 计算出与车头朝向相同的poi点
public static MogoPoiItem getFrontPoi(boolean isHighWay, ArrayList<MogoPoiItem> pois, MogoLocation location) {
if (location != null && pois != null) {
// (高速道路)推荐道路前方180度服务区限定30公里
// (非高速推荐停车场限定5公里内
for (MogoPoiItem poiItem : pois) {
// 计算距离
float calculateDistance = Utils.calculateLineDistance(
new MogoLatLng(poiItem.getPoint().getLat(), poiItem.getPoint().getLon()),
LocationUtils.getCurrentLatLon()
);
Logger.e(MODULE_NAME, "车辆距离POI点距离" + calculateDistance);
Logger.e(MODULE_NAME, "当前车辆是否在高速:" + isHighWay);
if (isHighWay) {
if (calculateDistance > 100 && calculateDistance < 30000) {
// 计算角度
double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
location.getLongitude(),
location.getLatitude(),
poiItem.getPoint().getLon(),
poiItem.getPoint().getLat(),
(int) location.getBearing()
);
Logger.e(MODULE_NAME, "车辆距离POI角度" + eventAngle);
// 车辆前方180度
if (0 <= eventAngle && eventAngle <= 90) {
return poiItem;
}
}
} else {
if (calculateDistance < 5000) {
return poiItem;
}
}
}
}
return null;
}
/**
* 获取车辆的前方的违章停车事件
*/
public static MarkerExploreWay getIllegalParkAlarmEvent(
ArrayList<MarkerExploreWay> v2XExploreWayEntityList,
MogoLocation currentLocation) {
try {
Logger.w(MODULE_NAME, "V2X预警--车辆状态:" + currentLocation);
// 60(km/h)
if (currentLocation != null && v2XExploreWayEntityList != null) {
// 因为集合是按照距离排序后的所以这里检索出来第一个就发出警告
for (MarkerExploreWay markerExploreWay : v2XExploreWayEntityList) {
// 计算车辆距离
float distance = Utils.calculateLineDistance(
new MogoLatLng(markerExploreWay.getLocation().getLat(), markerExploreWay.getLocation().getLon()),
new MogoLatLng(currentLocation.getLatitude(), currentLocation.getLongitude())
);
Logger.w(MODULE_NAME, "V2X预警--车辆与违章道路信息:" +
"\n当前车辆距离违章停车点" + distance);
// 判断是否到达了触发距离,50 米
if (distance <= 50) {
Logger.w(MODULE_NAME, "V2X预警--车辆与违章道路信息:" +
"\n违章道路名称" + markerExploreWay.getAddr() +
"\n车头角度" + currentLocation.getBearing());
// 判断是否已经提示过道路事件
boolean isAlreadyAlert = false;
String lastTime = mAlertIllegalParkEventList.get(markerExploreWay);
Logger.w(MODULE_NAME,
"V2X预警--事件ID" + markerExploreWay.getInfoId() +
"\n上一次预警时间" + lastTime);
if (!TextUtils.isEmpty(lastTime)) {
long timeSpan = TimeUtils.getTimeSpanByNow(lastTime, TimeConstants.MIN);
Logger.w(MODULE_NAME,
"V2X预警--事件ID" + markerExploreWay.getInfoId() +
"\n距离当前时间" + timeSpan);
// 5分钟内不重复提醒
if (timeSpan < 5) {
isAlreadyAlert = true;
}
}
// 进行提醒
if (!isAlreadyAlert) {
mAlertIllegalParkEventList.put(markerExploreWay, TimeUtils.getNowString());
return markerExploreWay;
}
return null;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,150 @@
package com.mogo.module.v2x.alarm;
import android.os.Handler;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.v2x.V2XConst;
import com.mogo.module.v2x.V2XStatusManager;
import com.mogo.module.v2x.listener.CarStatusListener;
import com.mogo.utils.logger.Logger;
import java.util.HashMap;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/13 11:02 AM
* desc :
* 这里充当计算服务
* 计算 当前 车速变化回调、方向角度
* version: 1.0
*/
public class V2XCalculateServer {
private static final String TAG = "V2XCalculateServer";
// 当前的车辆位置,主要用 经纬度,角度,速度
private static MogoLocation mCurrentLocation;
// 是否处于停车状态
private static boolean mIsPark = true;
// 没有行驶的次数
private static int mNoDriveCount = 0;
private static HashMap<String, CarStatusListener> mCarStatusListener = new HashMap<>();
private static V2XCalculateServer mV2XCalculateServer;
// 一分钟获取一次最新的路况信息
private static final int refreshTime = 5_000;
private static Handler refreshHandler;
private static Runnable refreshRunnable;
private V2XCalculateServer() {
}
public synchronized static V2XCalculateServer getInstance() {
synchronized (V2XCalculateServer.class) {
if (mV2XCalculateServer == null) {
mV2XCalculateServer = new V2XCalculateServer();
if (refreshHandler == null) {
refreshHandler = new Handler();
}
if (refreshRunnable == null) {
refreshRunnable = new Runnable() {
@Override
public void run() {
calculateCarStatus();
refreshHandler.postDelayed(this, refreshTime);
}
};
}
refreshHandler.post(refreshRunnable);
}
}
return mV2XCalculateServer;
}
/**
* 添加车辆状态监听
*
* @param tag 标记
* @param carStatusListener 回调
*/
public void addCarStatusListener(String tag, CarStatusListener carStatusListener) {
if (mCarStatusListener == null) {
mCarStatusListener = new HashMap<>();
}
mCarStatusListener.put(tag, carStatusListener);
}
/**
* 移除指定的标记的回调
*
* @param tag 标记
*/
public void removeCarStatusListener(String tag) {
if (mCarStatusListener != null) {
mCarStatusListener.remove(tag);
}
}
/**
* 记录车辆行驶轨迹
*
* @param location 车辆位置
*/
public void addCarTrajectory(MogoLocation location) {
// 记录最后一次车辆位置信息
mCurrentLocation = location;
// 车辆状态计算
calculateCarStatus();
}
/**
* 计算车辆状态
*/
private static void calculateCarStatus() {
if (mCurrentLocation != null) {
// 获取当前的车速
float currentSpeed = mCurrentLocation.getSpeed();
// Logger.d(V2XConst.MODULE_NAME + "_" + TAG, "车辆状态:" +
// "\n当前车辆位置->" + V2XStatusManager.getInstance().getLocation().getAddress() +
// "\ncurrentSpeed 速度->" + currentSpeed +
// "\n车辆行驶状态mIsPark->" + mIsPark +
// "\nmNoDriveCount->" + mNoDriveCount);
// 获取没有车速
if (currentSpeed == 0) {
// 防止重复播报
if (!mIsPark) {
// 超过 2 次的速度为 0 ,判定为 行驶->停止
if ((++mNoDriveCount) > 2) {
if (mCarStatusListener != null) {
Logger.d(V2XConst.MODULE_NAME, "车辆状态:车辆从 行驶->停止");
mIsPark = true;
for (CarStatusListener statusListener : mCarStatusListener.values()) {
statusListener.onCarDriving2Stop(mCurrentLocation);
}
}
}
}
}
// 获取到了车速 大于 3m/s = 10公里/小时 判定为行驶状态
else if (currentSpeed > 3) {
mNoDriveCount = 0;
if (mIsPark) {
if (mCarStatusListener != null) {
Logger.d(V2XConst.MODULE_NAME, "车辆状态:车辆从 停止->行驶");
mIsPark = false;
for (CarStatusListener statusListener : mCarStatusListener.values()) {
statusListener.onCarStop2Driving(mCurrentLocation);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,280 @@
package com.mogo.module.v2x.entity.net;
import android.text.TextUtils;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.mogo.commons.data.BaseData;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerOnlineCar;
import java.io.Serializable;
import java.util.ArrayList;
@SuppressWarnings("unused")
public class V2XAlarmEventRes extends BaseData implements Serializable {
@Expose
private Result result;
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
public class Result {
@Expose
@SerializedName(value = "recommendInfo", alternate = {"alarmInfo"})
private AlarmInfo alarmInfo;
@Expose
private ArrayList<MarkerOnlineCar> onlineCar;
public ArrayList<MarkerOnlineCar> getOnlineCar() {
return onlineCar;
}
public void setOnlineCar(ArrayList<MarkerOnlineCar> onlineCar) {
this.onlineCar = onlineCar;
}
public AlarmInfo getAlarmInfo() {
return alarmInfo;
}
public void setAlarmInfo(AlarmInfo alarmInfo) {
this.alarmInfo = alarmInfo;
}
@Override
public String toString() {
return "Result{" +
"alarmInfo=" + alarmInfo +
", onlineCar=" + onlineCar +
'}';
}
}
public static class AlarmInfo {
@Expose
private ContentData contentData;
@Expose
private Double distance;
@Expose
private MarkerLocation location;
@Expose
private String poiType;
@Expose
private String tts;
@Expose
private String type;
@Expose
private String alarmContent;
@Expose
private int expireTime;
@Expose
private int parkingSpaceSurplusNum;
public ContentData getContentData() {
return contentData;
}
public void setContentData(ContentData contentData) {
this.contentData = contentData;
}
public Double getDistance() {
return distance;
}
public void setDistance(Double distance) {
this.distance = distance;
}
public MarkerLocation getLocation() {
return location;
}
public void setLocation(MarkerLocation location) {
this.location = location;
}
public String getPoiType() {
if (TextUtils.isEmpty(poiType)) {
return "";
}
return poiType;
}
public void setPoiType(String poiType) {
this.poiType = poiType;
}
public String getTts() {
if (TextUtils.isEmpty(tts)) {
return "";
}
return tts;
}
public void setTts(String tts) {
this.tts = tts;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAlarmContent() {
return alarmContent;
}
public void setAlarmContent(String alarmContent) {
this.alarmContent = alarmContent;
}
public int getExpireTime() {
return expireTime;
}
public void setExpireTime(int expireTime) {
this.expireTime = expireTime;
}
public int getParkingSpaceSurplusNum() {
return parkingSpaceSurplusNum;
}
public void setParkingSpaceSurplusNum(int parkingSpaceSurplusNum) {
this.parkingSpaceSurplusNum = parkingSpaceSurplusNum;
}
@Override
public String toString() {
return "AlarmInfo{" +
"contentData=" + contentData +
", distance=" + distance +
", location=" + location +
", poiType='" + poiType + '\'' +
", tts='" + tts + '\'' +
", type='" + type + '\'' +
", alarmContent='" + alarmContent + '\'' +
", expireTime=" + expireTime +
", parkingSpaceSurplusNum=" + parkingSpaceSurplusNum +
'}';
}
}
public class ContentData {
@Expose
private String iconUrl;
@Expose
private String imgUrl;
@Expose
private String infoId = ""; // POI 唯一标示 「纠错」或「确认」「点赞」使用
@Expose
private String title;
@Expose
private String content;
@Expose
private String gasPrices;//"[{\"gasCode\":\"95\",\"gasPrice\":10.0},{\"gasCode\":\"98\",\"gasPrice\":23.0}]"
@Expose
private String styleType;// 内容类型image-图片类型video-视频类型
@Expose
private String carSn;// 如果是用户上报的,则需要返回该字段
public String getIconUrl() {
return iconUrl;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public String getInfoId() {
return infoId;
}
public void setInfoId(String infoId) {
this.infoId = infoId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getGasPrices() {
return gasPrices;
}
public void setGasPrices(String gasPrices) {
this.gasPrices = gasPrices;
}
public String getStyleType() {
return styleType;
}
public void setStyleType(String styleType) {
this.styleType = styleType;
}
public String getCarSn() {
return carSn;
}
public void setCarSn(String carSn) {
this.carSn = carSn;
}
@Override
public String toString() {
return "ContentData{" +
"iconUrl='" + iconUrl + '\'' +
", imgUrl='" + imgUrl + '\'' +
", infoId='" + infoId + '\'' +
", title='" + title + '\'' +
", content='" + content + '\'' +
", gasPrices='" + gasPrices + '\'' +
", styleType='" + styleType + '\'' +
", carSn='" + carSn + '\'' +
'}';
}
}
@Override
public String toString() {
return "V2XAlarmEventMessage{" +
"result=" + result +
'}';
}
}

View File

@@ -0,0 +1,258 @@
package com.mogo.module.v2x.entity.net;
import com.mogo.commons.data.BaseData;
import java.io.Serializable;
import java.util.List;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/24 4:20 PM
* desc : TODO 前瞻需求演示使用的用户数据
* version: 1.0
*/
public class V2XDemoUserInfoRes extends BaseData implements Serializable {
/**
* code : 0
* msg :
* detailMsg :
* result : {"userList":[{"sceneType":"1","location":{"lat":39.97541,"lon":116.41782761},"userInfo":{"sn":"ZD801B1920L00818","userId":1,"userName":"用户昵称","userHead":"https://www.baidu.com/img/baidu_jgylogo3.png","gender":"男","age":20,"lastActiveweekAvgscore":"96","safeLabel":"老司机","safeLabelType":1}},{"sceneType":"2","location":{"lat":39.97541,"lon":116.41782761},"userInfo":{"sn":"ZD802B1932L00779","userId":1,"userName":"用户昵称","userHead":"https://www.baidu.com/img/baidu_jgylogo3.png","gender":"男","age":20,"lastActiveweekAvgscore":"96","safeLabel":"老司机","safeLabelType":1}},{"sceneType":"3","location":{"lat":39.97541,"lon":116.41782761},"userInfo":{"sn":"ZD802B1932L00779","userId":1,"userName":"用户昵称","userHead":"https://www.baidu.com/img/baidu_jgylogo3.png","gender":"男","age":20,"lastActiveweekAvgscore":"96","safeLabel":"老司机","safeLabelType":1}}]}
*/
private ResultBean result;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public ResultBean getResult() {
return result;
}
public void setResult(ResultBean result) {
this.result = result;
}
public static class ResultBean {
private List<UserListBean> userList;
public List<UserListBean> getUserList() {
return userList;
}
public void setUserList(List<UserListBean> userList) {
this.userList = userList;
}
public static class UserListBean {
/**
* sceneType : 1
* location : {"lat":39.97541,"lon":116.41782761}
* userInfo : {"sn":"ZD801B1920L00818","userId":1,"userName":"用户昵称","userHead":"https://www.baidu.com/img/baidu_jgylogo3.png","gender":"男","age":20,"lastActiveweekAvgscore":"96","safeLabel":"老司机","safeLabelType":1}
*/
private String sceneType;
private LocationBean location;
private UserInfoBean userInfo;
public String getSceneType() {
return sceneType;
}
public void setSceneType(String sceneType) {
this.sceneType = sceneType;
}
public LocationBean getLocation() {
return location;
}
public void setLocation(LocationBean location) {
this.location = location;
}
public UserInfoBean getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfoBean userInfo) {
this.userInfo = userInfo;
}
public static class LocationBean {
/**
* lat : 39.97541
* lon : 116.41782761
*/
private double lat;
private double lon;
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
@Override
public String toString() {
return "LocationBean{" +
"lat=" + lat +
", lon=" + lon +
'}';
}
}
public static class UserInfoBean {
/**
* sn : ZD801B1920L00818
* userId : 1
* userName : 用户昵称
* userHead : https://www.baidu.com/img/baidu_jgylogo3.png
* gender : 男
* age : 20
* lastActiveweekAvgscore : 96
* safeLabel : 老司机
* safeLabelType : 1
*/
private String sn;
private int userId;
private String userName;
private String userHead;
private String gender;
private int age;
private String lastActiveweekAvgscore;
private String safeLabel;
private int safeLabelType;
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserHead() {
return userHead;
}
public void setUserHead(String userHead) {
this.userHead = userHead;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getLastActiveweekAvgscore() {
return lastActiveweekAvgscore;
}
public void setLastActiveweekAvgscore(String lastActiveweekAvgscore) {
this.lastActiveweekAvgscore = lastActiveweekAvgscore;
}
public String getSafeLabel() {
return safeLabel;
}
public void setSafeLabel(String safeLabel) {
this.safeLabel = safeLabel;
}
public int getSafeLabelType() {
return safeLabelType;
}
public void setSafeLabelType(int safeLabelType) {
this.safeLabelType = safeLabelType;
}
@Override
public String toString() {
return "UserInfoBean{" +
"sn='" + sn + '\'' +
", userId=" + userId +
", userName='" + userName + '\'' +
", userHead='" + userHead + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", lastActiveweekAvgscore='" + lastActiveweekAvgscore + '\'' +
", safeLabel='" + safeLabel + '\'' +
", safeLabelType=" + safeLabelType +
'}';
}
}
@Override
public String toString() {
return "UserListBean{" +
"sceneType='" + sceneType + '\'' +
", location=" + location +
", userInfo=" + userInfo +
'}';
}
}
}
@Override
public String toString() {
return "V2XDemoUserInfoEntity{" +
"result=" + result +
'}';
}
}

View File

@@ -0,0 +1,52 @@
package com.mogo.module.v2x.entity.net;
import com.google.gson.annotations.Expose;
import java.io.Serializable;
@SuppressWarnings("unused")
public class V2XGiveLike implements Serializable {
@Expose
private Long code;
@Expose
private String msg;
@Expose
private String result;
@Expose
private String sign;
public Long getCode() {
return code;
}
public void setCode(Long code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}

View File

@@ -0,0 +1,25 @@
package com.mogo.module.v2x.entity.net
/**
* 直播心跳请求
*/
class V2XLiveCarBroadcastReq {
var eventId: String? = null
var sn: String
var type: Int = 0
var videoChannel: String
constructor(sn: String, videoChannel: String) {
this.sn = sn
this.videoChannel = videoChannel
}
constructor(eventId: String, sn: String, type: Int, videoChannel: String) {
this.eventId = eventId
this.sn = sn
this.type = type
this.videoChannel = videoChannel
}
}

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