[V2X]V2XSDk功能代码提交

111
This commit is contained in:
renwj
2022-02-23 15:18:43 +08:00
parent 07d60fb48a
commit da609a15f5
46 changed files with 1507 additions and 339 deletions

9
.gitignore vendored
View File

@@ -1,16 +1,9 @@
*.iml *.iml
.gradle .gradle
/local.properties /local.properties
/.idea/caches
/.idea/libraries
/.idea/modules
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store .DS_Store
/build /build
/captures /captures
.externalNativeBuild .externalNativeBuild
.cxx .cxx
/.idea/modules/ .idea/

View File

@@ -1,122 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

6
.idea/compiler.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

View File

@@ -1,11 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="zhongchao">
<words>
<w>amap</w>
<w>coor</w>
<w>designative</w>
<w>mogo</w>
<w>tongchenfei</w>
</words>
</dictionary>
</component>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxProjectSettings">
<option name="commitMessageIssueKeyValidationOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
<option name="commitMessageValidationConfigOverride">
<CommitMessageValidationOverride>
<option name="enabled" value="true" />
</CommitMessageValidationOverride>
</option>
</component>
</project>

31
.idea/gradle.xml generated
View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/foudations" />
<option value="$PROJECT_DIR$/foudations/mogo-httpdns" />
<option value="$PROJECT_DIR$/foudations/mogo-live" />
<option value="$PROJECT_DIR$/foudations/mogo-location" />
<option value="$PROJECT_DIR$/foudations/mogo-network" />
<option value="$PROJECT_DIR$/foudations/mogo-passport" />
<option value="$PROJECT_DIR$/foudations/mogo-socket" />
<option value="$PROJECT_DIR$/modules" />
<option value="$PROJECT_DIR$/modules/mogo-realtime" />
<option value="$PROJECT_DIR$/modules/mogo-tanlu" />
<option value="$PROJECT_DIR$/modules/mogo-trafficlive" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@@ -1,36 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date,brief" />
</inspection_tool>
</profile>
</component>

View File

@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="http://nexus.zhidaoauto.com/repository/maven-releases/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven3" />
<option name="name" value="maven3" />
<option name="url" value="http://nexus.zhidaoauto.com/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="$USER_HOME$/Library/Android/sdk/extras/android/m2repository" />
<option name="name" value="$USER_HOME$/Library/Android/sdk/extras/android/m2repository" />
<option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/android/m2repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="$USER_HOME$/Library/Android/sdk/extras/m2repository" />
<option name="name" value="$USER_HOME$/Library/Android/sdk/extras/m2repository" />
<option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/m2repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="$USER_HOME$/Library/Android/sdk/extras/google/m2repository" />
<option name="name" value="$USER_HOME$/Library/Android/sdk/extras/google/m2repository" />
<option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/google/m2repository/" />
</remote-repository>
</component>
</project>

43
.idea/misc.xml generated
View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ASMIdeaPluginConfiguration">
<asm skipDebug="true" skipFrames="true" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ASMPluginConfiguration">
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ASMSmaliIdeaPluginConfiguration">
<asm skipDebug="true" skipFrames="true" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/layout/activity_live_play.xml" value="0.375" />
<entry key="app/src/main/res/layout/activity_live_play_and_push.xml" value="0.1" />
<entry key="app/src/main/res/layout/activity_live_push.xml" value="0.3640625" />
<entry key="app/src/main/res/layout/activity_location.xml" value="0.36502448356535333" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.3640625" />
<entry key="app/src/main/res/layout/activity_real_time.xml" value="0.1609347442680776" />
<entry key="app/src/main/res/xml/network_security_config.xml" value="0.23854166666666668" />
</map>
</option>
</component>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" value="$PROJECT_DIR$/ApiDoc" />
<option name="OPTION_DOCUMENT_TAG_USE" value="true" />
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="true" />
<option name="OPTION_DOCUMENT_TAG_VERSION" value="true" />
<option name="OTHER_OPTIONS" value="-encoding UTF-8 -charset UTF-8 -windowtitle 蘑菇AI云平台Doc" />
<option name="HEAP_SIZE" value="1024" />
<option name="LOCALE" value="zh_CN" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -62,11 +62,13 @@ dependencies {
implementation "com.mogo.cloud:tanlu:${MOGO_TANLU_VERSION}" implementation "com.mogo.cloud:tanlu:${MOGO_TANLU_VERSION}"
implementation "com.mogo.cloud:realtime:${MOGO_REALTIME_VERSION}" implementation "com.mogo.cloud:realtime:${MOGO_REALTIME_VERSION}"
implementation "com.mogo.cloud:trafficlive:${MOGO_TRAFFICLIVE_VERSION}" implementation "com.mogo.cloud:trafficlive:${MOGO_TRAFFICLIVE_VERSION}"
implementation "com.mogo.v2x:v2x:${MOGO_V2X_VERSION}"
} else { } else {
implementation project(":foudations:mogo-location") implementation project(":foudations:mogo-location")
implementation project(":modules:mogo-tanlu") implementation project(":modules:mogo-tanlu")
implementation project(":modules:mogo-realtime") implementation project(":modules:mogo-realtime")
implementation project(":modules:mogo-trafficlive") implementation project(":modules:mogo-trafficlive")
implementation project(":foudations:mogo-v2x")
} }
annotationProcessor 'com.elegant.spi:compiler:1.0.3' //编译时库 annotationProcessor 'com.elegant.spi:compiler:1.0.3' //编译时库

View File

@@ -4,18 +4,27 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import com.elegant.log.simplelog.Logger; import com.elegant.log.simplelog.Logger;
import com.mogo.cloud.network.NetworkActivity; import com.mogo.cloud.network.NetworkActivity;
import com.mogo.cloud.passport.IMoGoTokenCallback; import com.mogo.cloud.passport.IMoGoTokenCallback;
import com.mogo.cloud.passport.MoGoAiCloudClient; import com.mogo.cloud.passport.MoGoAiCloudClient;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.cloud.trafficlive.api.ITrafficCarLiveCallBack; import com.mogo.cloud.trafficlive.api.ITrafficCarLiveCallBack;
import com.mogo.cloud.trafficlive.api.ITrafficIntersectionLiveCallBack; import com.mogo.cloud.trafficlive.api.ITrafficIntersectionLiveCallBack;
import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive; import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive;
import com.mogo.v2x.V2XManager;
import com.mogo.v2x.callback.IV2XCallback;
import com.mogo.v2x.config.V2XConfig;
import com.mogo.v2x.event.V2XEvent;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
@@ -32,6 +41,9 @@ public class MainActivity extends AppCompatActivity {
private Button btnJumpLivePlay; private Button btnJumpLivePlay;
private Button btnRequestXINGLive; private Button btnRequestXINGLive;
private Button btnRequestCarLive; private Button btnRequestCarLive;
private Button btnV2XFunctionTest;
private boolean v2xHasBeenInitialized = false;
private SurfaceView surfacePreviewView; private SurfaceView surfacePreviewView;
private TextView tvSn; private TextView tvSn;
@@ -192,9 +204,62 @@ public class MainActivity extends AppCompatActivity {
}); });
}); });
//V2X功能测试
btnV2XFunctionTest = findViewById(R.id.btnV2XFunctionTest);
btnV2XFunctionTest.setOnClickListener(v -> {
if (v2xHasBeenInitialized) {
return;
}
v2xHasBeenInitialized = true;
V2XConfig.Builder builder = new V2XConfig.Builder();
builder.loggable(true)
.aiCloudConfig(MoGoAiCloudClientConfig.getInstance())
.appId("com.mogo.launcher")
.context(v.getContext())
.distanceForTriggerRefresh(300)
.durationForTriggerRefresh(1, TimeUnit.MINUTES);
V2XManager.INSTANCE.init(builder.build());
V2XManager.INSTANCE.addCallback(new IV2XCallback() {
@Override
public void onAck(@NonNull V2XEvent event) {
if (event instanceof V2XEvent.ForwardsWarning) {
V2XEvent.ForwardsWarning warning = (V2XEvent.ForwardsWarning) event;
Logger.d("V2XManager", "forward-warning<->onAck::" + warning.toString());
}
if (event instanceof V2XEvent.OptimalRoute) {
V2XEvent.OptimalRoute route = (V2XEvent.OptimalRoute) event;
Logger.d("V2XManager", "route<->onAck::" + route.toString());
}
if (event instanceof V2XEvent.Warning) {
V2XEvent.Warning warning = (V2XEvent.Warning) event;
Logger.d("V2XManager", "warning<->onAck::" + warning.toString());
}
if (event instanceof V2XEvent.Road) {
V2XEvent.Road road = (V2XEvent.Road) event;
Logger.d("V2XManager", "road<-->onAck::" + road.toString());
}
if (event instanceof V2XEvent.Marker) {
V2XEvent.Marker marker = (V2XEvent.Marker) event;
Logger.d("V2XManager", "marker<-->onAck::" + marker.toString());
}
}
@Override
public void onFail(@NonNull String s) {
Logger.d("V2XManager", "onFail::" + s);
}
});
});
MoGoAiCloudClient.getInstance().addTokenCallbacks(new IMoGoTokenCallback() { MoGoAiCloudClient.getInstance().addTokenCallbacks(new IMoGoTokenCallback() {
@Override @Override
public void onTokenGot(String token, String sn) { public void onTokenGot(String token, String sn) {
if (btnV2XFunctionTest.getVisibility() != View.VISIBLE) {
btnV2XFunctionTest.setVisibility(View.VISIBLE);
}
initPassportInfo(); initPassportInfo();
} }

View File

@@ -11,6 +11,7 @@ import com.mogo.cloud.httpdns.MogoHttpDnsClient;
import com.mogo.cloud.httpdns.MogoHttpDnsConfig; import com.mogo.cloud.httpdns.MogoHttpDnsConfig;
import com.mogo.cloud.httpdns.bean.HttpDnsSimpleLocation; import com.mogo.cloud.httpdns.bean.HttpDnsSimpleLocation;
import com.mogo.cloud.httpdns.listener.IHttpDnsCurrentLocation; import com.mogo.cloud.httpdns.listener.IHttpDnsCurrentLocation;
import com.mogo.cloud.location.LocationManager;
import com.mogo.cloud.passport.IMoGoTokenCallback; import com.mogo.cloud.passport.IMoGoTokenCallback;
import com.mogo.cloud.passport.MoGoAiCloudClient; import com.mogo.cloud.passport.MoGoAiCloudClient;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig; import com.mogo.cloud.passport.MoGoAiCloudClientConfig;

View File

@@ -112,6 +112,12 @@
android:text="查看周边可直播车" android:text="查看周边可直播车"
android:visibility="visible" /> android:visibility="visible" />
<Button
android:id="@+id/btnV2XFunctionTest"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<SurfaceView <SurfaceView
android:id="@+id/surfacePreviewView" android:id="@+id/surfacePreviewView"
android:layout_width="match_parent" android:layout_width="match_parent"

1
foudations/mogo-v2x/.gitignore vendored Executable file
View File

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

View File

@@ -0,0 +1,41 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode 1
versionName "${MOGO_SOCKET_VERSION}"
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 rootProject.ext.dependencies.rxandroid
if (Boolean.valueOf(RELEASE)) {
implementation "com.mogo.cloud:location:${MOGO_LOCATION_VERSION}"
implementation "com.mogo.cloud:network:${MOGO_NETWORK_VERSION}"
implementation "com.mogo.cloud:socket:${MOGO_SOCKET_VERSION}"
} else {
implementation project(":foudations:mogo-location")
implementation project(":foudations:mogo-network")
implementation project(":foudations:mogo-socket")
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.v2x
POM_ARTIFACT_ID=v2x
MOGO_V2X_VERSION=1.0.0

21
foudations/mogo-v2x/proguard-rules.pro vendored Executable file
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,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.v2x">
</manifest>

View File

@@ -0,0 +1,157 @@
package com.mogo.v2x
import android.os.Handler
import android.os.Looper
import com.mogo.cloud.location.LocationManager
import com.mogo.cloud.socket.SocketManager
import com.mogo.v2x.callback.IV2XCallback
import com.mogo.v2x.config.V2XConfig
import com.mogo.v2x.data.V2XMarkerResponse
import com.mogo.v2x.event.V2XEvent
import com.mogo.v2x.http.V2XRefreshModel
import com.mogo.v2x.http.callback.IV2XRefreshCallback
import com.mogo.v2x.socket.V2XMessageListener_401012
import com.mogo.v2x.socket.V2XMessageListener_401018
import com.mogo.v2x.socket.V2XMessageListener_402000
import com.mogo.v2x.socket.V2XMessageListener_404000
import com.mogo.v2x.logger.Logger
import com.mogo.v2x.utils.DistanceUtils
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicReference
object V2XManager {
internal const val TAG = "V2XManager"
private val config: AtomicReference<V2XConfig> by lazy {
AtomicReference<V2XConfig>(null)
}
private val cbs by lazy {
CopyOnWriteArrayList<IV2XCallback>()
}
private val longitude by lazy {
AtomicReference(0.0)
}
private val latitude by lazy {
AtomicReference(0.0)
}
private val refreshCallback = object : IV2XRefreshCallback<V2XMarkerResponse> {
override fun onSuccess(result: V2XMarkerResponse) {
cbs.forEach {
it.onAck(V2XEvent.Marker(result))
}
}
override fun onFail(msg: String?) {
cbs.forEach {
it.onFail(msg ?: "")
}
}
}
private val refreshTask = object : Runnable {
override fun run() {
V2XRefreshModel.querySnapshot(longitude = this@V2XManager.longitude.get(), latitude = this@V2XManager.latitude.get(), refreshCallback)
handler.postDelayed(this, config.get().durationForTriggerRefresh)
}
}
private val handler by lazy {
Handler(Looper.getMainLooper())
}
/**
* 根据所配置的参数初始化V2X相关功能注: 此方法不要重复调用,非首次调用会抛异常)
* @param config 相关配置类
*/
fun init(config: V2XConfig) {
if (this.config.get() != null) {
throw IllegalStateException("V2XManager has been initialized, don't initialize repeatably.")
}
val aiCloudConfig = config.aiCloudConfig
if (aiCloudConfig.sn?.isBlank() == true) {
throw IllegalStateException("please ensure sn must not null.")
}
if (aiCloudConfig.token?.isBlank() == true) {
throw IllegalStateException("please ensure token must not null.")
}
this.config.set(config)
Logger.loggable = config.loggable
SocketManager.getInstance().init(config.context)
SocketManager.getInstance().registerOnMessageListener(401012, V2XMessageListener_401012(cbs))
SocketManager.getInstance().registerOnMessageListener(401018, V2XMessageListener_401018(cbs))
SocketManager.getInstance().registerOnMessageListener(402000, V2XMessageListener_402000(cbs))
SocketManager.getInstance().registerOnMessageListener(404000, V2XMessageListener_404000(cbs))
LocationManager.getInstance().init(config.context)
LocationManager.getInstance().start()
handler.post(refreshTask)
}
/**
* 添加相关信息接口回调
* @param cb 要添加的回调接口
*/
fun addCallback(cb: IV2XCallback) {
if (cbs.contains(cb)) {
return
}
cbs += cb
}
/**
* 移除相关信息接口回调
* @param cb 要移除的回调接口
*/
fun removeCallback(cb: IV2XCallback) {
if (!cbs.contains(cb)) {
return
}
cbs.remove(cb)
}
/**
* 当自车位置变量时回调
* @param longitude 自车所在精度
* @param latitude 自车所在纬度
*/
fun onLocationChanged(longitude: Double, latitude: Double) {
if (this.config.get() == null) {
return
}
val oldLon = this.longitude.get()
val oldLat = this.latitude.get()
var update = false
try {
if (oldLon == 0.0 || oldLat == 0.0) {
handler.removeCallbacks(refreshTask)
handler.post(refreshTask)
update = true
return
}
if (DistanceUtils.calculateLineDistance(oldLon, oldLat, longitude, latitude) >= this.config.get().distanceForTriggerRefresh) {
handler.removeCallbacks(refreshTask)
handler.post(refreshTask)
update = true
}
} finally {
if (update) {
this.latitude.set(latitude)
this.longitude.set(longitude)
}
}
}
/**
* 是否已经初始化
* @return true: 已初始化过 false: 未初始化
*/
fun hasInit() = this.getConfig() != null
internal fun getConfig() = this.config.get()
}

View File

@@ -0,0 +1,15 @@
package com.mogo.v2x.callback
import com.mogo.v2x.event.V2XEvent
interface IV2XCallback {
/**
* 成功-对应事件
*/
fun onAck(event: V2XEvent)
/**
* 失败
*/
fun onFail(msg: String)
}

View File

@@ -0,0 +1,173 @@
package com.mogo.v2x.config
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.v2x.executor.Executors
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
import kotlin.IllegalStateException
/**
* V2X相关配置
*/
class V2XConfig private constructor(builder: Builder) {
init {
builder.aiCloudConfig ?: throw IllegalStateException("aiCloudConfig must not be null.")
}
/**
* 网络请求使用的线程池IO类型
*/
val executor: Executor by lazy {
builder.executor ?: Executors.IO
}
/**
* 是否开启日志
*/
val loggable: Boolean by lazy {
builder.loggable
}
/**
* 应用上下文
*/
val context : Context by lazy {
builder.context?.applicationContext ?: throw IllegalStateException("context must not be null.")
}
/**
* 公共参数
*/
val staticParams by lazy {
builder.staticParams ?: HashMap<String, Any>()
}
/**
* 云平台设置
*/
val aiCloudConfig by lazy {
builder.aiCloudConfig ?: throw IllegalStateException("aiCloudConfig must not be null.")
}
/**
* 应用ID一般为应用包名
*/
val appId by lazy {
builder.appId ?: throw IllegalStateException("appId must not be null.")
}
/**
* 基础Url
*/
val baseUrl by lazy {
builder.baseUrl ?: "http://dzt-launcherSnapshot.zhidaozhixing.com"
}
/**
* 多长时间请求一次自车周边信息
*/
val durationForTriggerRefresh by lazy {
val duration = builder.durationForTriggerRefresh
if (duration == null || duration <= 0) TimeUnit.SECONDS.toMillis(60) else duration
}
/**
* 自车行驶超过此长度,会刷新自车周边信息
*/
val distanceForTriggerRefresh: Float by lazy {
val distance = builder.distanceForTriggerRefresh
if (distance == null || distance <= 0) 200f else distance
}
fun newBuilder() = Builder(this)
class Builder {
constructor()
internal constructor(config: V2XConfig) {
context = config.context
executor = config.executor
loggable = config.loggable
appId = config.appId
baseUrl = config.baseUrl
staticParams = config.staticParams
aiCloudConfig = config.aiCloudConfig
durationForTriggerRefresh = config.durationForTriggerRefresh
distanceForTriggerRefresh = config.distanceForTriggerRefresh
}
internal var context: Context? = null
internal var executor: Executor? = null
internal var loggable: Boolean = false
internal var appId: String? = null
internal var staticParams: Map<String, Any?>? = null
internal var aiCloudConfig: MoGoAiCloudClientConfig? = null
internal var durationForTriggerRefresh: Long? = null
internal var baseUrl: String? = null
internal var distanceForTriggerRefresh: Float? = null
/**
* 应用上下文,此参数为必选项,不设置会抛异常
*/
fun context(context: Context) = apply { this.context = context }
/**
* 是否开启日志
*/
fun loggable(loggable: Boolean) = apply { this.loggable = loggable }
/**
* 应用ID(一般取应用包名),此参数是必选项,不设置会抛异常
*/
fun appId(appId: String) = apply { this.appId = appId }
/**
* 公共参数列表
*/
fun staticParams(params: Map<String, Any?>) = apply { this.staticParams = params }
/**
* 网络请求线程池,如未设置,会使用内置的
*/
fun executor(executor: Executor): Builder = apply {
if (this.executor != null) {
throw IllegalArgumentException("io executor has been initialized, don't set repeatedly.")
}
this.executor = executor
}
/**
* 刷新周边信息的时间间隔
*/
fun durationForTriggerRefresh(duration: Long, unit: TimeUnit = TimeUnit.SECONDS) = apply { this.durationForTriggerRefresh = unit.toMillis(duration) }
/**
* 自车走过的距离,超过此距离会刷新周边信息
*/
fun distanceForTriggerRefresh(distance: Float) = apply { this.distanceForTriggerRefresh = distance }
/**
* 云平台配置信息,此参数为必选项,不设置会抛异常
*/
fun aiCloudConfig(config: MoGoAiCloudClientConfig) = apply { this.aiCloudConfig = config }
/**
* 云平台baseUrl
*/
fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl }
fun build() : V2XConfig = V2XConfig(this)
}
}

View File

@@ -0,0 +1,31 @@
package com.mogo.v2x.data
import androidx.annotation.Keep
/**
* 路口碰撞预警、盲区预警等通用Bean
*/
@Keep
data class V2XAdvanceWarning (
var objectId: String,// 物体唯一标识
var objectType: Int,// 物体类型 1-人 2-自行车 3-小轿车 4-摩托车 5-红绿灯 6-bus 8-truck 9-路边摄像头
var status: Int,// 1.add 2.update 3.delete
var typeId: Int,// 首位大类标识 1预警 2规划 3拥堵 4事故
var time: Long,
var level: Int,// 预警等级
var threatLevel: Int,// 危险等级0保留1模型原始颜色2通知--黄3警告--红
var position: V2XLocation,
var heading: Double,
var speed: Double,
var distance: Double,
var roadId: String,// 道路id
var laneId: String,// 车道id
var laneNum: Int,// 车道号中心线编号为0 中心线右侧编号为负数3车道通行Road的车道编号0,-1,-2,-3
var gdLocusList: List<V2XLocation>,// 线性经纬度轨迹列表(高德)
var locusList: List<V2XLocation>// 轨迹列表(Wgs84坐标系)
) {
override fun toString(): String {
return "V2XAdvanceWarning(objectId='$objectId', objectType=$objectType, status=$status, typeId=$typeId, time=$time, level=$level, threatLevel=$threatLevel, position=$position, heading=$heading, speed=$speed, distance=$distance, roadId='$roadId', laneId='$laneId', laneNum=$laneNum, gdLocusList=$gdLocusList, locusList=$locusList)"
}
}

View File

@@ -0,0 +1,9 @@
package com.mogo.v2x.data
open class V2XBaseData {
@JvmField
var code = -1
@JvmField
var msg: String? = null
}

View File

@@ -0,0 +1,10 @@
package com.mogo.v2x.data
import androidx.annotation.Keep
@Keep
data class V2XLocation(var lon: Double = 0.0, var lat: Double = 0.0) {
override fun toString(): String {
return "V2XLocation(lon=$lon, lat=$lat)"
}
}

View File

@@ -0,0 +1,355 @@
package com.mogo.v2x.data
import androidx.annotation.Keep
import java.util.*
@Keep
class V2XMarkerCardResult: V2XBaseData() {
var dataType // 要查询的类型
: List<String>? = null
var carChat: List<V2XMarkerCarChat>? = null
var shareMusic: List<V2XMarkerShareMusic>? = null
var noveltyInfo: List<V2XMarkerNoveltyInfo>? = null
var onlineCar: List<V2XMarkerOnlineCar>? = null
var exploreWay: List<V2XMarkerExploreWay>? = null
var messageTime: Long = 0
override fun toString(): String {
return "MarkerCardResult(dataType=$dataType, carChat=$carChat, shareMusic=$shareMusic, noveltyInfo=$noveltyInfo, onlineCar=$onlineCar, exploreWay=$exploreWay, messageTime=$messageTime)"
}
}
@Keep
class V2XMarkerCarChat {
var type: String? = null
var location: V2XMarkerLocation? = null
var userInfo: V2XMarkerUserInfo? = null
override fun toString(): String {
return "V2XMarkerCarChat(type=$type, location=$location, userInfo=$userInfo)"
}
}
@Keep
class V2XMarkerShareMusic {
var bookInfo: String? = null
var id = 0
var likeNumber = 0
var location: V2XMarkerLocation? = null
var mediaId: String? = null
var mediaImg: String? = null
var mediaName: String? = null
var mediaSinger: String? = null
var mediaUrl: String? = null
var shareContentText: String? = null
var shareType = 0
var type: String? = null
var userInfo: V2XMarkerUserInfo? = null
override fun toString(): String {
return "V2XMarkerShareMusic(bookInfo=$bookInfo, id=$id, likeNumber=$likeNumber, location=$location, mediaId=$mediaId, mediaImg=$mediaImg, mediaName=$mediaName, mediaSinger=$mediaSinger, mediaUrl=$mediaUrl, shareContentText=$shareContentText, shareType=$shareType, type=$type, userInfo=$userInfo)"
}
}
/**
* 新鲜事儿Marker数据
*/
@Keep
class V2XMarkerNoveltyInfo {
var type: String? = null
var sn: String? = null
var location: V2XMarkerLocation? = null
var poiType: String? = null
var contentData: ContentData? = null
@Keep
class ContentData {
var content: String? = null
var iconUrl: String? = null
var imgUrl: String? = null
var infoId: String? = null
var likeNum: Long = 0
var title: String? = null
var gasPrices: String? = null
var isDisplayNavigation = false
var isDesplayHost = false
var isFabulous = false
var styleType: String? = null
//上报类型1-用户上报2-后台上报 3-三方上报
var uploadType: String? = null
override fun toString(): String {
return "ContentData(content=$content, iconUrl=$iconUrl, imgUrl=$imgUrl, infoId=$infoId, likeNum=$likeNum, title=$title, gasPrices=$gasPrices, isDisplayNavigation=$isDisplayNavigation, isDesplayHost=$isDesplayHost, isFabulous=$isFabulous, styleType=$styleType, uploadType=$uploadType)"
}
}
override fun toString(): String {
return "V2XMarkerNoveltyInfo(type=$type, sn=$sn, location=$location, poiType=$poiType, contentData=$contentData)"
}
}
@Keep
class V2XMarkerOnlineCar {
var type //卡片类型
: String? = null
var location //所在位置
: V2XMarkerLocation? = null
var focus //isFocus":"0-未关注1-关注
: Boolean? = null
var userInfo //用户数据
: V2XMarkerUserInfo? = null
var carInfo //车辆数据
: V2XMarkerCarInfo? = null
var pois //车辆路线
: List<V2XMarkerCarPois>? = null
var dynamicData //动态数据
: V2XMarkerDynamicData? = null
var hobbyData //爱好数据集合
: V2XMarkerHobbyDatum? = null
var activitiesScope //活动范围数据集合
: List<V2XMarkerActivitiesScope>? = null
var compatibility //匹配度
= 0
override fun toString(): String {
return "V2XMarkerOnlineCar(type=$type, location=$location, focus=$focus, userInfo=$userInfo, carInfo=$carInfo, pois=$pois, dynamicData=$dynamicData, hobbyData=$hobbyData, activitiesScope=$activitiesScope, compatibility=$compatibility)"
}
}
@Keep
class V2XMarkerExploreWay {
var infoId: String? = null
var type //卡片类型,
: String? = null
var poiType: String? = null
var sn: String? = null
var location //位置信息
: V2XMarkerLocation? = null
var direction //方位角度
= 0
var canLive //是否可直播1为可直播0不可直播
= false
var fileType //是图片还是视频1视频0图片
= 0
var addr //北京市朝阳区三里屯街道108号
: String? = null
var generateTime //时间戳
: Long = 0L
var cityName //:"城市名称",
: String? = null
var distance //距离
= 0.0
var userInfo //用户信息
: V2XMarkerUserInfo? = null
var items //视频地址和图片地址
: List<MarkerExploreWayItem>? = null
//上报类型1-用户上报2-后台上报 3-三方上报
var uploadType: String? = null
var isFabulous = false
// http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=42321443
// 1 需要用户判断是否拥堵 进行UGC问答
var infoCheckNode = 0
override fun equals(o: Any?): Boolean {
if (this === o) return true
if (o == null || javaClass != o.javaClass) return false
val that = o as V2XMarkerExploreWay
return infoId == that.infoId &&
type == that.type &&
poiType == that.poiType
}
override fun hashCode(): Int {
return Objects.hash(infoId, type, poiType)
}
override fun toString(): String {
return "V2XMarkerExploreWay(infoId=$infoId, type=$type, poiType=$poiType, sn=$sn, location=$location, direction=$direction, canLive=$canLive, fileType=$fileType, addr=$addr, generateTime=$generateTime, cityName=$cityName, distance=$distance, userInfo=$userInfo, items=$items, uploadType=$uploadType, isFabulous=$isFabulous, infoCheckNode=$infoCheckNode)"
}
}
@Keep
class V2XMarkerUserInfo {
private var sn: String? = null
var userId: Long = 0
private var userName //用户昵称
: String? = null
private var userHead //用户头像
: String? = null
private var gender //gender": "男也可以012根据实际库存返回即可
: String? = null
private var age // 年龄段,可以为空,与车聊聊一致
: Int? = null
var lastActiveweekAvgscore //末次活跃周驾驶行为平均得分
: String? = null
var safeLabel //车辆安全标签
: String? = null
var safeLabelType //1老司机 2安全驾驶 3危险驾驶
= 0
override fun toString(): String {
return "V2XMarkerUserInfo(sn=$sn, userId=$userId, userName=$userName, userHead=$userHead, gender=$gender, age=$age, lastActiveweekAvgscore=$lastActiveweekAvgscore, safeLabel=$safeLabel, safeLabelType=$safeLabelType)"
}
}
@Keep
class V2XMarkerCarInfo {
var carBrandLogoUrl: String? = null
var carTypeName: String? = null
var vehicleType = 0
var carLiveInfo: CarLiveInfo? = null
@Keep
class CarLiveInfo {
//rtmp视频直播地址rtmp://
var videoUrl: String? = null
//直播频道【直播心跳接口参数】C_1
var videoChannel: String? = null
//直播源sn【直播心跳接口参数】XTCBA90740400625
var videoSn: String? = null
override fun toString(): String {
return "CarLiveInfo(videoUrl=$videoUrl, videoChannel=$videoChannel, videoSn=$videoSn)"
}
}
override fun toString(): String {
return "V2XMarkerCarInfo(carBrandLogoUrl=$carBrandLogoUrl, carTypeName=$carTypeName, vehicleType=$vehicleType, carLiveInfo=$carLiveInfo)"
}
}
@Keep
class V2XMarkerCarPois {
var coordinates: List<*>? = null
var angle // 车头角度
= 0.0
var adcode: String? = null
override fun toString(): String {
return "V2XMarkerCarPois(coordinates=$coordinates, angle=$angle, adcode=$adcode)"
}
}
@Keep
class V2XMarkerDynamicData {
//QQ音乐懒人听书乐听头条 2 为书籍听书3 为新闻,1 为qq音乐
var type = 0
var mediaId //qq音乐id书的bookId
: String? = null
//qq音乐url 懒人听书为“”
var mediaUrl: String? = null
//歌曲名 ,当前播放书名,新闻标题内容
var mediaName: String? = null
//演唱歌手,当前章节,新闻来源
var mediaSinger: String? = null
//歌曲封面,书籍封面,新闻预览图
var mediaImg: String? = null
//音乐类别,类似经典 流行只有qq特有
var mediaType: String? = null
var maxTime //音频总时长
= 0
var bookInfo //懒人听书json串
: String? = null
//当前播放时长,可以不加,播放进度单独独立出来
var curTime = 0
//是否是本地音频只有qq音乐
var isLocalMedia //本地
= false
//播放模式,顺序,单曲循环,随机
var mediaPlayMode = 0
//1 播放 2 缓冲 0 暂停/停止 -1 播放错误
var playState = 0
override fun toString(): String {
return "V2XMarkerDynamicData(type=$type, mediaId=$mediaId, mediaUrl=$mediaUrl, mediaName=$mediaName, mediaSinger=$mediaSinger, mediaImg=$mediaImg, mediaType=$mediaType, maxTime=$maxTime, bookInfo=$bookInfo, curTime=$curTime, isLocalMedia=$isLocalMedia, mediaPlayMode=$mediaPlayMode, playState=$playState)"
}
}
@Keep
class V2XMarkerHobbyDatum {
var singerTop2 // 最喜欢的两位歌手
: List<MarkerOnlineTag>? = null
var songTypeTop2 // 最喜欢的两种音乐类型
: List<MarkerOnlineTag>? = null
var newsType // 最喜欢的资讯类型
: List<MarkerOnlineTag>? = null
var listenBookTop2 // 最喜欢听的两本书
: List<MarkerOnlineTag>? = null
var ifSociety // 是否喜爱社交
: List<MarkerOnlineTag>? = null
@Keep
class MarkerOnlineTag {
var content: String? = null
var isCheck = false
override fun toString(): String {
return "MarkerOnlineTag(content=$content, isCheck=$isCheck)"
}
}
override fun toString(): String {
return "V2XMarkerHobbyDatum(singerTop2=$singerTop2, songTypeTop2=$songTypeTop2, newsType=$newsType, listenBookTop2=$listenBookTop2, ifSociety=$ifSociety)"
}
}
@Keep
class V2XMarkerActivitiesScope {
var content: String? = null
var isCheck = false
override fun toString(): String {
return "V2XMarkerActivitiesScope(content=$content, isCheck=$isCheck)"
}
}
/**
* 道路情报V2X预警地图道路事件POI违章停车POI等
*/
@Keep
class MarkerExploreWayItem {
var thumbnail: String? = null
var url: String? = null
var content: String? = null
var illegalCount = 0.0
override fun toString(): String {
return "MarkerExploreWayItem(thumbnail=$thumbnail, url=$url, content=$content, illegalCount=$illegalCount)"
}
}
@Keep
class V2XMarkerLocation {
var lat //纬度
= 0.0
var lon //经度
= 0.0
var angle //车头角度,可以没有
= 0.0
var address //具体的位置信息
: String? = null
override fun toString(): String {
return "V2XMarkerLocation(lat=$lat, lon=$lon, angle=$angle, address=$address)"
}
}

View File

@@ -0,0 +1,15 @@
package com.mogo.v2x.data
import androidx.annotation.Keep
import com.elegant.network.BaseResp
@Keep
class V2XMarkerResponse: BaseResp() {
var result: V2XMarkerCardResult? = null
var sign: String? = null
override fun toString(): String {
return "V2XMarkerResponse(result=$result, sign=$sign)"
}
}

View File

@@ -0,0 +1,47 @@
package com.mogo.v2x.data
import androidx.annotation.Keep
/**
* 最优路线推荐
*/
@Keep
class V2XOptimalRoute {
var sn: String? = null
/**
* 道路ID
*/
var road_id: String? = null
/**
* 车道ID-2D路段
*/
var current_lane_id: String? = null
/**
* 车道号中心线编号为0 中心线右侧编号为负数3车道通行Road的车道编号0,-1,-2,-3
*/
var current_lane_num = 0
/**
* 最优车道平均速度
*/
var most_speed = 0.0
/**
* 车道号中心线编号为0 中心线右侧编号为负数3车道通行Road的车道编号0,-1,-2,-3
*/
var most_lane_num = 0
/**
* Wgs84坐标系线性经纬度轨迹列表
*/
var locus_list: List<V2XLocation>? = null
/**
* 高德坐标系Gcj线性经纬度轨迹列表
*/
var gd_locus_list: List<V2XLocation>? = null
}

View File

@@ -0,0 +1,112 @@
package com.mogo.v2x.data
import androidx.annotation.Keep
/**
* 预警目标物数据模型
*/
@Keep
class V2XWarningTarget {
//事件类型 行人1/自行车2/摩托车4/骑行车辆11
var type = 0
//目标物位置
var lat = 0.0
var lon = 0.0
//目标物颜色
var targetColor: String? = null
//目标物距离
var distance = 0.0
//预测碰撞点位置
var collisionLat = 0.0
var collisionLon = 0.0
//朝向 角度
var angle = 0.0
//方位 前 后 左 右
var direction = 0
//速度
var speed = 0f
//停止线经纬度
var stopLines: List<V2XLocation>? = null
//自车到停止线距离
var stopLineDistance = 0.0
//道路唯一标识
var roadId: String? = null
//车道唯一标识
var laneId: String? = null
//识别物体唯一标识
var uuid: String? = null
//红绿灯颜色
var color: String? = null
//车ID 暂不使用
var carId: String? = null
//预警文案
var warningContent: String? = null
//车头朝向
var heading = 0.0
//系统时间 暂时没用
var systemTime: Long = 0
//定位卫星时间 暂时没用
var satelliteTime: Long = 0
//预警蒙层等展示时长
var showTime: Long = 0
//设计划线宽度与道路同宽
var roadwidth = 0f
//自组字段
//tts播报
private var tts: String? = null
//自车位置
var carLocation: V2XLocation? = null
override fun toString(): String {
return "V2XWarningEntity{" +
"type=" + type +
", lat=" + lat +
", lon=" + lon +
", targetColor='" + targetColor + '\'' +
", distance=" + distance +
", collisionLat=" + collisionLat +
", collisionLon=" + collisionLon +
", angle=" + angle +
", direction=" + direction +
", speed=" + speed +
", stopLines=" + stopLines +
", stopLineDistance=" + stopLineDistance +
", roadId='" + roadId + '\'' +
", laneId='" + laneId + '\'' +
", uuid='" + uuid + '\'' +
", color='" + color + '\'' +
", carId='" + carId + '\'' +
", warningContent='" + warningContent + '\'' +
", heading=" + heading +
", systemTime=" + systemTime +
", satelliteTime=" + satelliteTime +
", showTime=" + showTime +
", roadwidth=" + roadwidth +
", tts='" + tts + '\'' +
", carLocation=" + carLocation +
'}'
}
}

View File

@@ -0,0 +1,32 @@
package com.mogo.v2x.event
import com.mogo.v2x.data.*
sealed class V2XEvent {
/**
* 长链-路口碰撞预警、盲区预警等通用Bean
*/
class ForwardsWarning(val type: Int = 404000, val data: V2XAdvanceWarning): V2XEvent()
/**
* 长链-最优推荐线种
*/
class OptimalRoute(val type: Int = 402000, val data: V2XOptimalRoute): V2XEvent()
/**
* 长链-预警目标物
*/
class Warning(val type: Int = 401018, val data: V2XWarningTarget): V2XEvent()
/**
* 长链-道路事件
*/
class Road(val type: Int = 401012, val data: V2XMarkerCardResult): V2XEvent()
/**
* 短链-道路标记事件
*/
class Marker(val data: V2XMarkerResponse): V2XEvent()
}

View File

@@ -0,0 +1,35 @@
package com.mogo.v2x.executor
import java.util.concurrent.*
import java.util.concurrent.atomic.AtomicLong
import kotlin.math.max
import kotlin.math.min
internal object Executors {
private val group: ThreadGroup by lazy {
ThreadGroup("v2x-group")
}
private val CPU_CORE_COUNT by lazy {
Runtime.getRuntime().availableProcessors()
}
private val DEFAULT_CORE_COUNT by lazy {
(max(2, min(CPU_CORE_COUNT - 1, 6)) * 3) + 1
}
private const val DEFAULT_MAX_COUNT_4_IO = 128
val IO by lazy {
val idGenerator = AtomicLong(0)
ThreadPoolExecutor(
DEFAULT_CORE_COUNT, DEFAULT_MAX_COUNT_4_IO, 30, TimeUnit.SECONDS, LinkedBlockingDeque()
) { r ->
Thread(group, r).apply {
name = "io-thread-${idGenerator.getAndIncrement()}"
}
}
}
}

View File

@@ -0,0 +1,72 @@
package com.mogo.v2x.http
import com.elegant.network.internal.RetrofitFactory
import com.elegant.network.utils.GsonUtil
import com.elegant.network.utils.SignUtil
import com.elegant.utils.CommonUtils
import com.mogo.v2x.V2XManager
import com.mogo.v2x.config.V2XConfig
import com.mogo.v2x.data.V2XLocation
import com.mogo.v2x.data.V2XMarkerResponse
import com.mogo.v2x.http.api.V2XApiService
import com.mogo.v2x.http.body.V2XRefreshEntity
import com.mogo.v2x.http.callback.IV2XRefreshCallback
import com.mogo.v2x.utils.DeviceUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
class V2XRefreshModel {
companion object {
fun querySnapshot(longitude: Double, latitude: Double, callback: IV2XRefreshCallback<V2XMarkerResponse>?): Disposable {
val config = V2XManager.getConfig()
return RetrofitFactory.getInstance(config.baseUrl)
.create(V2XApiService::class.java)
.querySnapshotAsync(buildParams(longitude, latitude, config))
.subscribeOn(Schedulers.from(config.executor))
.observeOn(AndroidSchedulers.mainThread())
.doOnError {
callback?.onFail(it.message)
}
.subscribe { data ->
if (data == null) {
callback?.onFail("returned data is null.")
return@subscribe
}
if (data.code != 0 && data.code != 200) {
callback?.onFail("code:${data.code}, msg: ${data.msg}")
} else {
callback?.onSuccess(data)
}
}
}
private fun buildParams(longitude: Double, latitude: Double, config: V2XConfig): Map<String, Any> = mutableMapOf<String, Any>().apply {
putAll(config.staticParams.let {
val handled = mutableMapOf<String, Any>()
it.asIterable().forEach { itx ->
val value = itx.value
if (value != null) {
handled[itx.key] = value
}
}
handled
})
this["netType"] = CommonUtils.getNetworkType(config.context)
this["cellId"] = DeviceUtils.getCellId(config.context) ?: ""
this["sn"] = config.aiCloudConfig.sn
this["ticket"] = config.aiCloudConfig.token
this["sig"] = SignUtil.createSign(this, "JGjZx6")
this["data"] = GsonUtil.jsonFromObject(V2XRefreshEntity().apply {
limit = 999
location = V2XLocation(longitude, latitude)
radius = 1000
dataType.add("CARD_TYPE_ROAD_CONDITION")
viewPush = true
})
}
}
}

View File

@@ -0,0 +1,14 @@
package com.mogo.v2x.http.api
import com.mogo.v2x.data.V2XMarkerResponse
import io.reactivex.Maybe
import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
interface V2XApiService {
@FormUrlEncoded
@POST("/yycp-launcherSnapshot/launcherSnapshot/querySnapshotAsync")
fun querySnapshotAsync(@FieldMap parameters: Map<String, Any>): Maybe<V2XMarkerResponse?>
}

View File

@@ -0,0 +1,39 @@
package com.mogo.v2x.http.body
import androidx.annotation.Keep
import com.mogo.v2x.data.V2XLocation
/**
* 刷新地图信息接口
*/
@Keep
class V2XRefreshEntity {
@JvmField
var dataType: MutableList<String> = mutableListOf() // 要查询的类型
@JvmField
var limit = 50 // 请求数量
@JvmField
var radius = 2000 // 地理围栏半径(米)
@JvmField
var location // 坐标
: V2XLocation? = null
@JvmField
var sn: String? = null
@JvmField
var onlyFocus // 是否仅查询已关注的好友
= false
@JvmField
var onlySameCity // 是否仅查询注册城市相同的同城用户
= false
@JvmField
var viewPush // 是否走V2X通道 true-401011false -401001
= false
@JvmField
var onlyRealUser = false
}

View File

@@ -0,0 +1,11 @@
package com.mogo.v2x.http.callback
/**
* 刷新回调
*/
interface IV2XRefreshCallback<T> {
fun onSuccess(result: T)
fun onFail(msg: String?)
}

View File

@@ -0,0 +1,24 @@
package com.mogo.v2x.logger
import android.util.Log
object Logger {
var loggable: Boolean = false
fun v(tag: String, msg: String) = if (loggable) Log.v(tag, msg) else 0
fun d(tag: String, msg: String) = if (loggable) Log.d(tag, msg) else 0
fun i(tag: String, msg: String) = if (loggable) Log.i(tag, msg) else 0
fun w(tag: String, msg: String) = if (loggable) Log.w(tag, msg) else 0
fun e(tag: String, msg: String, t: Throwable? = null) = if (loggable) {
if (t == null) {
Log.e(tag, msg)
} else {
Log.e(tag, msg, t)
}
} else 0
}

View File

@@ -0,0 +1,27 @@
package com.mogo.v2x.socket
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener
import com.mogo.v2x.V2XManager
import com.mogo.v2x.callback.IV2XCallback
import com.mogo.v2x.data.V2XMarkerCardResult
import com.mogo.v2x.event.V2XEvent
import com.mogo.v2x.logger.Logger
internal class V2XMessageListener_401012(val cbs: Iterable<IV2XCallback>?): IMogoCloudSocketOnMessageListener<V2XMarkerCardResult> {
override fun target(msgType: Int): Class<V2XMarkerCardResult> = V2XMarkerCardResult::class.java
override fun onMsgReceived(msgType: Int, data: V2XMarkerCardResult?) {
if (msgType != 401012) {
return
}
if (data == null) {
Logger.i(V2XManager.TAG, "V2XMessageListener_401012message is null!")
return
}
Logger.i(V2XManager.TAG, "V2XMessageListener_401012:$data")
cbs?.forEach {
it.onAck(V2XEvent.Road(data = data))
}
}
}

View File

@@ -0,0 +1,27 @@
package com.mogo.v2x.socket
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener
import com.mogo.v2x.V2XManager
import com.mogo.v2x.callback.IV2XCallback
import com.mogo.v2x.event.V2XEvent
import com.mogo.v2x.data.V2XWarningTarget
import com.mogo.v2x.logger.Logger
internal class V2XMessageListener_401018(val cbs: Iterable<IV2XCallback>?): IMogoCloudSocketOnMessageListener<V2XWarningTarget> {
override fun target(msgType: Int): Class<V2XWarningTarget> = V2XWarningTarget::class.java
override fun onMsgReceived(msgType: Int, data: V2XWarningTarget?) {
if (msgType != 401018) {
return
}
if (data == null) {
Logger.i(V2XManager.TAG, "V2XMessageListener_401018message is null!")
return
}
Logger.i(V2XManager.TAG, "V2XMessageListener_401018:$data")
cbs?.forEach {
it.onAck(V2XEvent.Warning(data = data))
}
}
}

View File

@@ -0,0 +1,27 @@
package com.mogo.v2x.socket
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener
import com.mogo.v2x.V2XManager
import com.mogo.v2x.callback.IV2XCallback
import com.mogo.v2x.data.V2XAdvanceWarning
import com.mogo.v2x.event.V2XEvent
import com.mogo.v2x.logger.Logger
internal class V2XMessageListener_402000(val cbs: Iterable<IV2XCallback>?): IMogoCloudSocketOnMessageListener<V2XAdvanceWarning> {
override fun target(msgType: Int): Class<V2XAdvanceWarning> = V2XAdvanceWarning::class.java
override fun onMsgReceived(msgType: Int, data: V2XAdvanceWarning?) {
if (msgType != 402000) {
return
}
if (data == null) {
Logger.i(V2XManager.TAG, "V2XMessageListener_402000message is null!")
return
}
Logger.i(V2XManager.TAG, "V2XMessageListener_402000:$data")
cbs?.forEach {
it.onAck(V2XEvent.ForwardsWarning(data = data))
}
}
}

View File

@@ -0,0 +1,27 @@
package com.mogo.v2x.socket
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener
import com.mogo.v2x.V2XManager
import com.mogo.v2x.callback.IV2XCallback
import com.mogo.v2x.data.V2XOptimalRoute
import com.mogo.v2x.event.V2XEvent
import com.mogo.v2x.logger.Logger
internal class V2XMessageListener_404000(val cbs: Iterable<IV2XCallback>?): IMogoCloudSocketOnMessageListener<V2XOptimalRoute> {
override fun target(msgType: Int): Class<V2XOptimalRoute> = V2XOptimalRoute::class.java
override fun onMsgReceived(msgType: Int, data: V2XOptimalRoute?) {
if (msgType != 404000) {
return
}
if (data == null) {
Logger.i(V2XManager.TAG, "V2XMessageListener_404000message is null!")
return
}
Logger.i(V2XManager.TAG, "V2XMessageListener_404000:$data")
cbs?.forEach {
it.onAck(V2XEvent.OptimalRoute(data = data))
}
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.v2x.utils
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.telephony.CellLocation
import android.telephony.TelephonyManager
import android.telephony.cdma.CdmaCellLocation
import android.telephony.gsm.GsmCellLocation
import java.lang.Exception
class DeviceUtils {
companion object {
@SuppressLint("MissingPermission")
@JvmStatic
fun getCellId(context: Context): String? {
val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val pm = context.packageManager
val accessCoarseLocationPermission = PackageManager.PERMISSION_GRANTED ==
pm.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, context.packageName)
val accessFineLocationPermission = PackageManager.PERMISSION_GRANTED ==
pm.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, context.packageName)
if (!accessCoarseLocationPermission || !accessFineLocationPermission) return "noPermission"
var location: CellLocation? = null
try {
location = tm.cellLocation
} catch (e: Exception) {
e.printStackTrace()
}
if (location != null) {
// Gsm网络 , 联通移动的网络属于这一套
if (location is GsmCellLocation) {
val cellid = location.cid
return cellid.toString()
// Cdma网络 , 电信网络属于这一种
} else if (location is CdmaCellLocation) {
return location.baseStationId.toString()
}
}
return null
}
}
}

View File

@@ -0,0 +1,52 @@
package com.mogo.v2x.utils
import kotlin.math.asin
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
class DistanceUtils {
companion object {
/**
* @param lon1
* @param lat1
* @param lon2
* @param lat2
* @return 两坐标的距离 单位M
*/
fun calculateLineDistance(lon1: Double, lat1: Double, lon2: Double, lat2: Double): Float {
return try {
var var2 = lon1
var var4 = lat1
var var6 = lon2
var var8 = lat2
var2 *= 0.01745329251994329
var4 *= 0.01745329251994329
var6 *= 0.01745329251994329
var8 *= 0.01745329251994329
val var10 = sin(var2)
val var12 = sin(var4)
val var14 = cos(var2)
val var16 = cos(var4)
val var18 = sin(var6)
val var20 = sin(var8)
val var22 = cos(var6)
val var24 = cos(var8)
val var28 = DoubleArray(3)
val var29 = DoubleArray(3)
var28[0] = var16 * var14
var28[1] = var16 * var10
var28[2] = var12
var29[0] = var24 * var22
var29[1] = var24 * var18
var29[2] = var20
(asin(sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2])) / 2.0) * 1.27420015798544E7).toFloat()
} catch (var26: Throwable) {
var26.printStackTrace()
0.0f
}
}
}
}

View File

@@ -55,3 +55,6 @@ MOGO_LIVE_VERSION=1.3.18
MOGO_TRAFFICLIVE_VERSION=1.3.18 MOGO_TRAFFICLIVE_VERSION=1.3.18
# 定位服务 # 定位服务
MOGO_LOCATION_VERSION=1.3.18 MOGO_LOCATION_VERSION=1.3.18
# v2x
MOGO_V2X_VERSION=1.0.1

View File

@@ -9,3 +9,4 @@ include ':foudations:mogo-httpdns'
include ':foudations:mogo-passport' include ':foudations:mogo-passport'
include ':app' include ':app'
rootProject.name = "MoGoAiCloudSdk" rootProject.name = "MoGoAiCloudSdk"
include ':foudations:mogo-v2x'