[V2X]弹窗互斥逻辑和更改道路事件展示弹窗的方式

This commit is contained in:
renwj
2022-01-26 16:47:21 +08:00
parent 19ae5c4250
commit 5002b28ef7
73 changed files with 1434 additions and 4681 deletions

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mogo.launcher.f.test"
android:versionCode="1"
android:versionName="1.0">
<instrumentation android:targetPackage="com.mogo.launcher.f"
android:name="androidx.test.runner.AndroidJUnitRunner"/>
<application tools:replace="label" android:label="AutoPilotTest" />
</manifest>

View File

@@ -0,0 +1,390 @@
package com.mogo.functions.test
import android.animation.Animator
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.animation.OvershootInterpolator
import android.widget.PopupWindow
import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.function.hmi.notification.WarningFloat
import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator
import com.mogo.eagle.core.function.hmi.notification.enums.SidePattern
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
import com.mogo.eagle.core.function.main.MainLauncherActivity
import com.mogo.eagle.core.utilcode.kotlin.shape
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.ActivityReminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.PopupWindowReminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.ViewReminder
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.mogo.module.common.enums.EventTypeEnum
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.lang.Integer.min
import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@LargeTest
class ReminderTest {
lateinit var launch: ActivityScenario<MainLauncherActivity>
@Before
fun before() {
launch = ActivityScenario.launch(MainLauncherActivity::class.java)
}
@Test
fun testViewReminderNotOverride() = runBlocking(Dispatchers.Main) {
launch.onActivity {
it.lifecycleScope.launchWhenResumed {
for (i in 1..10) {
val reminder = WindowManagerViewUnOverrideReminder(View(it).also { itx -> itx.background = shape(solid = color(i)) }, 300, 300)
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(3))
reminder.hide()
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
return@runBlocking
}
@Test
fun testViewReminderOverride() = runBlocking(Dispatchers.Main) {
launch.onActivity {
it.lifecycleScope.launchWhenCreated {
for (i in 1..10) {
val reminder = WindowManagerViewOverrideReminder(View(it).also { itx -> itx.background = shape(solid = color(i)) }, 300, 300)
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(3))
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
return@runBlocking
}
@Test
fun testViewReminderWhenActivityDestroyed() = runBlocking(Dispatchers.Main) {
launch.onActivity {
it.lifecycleScope.launchWhenCreated {
for (i in 1..10) {
val reminder = WindowManagerViewOverrideReminder(View(it).also { itx -> itx.background = shape(solid = color(i)) }, 300, 300)
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(3))
if (i == 8) {
it.finish()
}
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
@Test
fun testWarningFloat() = runBlocking(Dispatchers.Main) {
launch.onActivity {
it.lifecycleScope.launchWhenCreated {
for (i in 1..10) {
val v = View(it).also {
it.background = shape(solid = color(i))
it.layoutParams = WindowManager.LayoutParams().also { itx ->
itx.width = 300
itx.height = 400
}
}
val builder = WarningFloat.with(it).setTag("test${i}").setLayout(v).setSidePattern(SidePattern.RESULT_TOP).setCountDownTime(TimeUnit.SECONDS.toMillis(10)).setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110).setImmersionStatusBar(true).addWarningStatusListener(object :
IMoGoWarningStatusListener {
override fun onShow() {
}
}).setAnimator(object : DefaultAnimator() {
override fun enterAnim(view: View, params: WindowManager.LayoutParams, windowManager: WindowManager, sidePattern: SidePattern): Animator? = super.enterAnim(view, params, windowManager, sidePattern)?.apply {
interpolator = OvershootInterpolator()
}
override fun exitAnim(view: View, params: WindowManager.LayoutParams, windowManager: WindowManager, sidePattern: SidePattern): Animator? = super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200)
})
Reminder.enqueue(it, WarningFloatReminder(builder))
delay(TimeUnit.SECONDS.toMillis(3))
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
@Test
fun testActivityReminder() = runBlocking(Dispatchers.Main) {
launch.onActivity {
it.lifecycleScope.launchWhenResumed {
for (i in 1..10) {
val reminder = ActivityNameReminder(it, "com.mogo.launcher.TestActivity")
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(6))
reminder.hide()
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
@Test
fun testActivityReminderOverride() = runBlocking(Dispatchers.Main) {
launch.onActivity {
it.lifecycleScope.launchWhenResumed {
for (i in 1..10) {
val reminder = ActivityNameOverrideReminder(it, "com.mogo.launcher.TestActivity")
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(6))
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
@Test
fun testPopupWindowReminder() = runBlocking {
launch.onActivity {
it.lifecycleScope.launchWhenResumed {
for (i in 1..10) {
val reminder = TestPopupWindowReminder(it.findViewById(android.R.id.content), PopupWindow(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT).also { itx ->
itx.contentView = View(it).also {
xx -> xx.background = shape(solid = color(i))
xx.layoutParams = ViewGroup.LayoutParams(300, 400)
}
})
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(3))
reminder.hide()
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
@Test
fun testPopupWindowReminderOverride() = runBlocking {
launch.onActivity {
it.lifecycleScope.launchWhenResumed {
for (i in 1..10) {
val reminder = TestPopupWindowReminderOverride(it.findViewById(android.R.id.content), PopupWindow(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT).also { itx ->
itx.contentView = View(it).also {
xx -> xx.background = shape(solid = color(i))
xx.layoutParams = ViewGroup.LayoutParams(300, 400)
}
})
Reminder.enqueue(it, reminder)
delay(TimeUnit.SECONDS.toMillis(3))
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
@Test
fun testWarningFloatForProject() = runBlocking {
launch.onActivity {
it.lifecycleScope.launchWhenResumed {
for (i in 1..10) {
val notificationView = V2XNotificationView(it)
notificationView.setWarningIcon(EventTypeEnum.getWarningIcon("10003"))
notificationView.setWarningContent("XXXXXX${i}")
WarningFloat.with(it)
.setTag("tag")
.setLayout(notificationView)
.setSidePattern(SidePattern.RESULT_TOP)
.setCountDownTime(5000)
.setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110)
.setImmersionStatusBar(true)
.addWarningStatusListener(object : IMoGoWarningStatusListener {
override fun onShow() {
}
})
.setAnimator(object : DefaultAnimator() {
override fun enterAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.enterAnim(view, params, windowManager, sidePattern)?.apply {
interpolator = OvershootInterpolator()
}
override fun exitAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200)
})
.show()
delay(2000)
}
}
}
delay(TimeUnit.SECONDS.toMillis(100))
}
class WarningFloatReminder(private val builder: WarningFloat.Builder) : ViewReminder(builder.config.layoutView!!) {
override fun show() {
builder.show()
}
override fun hide() {
WarningFloat.dismiss(builder.config.floatTag, false)
}
override fun isOverride(): Boolean {
return true
}
}
class WindowManagerViewUnOverrideReminder(private val content: View, private val width: Int, private val height: Int) : ViewReminder(content) {
private val wm by lazy {
content.context.getSystemService(Activity.WINDOW_SERVICE) as WindowManager
}
private var isAdd = false
override fun show() {
if (!isAdd) {
val params = WindowManager.LayoutParams().also {
it.width = width
it.height = height
}
params.gravity = Gravity.CENTER
wm.addView(content, params)
isAdd = true
}
}
override fun hide() {
if (isAdd && ViewCompat.isAttachedToWindow(content)) {
wm.removeView(content)
isAdd = false
}
}
}
class WindowManagerViewOverrideReminder(private val content: View, private val width: Int, private val height: Int) : ViewReminder(content) {
private val wm by lazy {
content.context.getSystemService(Activity.WINDOW_SERVICE) as WindowManager
}
private var isAdd = false
override fun show() {
if (!isAdd) {
val params = WindowManager.LayoutParams().also {
it.width = width
it.height = height
}
params.gravity = Gravity.CENTER
wm.addView(content, params)
isAdd = true
}
}
override fun hide() {
if (isAdd && ViewCompat.isAttachedToWindow(content)) {
wm.removeView(content)
isAdd = false
}
}
override fun isOverride(): Boolean {
return true
}
}
class ActivityNameReminder(private val context: Context, private val className: String): ActivityReminder(className) {
override fun show() {
Intent(context, Class.forName(className)).also {
context.startActivity(it)
}
}
override fun hide() {
AppStateManager.currentActivity()?.takeIf { it.javaClass.name == className }?.finish()
}
}
class ActivityNameOverrideReminder(private val context: Context, private val className: String): ActivityReminder(className) {
override fun show() {
Intent(context, Class.forName(className)).also {
context.startActivity(it)
}
}
override fun hide() {
AppStateManager.currentActivity()?.takeIf { it.javaClass.name == className }?.finish()
}
override fun isOverride(): Boolean {
return true
}
}
class TestPopupWindowReminder(private val anchor: View, private val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) {
override fun show() {
popupWindow.showAtLocation(anchor, Gravity.CENTER, 0, 0)
}
}
class TestPopupWindowReminderOverride(private val anchor: View, private val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) {
override fun show() {
popupWindow.showAtLocation(anchor, Gravity.CENTER, 0, 0)
}
override fun isOverride(): Boolean {
return true
}
}
private fun color(index: Int): Int {
if (index > 10) {
return Color.BLACK
}
val alpha = min(255, 255 - index * 20)
return Color.argb(alpha, Color.red(Color.RED), Color.green(Color.RED), Color.blue(Color.RED))
}
}

View File

@@ -247,6 +247,7 @@ ext {
life_cycle_scope : "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0",
view_model_scope : "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0",
live_data_scope : "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0",
life_cycle_java8 : "androidx.lifecycle:lifecycle-common-java8:2.2.0",
//========================== Unit Test ======================
@@ -255,7 +256,8 @@ ext {
androidx_unit_ext : "androidx.test.ext:junit:1.1.2",
androidx_unit_ext_ktx : "androidx.test.ext:junit-ktx:1.1.2",
androidx_runner : "androidx.test:runner:1.3.0",
androidx_espresso_core : "androidx.test.espresso:espresso-core:3.3.0",
androidx_espresso_core : "androidx.test.espresso:espresso-core:3.3.0"
]
}

View File

@@ -2,7 +2,6 @@ package com.mogo.eagle.core.function.check
import android.content.Context
import android.content.Intent
import android.util.Log
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.function.api.check.ICheckProvider
@@ -12,10 +11,7 @@ import com.mogo.eagle.core.function.check.net.CheckNetWork.checkNetWork
import com.mogo.eagle.core.function.check.net.CheckResultData
import com.mogo.eagle.core.function.check.view.CheckActivity
import com.mogo.eagle.core.function.check.view.CheckDialog
import com.mogo.eagle.core.utilcode.util.ActivityLifecycleManager
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.eagle.core.utilcode.util.LogUtils
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.module.common.MogoApisHandler
import com.mogo.module.service.receiver.MogoReceiver
import com.mogo.service.statusmanager.IMogoStatusChangedListener
@@ -89,7 +85,7 @@ class VehicleMonitoringManager : ICheckProvider, IMogoStatusChangedListener {
*/
private fun showDialog(context: Context) {
try {
if (ActivityLifecycleManager.getInstance().isAppActive && AppUtils.isAppRunning(
if (AppStateManager.isActive() && AppUtils.isAppRunning(
AppUtils.getAppPackageName()
) && ActivityUtils.getTopActivity() !is CheckActivity
) {

View File

@@ -1,11 +1,18 @@
package com.mogo.eagle.core.function.hmi.notification
import android.content.Context
import android.content.ContextWrapper
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.view.ContextThemeWrapper
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.mogo.eagle.core.function.hmi.notification.enums.SidePattern
import com.mogo.eagle.core.function.hmi.notification.interfaces.OnFloatAnimator
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.ViewReminder
import com.mogo.eagle.core.utilcode.util.WindowUtils
/**
@@ -33,7 +40,6 @@ class WarningFloat {
}
/**
* 浮窗的属性构建类,支持链式调用
*/
@@ -155,6 +161,10 @@ class WarningFloat {
this.config.height = height
}
fun isOverride(isOverride: Boolean) = apply {
this.config.isOverride = isOverride
}
/**
* 创建浮窗包括Activity浮窗和系统浮窗如若系统浮窗无权限先进行权限申请
*/
@@ -164,9 +174,62 @@ class WarningFloat {
config.layoutId == null && config.layoutView == null ->
Logger.e(TAG, "需要传入 layoutId 或 layoutView ")
// 申请浮窗权限
else -> WarningFloatWindowManager.create(activity, config)
else -> {
var content: View? = null
if (config.layoutView != null) {
content = config.layoutView
} else if (config.layoutId != null) {
content = LayoutInflater.from(activity).inflate(config.layoutId!!, null)
}
content?.let {
config.layoutId = null
config.layoutView = it
Reminder.enqueue(getLifecycleOwner(activity), WarningFloatReminder(activity, config, it))
}
}
}
}
private fun getLifecycleOwner(context: Context): LifecycleOwner {
if (context is LifecycleOwner) {
return context
}
if (context is ContextThemeWrapper) {
return getLifecycleOwner(context.baseContext)
}
return ProcessLifecycleOwner.get()
}
internal class WarningFloatReminder(private val activity: Context, private val config: WarningNotificationConfig, content: View): ViewReminder(content) {
private var hasShow = false
override fun show() {
hasShow = !WarningFloatWindowManager.create(activity, config)
}
override fun hide() {
dismiss(config.floatTag, false)
}
override fun isOverride(): Boolean {
return config.isOverride
}
override fun maxProtectDuration(): Long {
return if (hasShow) 0L else super.maxProtectDuration()
}
}
fun isShow(): Boolean = WarningFloatWindowManager.getHelper(config.floatTag)?.isShow() ?: false
fun resetExpireTime(expireTime: Long) {
if (!isShow()) {
return
}
WarningFloatWindowManager.getHelper(config.floatTag)?.resetDownTime(expireTime)
}
}
}

View File

@@ -131,6 +131,11 @@ internal class WarningFloatWindowHelper(
}
}
fun resetDownTime(expireTime: Long) {
config.countDownTime = expireTime
resetDownTime()
}
/**
* 入场动画
*/
@@ -292,5 +297,5 @@ internal class WarningFloatWindowHelper(
windowManager.updateViewLayout(view, params)
}
fun isShow(): Boolean = config.isShow
}

View File

@@ -18,15 +18,17 @@ internal object WarningFloatWindowManager {
* 创建浮窗tag不存在创建tag存在创建失败
* 创建结果通过tag添加到相应的map进行管理
*/
fun create(context: Context, config: WarningNotificationConfig) {
fun create(context: Context, config: WarningNotificationConfig): Boolean {
if (!checkTag(config)) {
val helper = WarningFloatWindowHelper(context, config)
if (helper.createWindow()) windowMap[config.floatTag!!] = helper
return true
} else {
Log.w(TAG, "存在相同的tag延长弹窗时间")
// 存在相同的tag直接创建失败
config.callbacks?.createdResult(false, "存在相同的tag延长弹窗时间", null)
windowMap[config.floatTag!!]?.resetDownTime()
return false
}
}

View File

@@ -65,4 +65,6 @@ data class WarningNotificationConfig(
// 窗口高度
var height: Int = WindowManager.LayoutParams.WRAP_CONTENT
)
) {
var isOverride: Boolean = true
}

View File

@@ -78,12 +78,6 @@ class V2XWarningBroadcastReceiver : BroadcastReceiver() {
if (EventTypeEnum.TYPE_USECASE_ID_IVP.poiType == v2xType.toString()) {
CallerHmiManager.showLimitingVelocity(1)
}
CallerHmiManager.showWarningV2X(
v2xType,
alertContent,
ttsContent,
tag,
null
)
CallerHmiManager.showWarningV2X(v2xType, alertContent, ttsContent, tag, null, true, 5000L)
}
}

View File

@@ -71,7 +71,6 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
// V2X、OBU、云端推送预警弹窗
private var mWarningFloat: WarningFloat.Builder? = null
// 通知、云公告弹窗
private var mNoticeFloat: WarningFloat.Builder? = null
// 超视距、路侧、前车直播
@@ -581,35 +580,30 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
* @param tag tag绑定弹窗的标志
*/
@Synchronized
override fun showWarningV2X(
v2xType: Int,
alertContent: String?,
ttsContent: String?,
tag: String?,
listenerIMoGo: IMoGoWarningStatusListener?
) {
override fun showWarningV2X(v2xType: Int, alertContent: String?, ttsContent: String?, tag: String?, listenerIMoGo: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long) {
activity?.let {
val floatWindow = mWarningFloat
val showTag = floatWindow?.config?.floatTag
if (floatWindow == null || TextUtils.isEmpty(showTag)) {
val notificationView = V2XNotificationView(it)
notificationView.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType.toString()))
val warningContent = alertContent ?: EventTypeEnum.getWarningContent(v2xType.toString())
if (warningContent.isEmpty()) {
Logger.e(TAG, "Show warningContent is null or empty!")
return
} else {
notificationView.setWarningContent(warningContent)
}
val notificationView = V2XNotificationView(it)
notificationView.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType.toString()))
val warningContent = alertContent ?: EventTypeEnum.getWarningContent(v2xType.toString())
if (warningContent.isNullOrEmpty()) {
Logger.e(TAG, "Show warningContent is null or empty!")
return
} else {
notificationView.setWarningContent(warningContent)
}
if (mWarningFloat != null && mWarningFloat!!.config.floatTag != tag) {
WarningFloat.dismiss(mWarningFloat!!.config.floatTag, true)
}
if (mWarningFloat != null && mWarningFloat!!.config.floatTag != tag) {
WarningFloat.dismiss(mWarningFloat!!.config.floatTag, true)
}
mWarningFloat = WarningFloat.with(it)
mWarningFloat = WarningFloat.with(it)
.setTag(tag)
.setLayout(notificationView)
.setSidePattern(SidePattern.RESULT_TOP)
.setCountDownTime(5000)
.setCountDownTime(expireTime)
.setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110)
.setImmersionStatusBar(true)
.addWarningStatusListener(listenerIMoGo)
@@ -617,37 +611,45 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
override fun onShow() {
// 创建弹窗成功才进行TTS播报
Logger.d(
"MoGoWarningFragment",
"mWarningFloat = $mWarningFloat---ttsContent = $ttsContent"
"MoGoWarningFragment",
"mWarningFloat = $mWarningFloat---ttsContent = $ttsContent"
)
if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent)) {
if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent) && playTts) {
Logger.d("MoGoWarningFragment", "---> ttsContent = $ttsContent")
AIAssist.getInstance(activity)
.speakTTSVoice(ttsContent)
.speakTTSVoice(ttsContent)
}
}
})
.setAnimator(object : DefaultAnimator() {
override fun enterAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.enterAnim(view, params, windowManager, sidePattern)?.apply {
interpolator = OvershootInterpolator()
}
super.enterAnim(view, params, windowManager, sidePattern)?.apply {
interpolator = OvershootInterpolator()
}
override fun exitAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200)
super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200)
})
.show()
} else {
if (floatWindow.isShow()) {
val notification = floatWindow.config.layoutView as? V2XNotificationView
if (alertContent?.isNotEmpty() == true) {
notification?.setWarningContent(alertContent)
floatWindow.resetExpireTime(expireTime)
}
}
}
}
}

View File

@@ -13,7 +13,6 @@ import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.function.api.base.IMoGoFunctionProvider;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.ActivityLifecycleManager;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.module.main.MainActivity;
import com.mogo.service.intent.IMogoIntentListener;
@@ -47,7 +46,7 @@ public class MainLauncherActivity extends MainActivity implements IMogoIntentLis
protected void onStart() {
super.onStart();
getApis().getIntentManagerApi().registerIntentListener(Intent.ACTION_CLOSE_SYSTEM_DIALOGS, this);
ActivityLifecycleManager.getInstance().setAppActive(true);
//ActivityLifecycleManager.getInstance().setAppActive(true);
}
@Override
@@ -60,7 +59,7 @@ public class MainLauncherActivity extends MainActivity implements IMogoIntentLis
protected void onStop() {
super.onStop();
getApis().getIntentManagerApi().unregisterIntentListener(Intent.ACTION_CLOSE_SYSTEM_DIALOGS, this);
ActivityLifecycleManager.getInstance().setAppActive(false);
//ActivityLifecycleManager.getInstance().setAppActive(false);
}
@Override

View File

@@ -340,18 +340,14 @@ class MogoPrivateObuManager private constructor() {
// CallerHmiManager.showWarning(direction)
//显示弹框,语音提示
CallerHmiManager.showWarningV2X(
appId.toInt(),
alertContent,
ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
(appId + direction.direction).toString(),//使用当前事件类型+方向记录tag当发生变化的时候关闭当前弹出新的
object : IMoGoWarningStatusListener {
override fun onDismiss() {
// 关闭警告红边
CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON)
}
CallerHmiManager.showWarningV2X(appId.toInt(), alertContent, ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
(appId + direction.direction).toString(),//使用当前事件类型+方向记录tag当发生变化的时候关闭当前弹出新的
object : IMoGoWarningStatusListener {
override fun onDismiss() {
// 关闭警告红边
CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON)
}
)
}, true, 5000L)
// 更新数据
TrafficDataConvertUtils.cvxRtiThreatIndInfo2TrafficData(info)?.let {
TrafficMarkerDrawer.updateITrafficThreatLevelInfo(it)
@@ -421,18 +417,14 @@ class MogoPrivateObuManager private constructor() {
// if (level == 2 || level == 3) { //不考虑level
//显示警告红边
CallerHmiManager.showWarning(direction)
CallerHmiManager.showWarningV2X(
v2xType.toInt(),
alertContent,
ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
(v2xType + direction.direction).toString(),//使用当前事件类型+方向记录tag当发生变化的时候关闭当前弹出新的
object : IMoGoWarningStatusListener {
override fun onDismiss() {
// 关闭警告红边
CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON)
}
CallerHmiManager.showWarningV2X(v2xType.toInt(), alertContent, ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
(v2xType + direction.direction).toString(),//使用当前事件类型+方向记录tag当发生变化的时候关闭当前弹出新的
object : IMoGoWarningStatusListener {
override fun onDismiss() {
// 关闭警告红边
CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON)
}
)
}, true, 5000L)
// }
// 更新数据
TrafficDataConvertUtils.cvxPtcThreatIndInfo2TrafficData(info)?.let {
@@ -615,13 +607,8 @@ class MogoPrivateObuManager private constructor() {
0x2 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT
ttsContent = EventTypeEnum.getWarningTts(appId.toString())
alertContent = EventTypeEnum.getWarningContent(appId.toString())
CallerHmiManager.showWarningV2X(
appId,
alertContent,
ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
appId.toString(),
null
)
CallerHmiManager.showWarningV2X(appId, alertContent, ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
appId.toString(), null, true, 5000L)
}
0x3 -> {//闯黄灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_YELLOW_LIGHT
}
@@ -685,13 +672,8 @@ class MogoPrivateObuManager private constructor() {
val maxSpeed = currentLight.glosa_suggested_speed_max.toInt()
if (maxSpeed > 0) {
CallerHmiManager.showWarningV2X(
EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType.toInt(),
alertContent,
ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
appId.toString(),
null
)
CallerHmiManager.showWarningV2X(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType.toInt(), alertContent, ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
appId.toString(), null, true, 5000L)
}
}
// 黄灯
@@ -813,18 +795,14 @@ class MogoPrivateObuManager private constructor() {
)
if (level == 2 || level == 3) {
//显示弹框,语音提示
CallerHmiManager.showWarningV2X(
appId,
alertContent,
ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
(appId + direction.direction).toString(),//使用当前事件类型+方向记录tag当发生变化的时候关闭当前弹出新的
object : IMoGoWarningStatusListener {
override fun onDismiss() {
// 关闭警告红边
CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON)
}
CallerHmiManager.showWarningV2X(appId, alertContent, ttsContent,// 只有第一次才tts防止更新的时候不断的提醒
(appId + direction.direction).toString(),//使用当前事件类型+方向记录tag当发生变化的时候关闭当前弹出新的
object : IMoGoWarningStatusListener {
override fun onDismiss() {
// 关闭警告红边
CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON)
}
)
}, true, 5000L)
//显示警告红边
CallerHmiManager.showWarning(direction)
}

View File

@@ -570,7 +570,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb
override fun onShow() {}
override fun onDismiss() {
}
})
}, true, 5000L)
TrafficMarkerDrawer.updateITrafficInfo(trafficData)
}
2 -> {

View File

@@ -1,21 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
/**
* 事件面板viewpager2的adapter
*
* @author tongchenfei
*/
class V2XEventPagerAdapter(fragment: Fragment,
private val fragments: Array<Fragment>) :
FragmentStateAdapter(fragment) {
/**
* 目前一共就三个fragment
*/
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}

View File

@@ -11,7 +11,7 @@ import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XIllegalParkVH;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XLiveVideoVH;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XOtherSeekHelpVH;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XPushEventVH;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XRoadEventVH;
//import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XRoadEventVH;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XWindow;
import com.mogo.module.common.entity.V2XEventShowEntity;
import com.mogo.module.common.entity.V2XMessageEntity;
@@ -46,10 +46,10 @@ public class V2XRoadEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
case V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_LIVE_CAR_WARNING:
holder = new V2XLiveVideoVH(parent, mV2XWindow);
break;
//道路事件详情
case V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING:
holder = new V2XRoadEventVH(parent, mV2XWindow);
break;
// //道路事件详情
// case V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING:
// holder = new V2XRoadEventVH(parent, mV2XWindow);
// break;
//违章停车
case V2XMessageEntity.V2XTypeEnum.ALERT_ILLEGAL_PARK_WARNING:
holder = new V2XIllegalParkVH(parent, mV2XWindow);
@@ -83,9 +83,9 @@ public class V2XRoadEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
if (holder instanceof V2XLiveVideoVH) {
((V2XLiveVideoVH) holder).initView(itemList.get(position));
}
if (holder instanceof V2XRoadEventVH) {
((V2XRoadEventVH) holder).initView(itemList.get(position));
}
// if (holder instanceof V2XRoadEventVH) {
// ((V2XRoadEventVH) holder).initView(itemList.get(position));
// }
if (holder instanceof V2XIllegalParkVH) {
((V2XIllegalParkVH) holder).initView(itemList.get(position));
}

View File

@@ -1,102 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XScenarioHistoryIllegalParkVH;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XScenarioHistoryOtherSeekHelpVH;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XScenarioHistoryRoadEventVH;
import com.mogo.module.common.entity.V2XHistoryScenarioData;
import com.mogo.module.common.entity.V2XMessageEntity;
import java.util.ArrayList;
/**
* @author donghongyu
*/
public class V2XScenarioHistoryAdapter extends RecyclerView.Adapter<ViewHolder> {
private ArrayList<V2XHistoryScenarioData> mV2XHistoryScenarioData;
public V2XScenarioHistoryAdapter(ArrayList<V2XHistoryScenarioData> v2XHistoryScenarioData) {
if (v2XHistoryScenarioData != null) {
this.mV2XHistoryScenarioData = v2XHistoryScenarioData;
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ViewHolder holder;
switch (viewType) {
//道路事件详情
case V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING:
holder = new V2XScenarioHistoryRoadEventVH(parent);
break;
//违章停车
case V2XMessageEntity.V2XTypeEnum.ALERT_ILLEGAL_PARK_WARNING:
holder = new V2XScenarioHistoryIllegalParkVH(parent);
break;
//他人故障求助
case V2XMessageEntity.V2XTypeEnum.ALERT_SEEK_WARNING:
holder = new V2XScenarioHistoryOtherSeekHelpVH(parent);
break;
//没有更多的数据的Footer
default:
View footerView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.footer_nomore_view, parent, false);
holder = new FooterViewHolder(footerView);
break;
}
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
if (position < mV2XHistoryScenarioData.size()) {
if (holder instanceof V2XScenarioHistoryRoadEventVH) {
((V2XScenarioHistoryRoadEventVH) holder).initView(mV2XHistoryScenarioData.get(position));
}
if (holder instanceof V2XScenarioHistoryIllegalParkVH) {
((V2XScenarioHistoryIllegalParkVH) holder).initView(mV2XHistoryScenarioData.get(position));
}
if (holder instanceof V2XScenarioHistoryOtherSeekHelpVH) {
((V2XScenarioHistoryOtherSeekHelpVH) holder).initView(mV2XHistoryScenarioData.get(position));
}
}
}
@Override
public int getItemViewType(int position) {
if (position < mV2XHistoryScenarioData.size()) {
return mV2XHistoryScenarioData.get(position).getScenarioType();
} else {
// 没有更多的Footer
return -1;
}
}
@Override
public int getItemCount() {
// 多添加一个Footer
return mV2XHistoryScenarioData == null ? 0 : mV2XHistoryScenarioData.size() + 1;
}
/**
* Footer 视图
*/
static class FooterViewHolder extends RecyclerView.ViewHolder {
public FooterViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}

View File

@@ -1,240 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventDescription;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventItem;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventItemEnum;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventLoadMoreItem;
import com.mogo.eagle.core.function.v2x.events.fragment.V2XEventPanelFragment;
import com.mogo.eagle.core.function.v2x.events.listener.AdapterCallback;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.module.common.enums.EventTypeEnum;
import com.mogo.module.common.view.CustomRatingBar;
import com.mogo.service.IMogoServiceApis;
import com.mogo.eagle.core.data.constants.MogoServicePaths;
import java.util.ArrayList;
public class V2XShareEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ArrayList dataArrayList;
private final LayoutInflater shareLayoutInflater;
private IMogoServiceApis mApis;
private AdapterCallback callback;
public V2XShareEventAdapter(Context context, ArrayList dataArrayList, AdapterCallback callback) {
this.context = context;
this.dataArrayList = dataArrayList;
this.callback = callback;
shareLayoutInflater = LayoutInflater.from(context);
mApis = (IMogoServiceApis) ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(context);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//根据viewType创建自定义布局
if (viewType == V2XShareEventItemEnum.ITEM_TYPE_NUM_DES) {
View v = shareLayoutInflater.inflate(R.layout.module_v2x_event_share_description, parent,
false);
shareDescriptionViewHolder holder = new shareDescriptionViewHolder(v);
return holder;
} else if (viewType == V2XShareEventItemEnum.ITEM_TYPE_SHARE_LIST) {
View v = shareLayoutInflater.inflate(R.layout.module_v2x_event_share_item, parent,
false);
shareItemViewHolder holder = new shareItemViewHolder(v);
return holder;
} else if (viewType == V2XShareEventItemEnum.ITEM_TYPE_SHARE_EMPTY) {
View v = shareLayoutInflater.inflate(R.layout.module_v2x_event_share_empty, parent,
false);
shareEmptyViewHolder holder = new shareEmptyViewHolder(v);
return holder;
} else if (viewType == V2XShareEventItemEnum.ITEM_TYPE_LOAD_MORE_STATUS) {
View v = shareLayoutInflater.inflate(R.layout.item_v2x_event_share_load_more, parent,
false);
shareLoadStatusViewHolder holder = new shareLoadStatusViewHolder(v);
return holder;
} else {
View v = shareLayoutInflater.inflate(R.layout.footer_nomore_view, parent,
false);
shareLoadNoMoreViewHolder holder = new shareLoadNoMoreViewHolder(v);
return holder;
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
try {
if (holder instanceof shareDescriptionViewHolder) {
//分享次数,车友认同次数,热心指数
if (dataArrayList.size() > position) {
V2XShareEventDescription.ResultBean.EnthusiasmIndexBean data = (V2XShareEventDescription.ResultBean.EnthusiasmIndexBean) dataArrayList.get(position);
if (data != null) {
String shareNum = String.valueOf(data.getShareNum());
String likeNum = String.valueOf(data.getLikeNum());
double enthusiasmIndex = data.getEnthusiasmIndex() <= 5 ? data.getEnthusiasmIndex() : 5;
if (shareNum != null) {
((shareDescriptionViewHolder) holder).shareNumTextView.setText(shareNum);
}
if (likeNum != null) {
((shareDescriptionViewHolder) holder).approveNumTextView.setText(likeNum);
}
((shareDescriptionViewHolder) holder).ratingBar.setRating((float) enthusiasmIndex);
}
}
} else if (holder instanceof shareItemViewHolder) {
//分享列表
if (dataArrayList.size() > position) {
V2XShareEventItem.ResultBean.PageBean.ContentBean data = (V2XShareEventItem.ResultBean.PageBean.ContentBean) dataArrayList.get(position);
if (data != null) {
String poitype = data.getPoiType();
String address = data.getUploadAddress();
String time = DateTimeUtils.getTimeText(data.getUploadTimestamp(), DateTimeUtils.MM_Yue_dd_Ri_HH_mm);
String likeNum = String.valueOf(data.getLikeNum());
String notLikeNum = String.valueOf(data.getNotlikeNum());
if (poitype != null) {
((shareItemViewHolder) holder).caseStyleTextView.setText(EventTypeEnum.getPoiTypeStr(poitype));
((shareItemViewHolder) holder).caseStyleTextView.setBackgroundResource(EventTypeEnum.getPoiTypeBgForShareItem(poitype));
}
if (address != null) {
((shareItemViewHolder) holder).caseAddressTextView.setText(address);
}
if (time != null) {
((shareItemViewHolder) holder).caseTimeTextView.setText(time);
}
if (likeNum != null) {
((shareItemViewHolder) holder).caseUsefulTextView.setText(likeNum);
}
if (notLikeNum != null) {
((shareItemViewHolder) holder).caseUselessTextView.setText(notLikeNum);
}
}
}
}
} catch (Exception e) {
}
}
@Override
public int getItemCount() {
return dataArrayList.size();
}
@Override
public int getItemViewType(int position) {
Object item = dataArrayList.get(position);
if (item instanceof V2XShareEventDescription.ResultBean.EnthusiasmIndexBean) {
return V2XShareEventItemEnum.ITEM_TYPE_NUM_DES;
} else if (item instanceof V2XShareEventItem.ResultBean.PageBean.ContentBean) {
return V2XShareEventItemEnum.ITEM_TYPE_SHARE_LIST;
} else if (item instanceof V2XShareEventLoadMoreItem) {
return ((V2XShareEventLoadMoreItem) dataArrayList.get(position)).getViewType();
}
return V2XShareEventItemEnum.ITEM_TYPE_OTHER;
}
/*
* 分享列表
* */
class shareItemViewHolder extends RecyclerView.ViewHolder {
private TextView caseStyleTextView;
private TextView caseAddressTextView;
private TextView caseTimeTextView;
private TextView caseUsefulTextView;
private TextView caseUselessTextView;
public shareItemViewHolder(@NonNull View itemView) {
super(itemView);
caseStyleTextView = itemView.findViewById(R.id.road_case_style);
caseAddressTextView = itemView.findViewById(R.id.road_case_address);
caseTimeTextView = itemView.findViewById(R.id.road_case_share_time);
caseUsefulTextView = itemView.findViewById(R.id.road_case_useful_num);
caseUselessTextView = itemView.findViewById(R.id.road_case_useless_num);
}
}
/*
* 分享次数,热心指数...
* */
class shareDescriptionViewHolder extends RecyclerView.ViewHolder {
private TextView shareNumTextView;
private TextView approveNumTextView;
private CustomRatingBar ratingBar;
public shareDescriptionViewHolder(@NonNull View itemView) {
super(itemView);
shareNumTextView = itemView.findViewById(R.id.share_num);
approveNumTextView = itemView.findViewById(R.id.share_approve);
ratingBar = itemView.findViewById(R.id.rating_bar);
}
}
/*
* 去分享 刷新
* */
class shareEmptyViewHolder extends RecyclerView.ViewHolder {
public shareEmptyViewHolder(@NonNull View itemView) {
super(itemView);
TextView share = itemView.findViewById(R.id.share_event_button);
share.setOnClickListener(view -> {
// TODO
// V2XEventPanelFragment.Companion.getInstance().hidePanel();
// mApis.getShareManager().showShareDialog();
});
TextView refresh = itemView.findViewById(R.id.refresh_button);
refresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.getShareEventResponse();
}
});
}
}
/*
* 加载更多/没有更多
* */
class shareLoadStatusViewHolder extends RecyclerView.ViewHolder {
private TextView statusButton;
public shareLoadStatusViewHolder(@NonNull View itemView) {
super(itemView);
statusButton = itemView.findViewById(R.id.event_share_load_status);
;
statusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.loadMoreShareEventList();
}
});
}
}
/*
* 没有更多记录了
* */
class shareLoadNoMoreViewHolder extends RecyclerView.ViewHolder {
public shareLoadNoMoreViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}

View File

@@ -1,105 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter;
import android.content.Context;
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.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XSurroundingViewHolder;
import com.mogo.eagle.core.function.v2x.events.entity.panel.SurroundingConstruction;
import com.mogo.eagle.core.function.v2x.events.listener.SurroundingItemClickListener;
import com.mogo.module.common.enums.EventTypeEnum;
import java.util.List;
/**
* @author lixiaopeng
* @description 周边
* @since 2020/7/29
*/
public class V2XSurroundingAdapter extends RecyclerView.Adapter<V2XSurroundingViewHolder> {
private List<SurroundingConstruction> mPoiInfosList;
private Context mContext;
private ImageView mBgImageView;
private ImageView mTypeImageView;
private TextView mTypeTv;
private TextView mTotalTv;
private SurroundingItemClickListener mClickListener;
public V2XSurroundingAdapter(Context context, List<SurroundingConstruction> poiInfosList, SurroundingItemClickListener clickListener) {
mContext = context;
mPoiInfosList = poiInfosList;
mClickListener = clickListener;
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
@NonNull
@Override
public V2XSurroundingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View inflate = LayoutInflater.from(parent.getContext())
.inflate(R.layout.module_fragment_surrounding_event_item, parent, false);
return new V2XSurroundingViewHolder(inflate);
}
@Override
public void onBindViewHolder(@NonNull V2XSurroundingViewHolder holder, final int position) {
final SurroundingConstruction surroundingConstruction = mPoiInfosList.get(position);
if (surroundingConstruction == null) {
return;
}
mBgImageView = holder.itemView.findViewById(R.id.iv_event_bg);
mTypeImageView = holder.itemView.findViewById(R.id.iv_event_type);
mTypeTv = holder.itemView.findViewById(R.id.tv_poitype);
mTotalTv = holder.itemView.findViewById(R.id.tv_info_total);
mTypeTv.setText(EventTypeEnum.getTypeName(surroundingConstruction.getPoiType()));
if (surroundingConstruction.getConstrutList() != null) {
mTotalTv.setText(surroundingConstruction.getConstrutList().size() + "");
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mClickListener != null) {
mClickListener.onItemClickListener(v, holder.getAdapterPosition(), surroundingConstruction);
}
}
});
mBgImageView.setBackgroundResource(EventTypeEnum.getTypeRes(surroundingConstruction.getPoiType()));
mTypeImageView.setBackgroundResource(EventTypeEnum.getTypeSmallRes(surroundingConstruction.getPoiType()));
// RequestOptions requestOptions = new RequestOptions()
// .placeholder(R.drawable.v2x_icon_live_logo)
// .error(R.drawable.v2x_icon_live_logo)
// .fallback(R.drawable.v2x_icon_live_logo);
// Glide.with(mContext)
// .asBitmap()
// .load(getTypeSmallRes(surroundingConstruction.getPoiType()))
// .apply(requestOptions)
// .into(new SkinAbleBitmapTarget(mTypeImageView, requestOptions));
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
@Override
public int getItemCount() {
return mPoiInfosList == null ? 0 : mPoiInfosList.size();
}
}

View File

@@ -1,135 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.adapter.holder.V2XSurroundingDetailVH;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.listener.SurroundingDetailItemListener;
import com.mogo.eagle.core.function.v2x.events.utils.RoadConditionUtils;
import com.mogo.eagle.core.function.v2x.events.view.HeartLikeView;
import com.mogo.eagle.core.function.v2x.events.view.HeartUnLikeView;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.enums.EventTypeEnum;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import java.util.List;
/**
* @author lixiaopeng
* @description 周边详情
* @since 2020/11/18
*/
public class V2XSurroundingDetailAdapter extends RecyclerView.Adapter<V2XSurroundingDetailVH> {
private List<MarkerExploreWay> markerExploreWays;
private Context mContext;
private TextView mTypeTv;
private TextView mAddressTv;
private TextView mUserNameTv;
private TextView mTimeTv;
private HeartLikeView mHeartLikeView;
private HeartUnLikeView mUnHeartLikeView;
private SurroundingDetailItemListener mListener;
public V2XSurroundingDetailAdapter(Context context, List<MarkerExploreWay> list, SurroundingDetailItemListener listener) {
mContext = context;
markerExploreWays = list;
mListener = listener;
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
@NonNull
@Override
public V2XSurroundingDetailVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View inflate = LayoutInflater.from(parent.getContext())
.inflate(R.layout.module_v2x_event_surrounding_detail_item, parent, false);
return new V2XSurroundingDetailVH(inflate);
}
@Override
public void onBindViewHolder(@NonNull V2XSurroundingDetailVH holder, final int position) {
final MarkerExploreWay exploreWay = markerExploreWays.get(position);
if (exploreWay == null) {
return;
}
mAddressTv = holder.itemView.findViewById(R.id.surrounding_road_type_address);
mUserNameTv = holder.itemView.findViewById(R.id.surrounding_username);
mTimeTv = holder.itemView.findViewById(R.id.surrounding_time);
mTypeTv = holder.itemView.findViewById(R.id.surrounding_road_type);
mHeartLikeView = holder.itemView.findViewById(R.id.surrounding_road_like);
mUnHeartLikeView = holder.itemView.findViewById(R.id.surrounding_road_unlike);
mUserNameTv.setText( exploreWay.getUserInfo() != null ? ("用户" + exploreWay.getUserInfo().getUserName() + "分享") : "蘑菇用户分享");
mTypeTv.setText(EventTypeEnum.getTypeName(exploreWay.getPoiType()));
mAddressTv.setText(exploreWay.getAddr());
mTimeTv.setText(DateTimeUtils.getTimeText(exploreWay.getGenerateTime(), DateTimeUtils.MM_Yue_dd_Ri_HH_mm));
Logger.d(V2XConst.MODULE_NAME, "exploreWay.isFabulous() = " + exploreWay.isFabulous());
showView(exploreWay.isFabulous());
mHeartLikeView.setOnClickCallListener(v -> {
Logger.d(V2XConst.MODULE_NAME, "反馈有用 position = " + position);
roadReportTrue(exploreWay);
mListener.onItemClickListener(v, position, exploreWay);
});
mUnHeartLikeView.setOnClickCallListener(v -> {
Logger.d(V2XConst.MODULE_NAME, "反馈无用 position = " + position);
roadReportErr(exploreWay);
mListener.onItemClickListener(v, position, exploreWay);
});
}
private void showView(boolean isAlreadyShow) {
if (isAlreadyShow) {
mHeartLikeView.setVisibility(View.GONE);
mUnHeartLikeView.setVisibility(View.GONE);
} else {
mHeartLikeView.setVisibility(View.VISIBLE);
mUnHeartLikeView.setVisibility(View.VISIBLE);
}
}
/**
* 反馈路况正确
*/
private void roadReportTrue(MarkerExploreWay exploreWay) {
if (exploreWay != null) {
RoadConditionUtils.sendShareReceiverInfo(
exploreWay.getInfoId(),
exploreWay.getPoiType(),
2);
}
}
/**
* 反馈路况错误
*/
private void roadReportErr(MarkerExploreWay exploreWay) {
if (exploreWay != null) {
RoadConditionUtils.sendShareReceiverInfo(
exploreWay.getInfoId(),
exploreWay.getPoiType(),
3);
}
}
@Override
public int getItemCount() {
return markerExploreWays == null ? 0 : markerExploreWays.size();
}
}

View File

@@ -1,233 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import static com.mogo.eagle.core.function.v2x.events.consts.V2XConst.MODULE_NAME;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.utils.ChartingUtil;
import com.mogo.eagle.core.function.v2x.events.utils.RoadConditionUtils;
import com.mogo.eagle.core.function.v2x.events.utils.TrackUtils;
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.TimeUtils;
import com.mogo.eagle.core.utilcode.util.Utils;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.navi.MogoTraffic;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.V2XEventZanData;
import com.mogo.service.module.IMogoRegisterCenter;
import com.zhidao.carchattingprovider.CallChattingProviderConstant;
import com.zhidao.carchattingprovider.ICarsChattingProvider;
import com.zhidao.carchattingprovider.MogoDriverInfo;
/**
* 出行动态
*
* @author donghongyu
*/
public abstract class V2XHistoryBaseViewHolder<T>
extends RecyclerView.ViewHolder
implements IMogoNaviListener {
private static final String TAG = "V2XBaseViewHolder";
private ICarsChattingProvider mCarsChattingProvider;
public V2XHistoryBaseViewHolder(@NonNull View itemView) {
super(itemView);
}
/**
* 填充View视图
*
* @param viewData 与视图绑定的数据
*/
public abstract void initView(T viewData);
/**
* 延迟关闭窗体视图
*/
public void delayedCloseWindow() {
}
/**
* 点赞
*/
public void triggerZan(MarkerExploreWay noveltyInfo) {
try {
AIAssist.getInstance(Utils.getApp()).speakTTSVoice("已点赞", null);
showTip("已点赞");
if (noveltyInfo != null) {
// 调用网络API接口
BridgeApi.INSTANCE.refreshModel().giveLikeLiveVideo(null, noveltyInfo.getSn());
V2XEventZanData v2XEventZanData = new V2XEventZanData();
v2XEventZanData.setEventId(noveltyInfo.getInfoId());
v2XEventZanData.setTriggerTime(TimeUtils.getNowMills());
V2XSQLiteUtils.saveEventZanLocalStory(v2XEventZanData);
// 上报数据统计
TrackUtils.trackV2xRoadEvent(
noveltyInfo.getInfoId(),
noveltyInfo.getSn(),
V2XConst.V2X_ROAD_ZAN);
}
} catch (Exception e) {
e.printStackTrace();
}
delayedCloseWindow();
}
public void triggerIVReportHead(MarkerExploreWay noveltyInfo) {
Log.d(TAG, "点击头像" + mCarsChattingProvider);
try {
mCarsChattingProvider = (ICarsChattingProvider) ARouter.getInstance().build(CallChattingProviderConstant.CAR_CALL_PROVIDER).navigation();
MogoDriverInfo mogoDriverInfo = new MogoDriverInfo();
int ageNumber = noveltyInfo.getUserInfo().getAgeNumber();
mogoDriverInfo.setAge(ageNumber);
String gender = noveltyInfo.getUserInfo().getGender();
mogoDriverInfo.setGender(gender);
String sn = noveltyInfo.getUserInfo().getSn();
mogoDriverInfo.setSn(sn != null ? sn : "");
String name = noveltyInfo.getUserInfo().getUserName();
mogoDriverInfo.setUserName(name != null ? name : "");
mogoDriverInfo.setUserHead(noveltyInfo.getUserInfo().getUserHead());
if (mCarsChattingProvider != null) {
mCarsChattingProvider.showUserWindow(MODULE_NAME, mogoDriverInfo, this.itemView.getContext());
}
} catch (Exception e) {
Log.d(TAG, "点击头像发生错误--triggerIVReportHead" + e);
e.printStackTrace();
}
}
/**
* 打电话
*/
public void triggerCallChart(MarkerExploreWay noveltyInfo) {
try {
MarkerLocation location = new MarkerLocation();
location.setLat(noveltyInfo.getLocation().getLat());
location.setLon(noveltyInfo.getLocation().getLon());
ChartingUtil.callChatting(noveltyInfo.getUserInfo(), location);
TrackUtils.trackV2xRoadEvent(
noveltyInfo.getInfoId(),
noveltyInfo.getSn(),
V2XConst.V2X_ROAD_CHAT);
} catch (Exception e) {
e.printStackTrace();
TipToast.tip("用户信息异常");
}
delayedCloseWindow();
}
/**
* 反馈路况错误
*/
public void triggerReportErr(MarkerExploreWay noveltyInfo) {
try {
RoadConditionUtils.sendShareReceiverInfo(
noveltyInfo.getInfoId(),
noveltyInfo.getPoiType(),
3);
TrackUtils.trackV2xRoadEvent(
noveltyInfo.getInfoId(),
noveltyInfo.getSn(),
V2XConst.V2X_ROAD_REPORT_ERROR);
} catch (Exception e) {
e.printStackTrace();
TipToast.tip("路况信息异常");
}
delayedCloseWindow();
}
/**
* 反馈路况正确
*/
public void triggerReportTrue(MarkerExploreWay noveltyInfo) {
try {
RoadConditionUtils.sendShareReceiverInfo(
noveltyInfo.getInfoId(),
noveltyInfo.getPoiType(),
2);
TrackUtils.trackV2xRoadEvent(
noveltyInfo.getInfoId(),
noveltyInfo.getSn(),
V2XConst.V2X_ROAD_REPORT_RIGHT);
} catch (Exception e) {
e.printStackTrace();
TipToast.tip("路况信息异常");
}
delayedCloseWindow();
}
/**
* 显示自定义 Toast
*
* @param msg
*/
public void showTip(String msg) {
TipToast.tip(msg);
}
@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() {
Logger.w(TAG, "onCalculateSuccess");
IMogoRegisterCenter registerCenter = BridgeApi.INSTANCE.registerCenter();
if (registerCenter != null) {
registerCenter.unregisterMogoNaviListener(MODULE_NAME);
}
}
@Override
public void onoCalculateFailed() {
}
@Override
public void onUpdateTraffic(MogoTraffic traffic) {
}
}

View File

@@ -1,544 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static com.mogo.eagle.core.function.v2x.events.consts.V2XConst.MODULE_NAME;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.enums.WarningDirectionEnum;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi;
import com.mogo.eagle.core.function.v2x.events.entity.net.V2XUserInfoRes;
import com.mogo.eagle.core.function.v2x.events.network.V2XRefreshCallback;
import com.mogo.eagle.core.function.v2x.events.scenario.scene.livecar.V2XRoadLiveCarScenario;
import com.mogo.eagle.core.function.v2x.events.scenario.scene.road.V2XRoadEventWindow;
import com.mogo.eagle.core.function.v2x.events.scenario.scene.road.V2XRoadVideoCarScenario;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XWindow;
import com.mogo.eagle.core.function.v2x.events.utils.ChartingUtil;
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils;
import com.mogo.eagle.core.function.v2x.events.view.HeartLikeView;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceCallbackListener;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceConstants;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.glide.GlideRoundedCornersTransform;
import com.mogo.eagle.core.utilcode.util.CollectionUtils;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.module.common.animation.BezierAnimationView;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerUserInfo;
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.enums.EventTypeEnum;
import com.mogo.module.common.wm.WindowManagerView;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.service.imageloader.IMogoImageloader;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.v2x.DisplayEffectsInterface;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/11 4:35 PM
* desc : 道路事件详情
* version: 1.0
*
* @author donghongyu
*/
public class V2XRoadEventVH extends V2XBaseViewHolder<V2XEventShowEntity> {
private static final String TAG = "V2XRoadEventVH";
private Context mContext;
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 HeartLikeView ivEventZan;
private WindowManagerView mWindowManagerView;
// 上传事件的用户信息
private MarkerUserInfo mUserInfo;
// 当前的新鲜事儿信息
private MarkerExploreWay mNoveltyInfo;
private V2XRoadEventEntity mV2XRoadEventEntity;
private V2XEventShowEntity mV2XEventShowEntity;
// 拨打车聊聊语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackCallListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
triggerCallChart(mNoveltyInfo);
}
};
// 点赞语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackLickListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
triggerZan(mNoveltyInfo);
}
};
// 反馈"正确"语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackReportTrueListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
triggerReportTrue(mNoveltyInfo);
}
};
// 反馈"错误"语音回调
private V2XVoiceCallbackListener v2XVoiceCallbackReportErrorListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
triggerReportErr(mNoveltyInfo);
}
};
// 反馈"错误"语音回调
private V2XVoiceCallbackListener v2XVoiceOpenLiveListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
showLiveCar(mV2XEventShowEntity);
}
};
// 查看车辆信息
private V2XVoiceCallbackListener v2xVoiceOpenCarInfoListener = new V2XVoiceCallbackListener() {
@Override
public void onCallback(String command, Intent intent) {
triggerIVReportHead(mNoveltyInfo);
}
};
private MogoImageView ivEvent;
private TextView tvEvent;
private ImageView ivPlay;
private TextView tvLine;
private TextView tvPlay;
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);
ivEvent = itemView.findViewById(R.id.iv_event);
tvEvent = itemView.findViewById(R.id.tv_event);
ivPlay = itemView.findViewById(R.id.iv_play);
tvLine = itemView.findViewById(R.id.tv_line);
tvPlay = itemView.findViewById(R.id.tv_play);
}
public V2XRoadEventVH(ViewGroup viewGroup, IV2XWindow v2XWindow) {
super(BridgeApi.INSTANCE.statusManager() != null && BridgeApi.INSTANCE.statusManager().isVrMode() ?
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_v2x_event_detail_vr, viewGroup, false) :
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_v2x_event_detail, viewGroup, false)
, v2XWindow);
mContext = viewGroup.getContext();
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)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_CAR_INFO_UN_WAKEUP,
v2xVoiceOpenCarInfoListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
Log.d(TAG, "onViewDetachedFromWindow unRegister");
// 反注册语音交互
V2XVoiceManager.INSTANCE
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_CHATTING)
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_ZAN)
.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)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_CAR_INFO_UN_WAKEUP);
}
});
}
@Override
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) {
mUserInfo = mNoveltyInfo.getUserInfo();
if (!CollectionUtils.isEmpty(mNoveltyInfo.getItems())) {
String imgUrl = mNoveltyInfo.getItems().get(0).getThumbnail();
String url = mNoveltyInfo.getItems().get(0).getUrl();
if (TextUtils.isEmpty(imgUrl)) {
imgUrl = mNoveltyInfo.getItems().get(0).getUrl();
}
if (!TextUtils.isEmpty(imgUrl)) {
boolean isVrMode = false;
IMogoStatusManager statusManager = BridgeApi.INSTANCE.statusManager();
if (statusManager != null) {
isVrMode = statusManager.isVrMode();
}
if (isVrMode) {
Glide.with(mContext).load(imgUrl).apply(RequestOptions.bitmapTransform(
new GlideRoundedCornersTransform(20, GlideRoundedCornersTransform.CornerType.LEFT))).into(ivEventImg);
} else {
IMogoImageloader imageloader = BridgeApi.INSTANCE.imageLoader();
if (imageloader != null) {
imageloader.displayImage(imgUrl, ivEventImg);
}
}
}
if (url.contains(".mp4")) {
ivEventImg.setOnClickListener(v -> {
showRoadVideoInfo(v2XEventShowEntity);
});
ivPlay.setVisibility(VISIBLE);
tvLine.setVisibility(VISIBLE);
tvPlay.setVisibility(VISIBLE);
tvPlay.setOnClickListener(v -> {
showRoadVideoInfo(v2XEventShowEntity);
});
ivEventPlay.setOnClickListener(v -> {
showRoadVideoInfo(v2XEventShowEntity);
});
ivEventPlay.setVisibility(VISIBLE);
} else {
ivEventImg.setOnClickListener(null);
ivEventPlay.setOnClickListener(null);
ivEventPlay.setVisibility(GONE);
ivPlay.setVisibility(GONE);
tvLine.setVisibility(GONE);
tvPlay.setVisibility(GONE);
}
}
if (mNoveltyInfo.getUserInfo() != null &&
!TextUtils.isEmpty(mNoveltyInfo.getUserInfo().getUserHead())) {
IMogoImageloader imageloader = BridgeApi.INSTANCE.imageLoader();
if (imageloader != null) {
imageloader.displayImage(mNoveltyInfo.getUserInfo().getUserHead(), ivReportHead);
}
}
String poiType = EventTypeEnum.getPoiTypeStr(mNoveltyInfo.getPoiType());
if (!TextUtils.isEmpty(poiType)) {
tvEventTypeTitle.setText(poiType);
tvEventTypeTitle.setBackgroundResource(EventTypeEnum.getPoiTypeBg(mNoveltyInfo.getPoiType(),
BridgeApi.INSTANCE.statusManager() != null && BridgeApi.INSTANCE.statusManager().isVrMode()));
}
ivEvent.setImageResource(EventTypeEnum.getPoiTypeSrcVr(mNoveltyInfo.getPoiType()));
tvEvent.setText(EventTypeEnum.getPoiTypeStrVr(mNoveltyInfo.getPoiType()));
if (EventTypeEnum.FOURS_FOG.getPoiType().equals(mNoveltyInfo.getPoiType())) {
DisplayEffectsInterface displayEffects = BridgeApi.INSTANCE.displayEffects();
if (displayEffects != null) {
displayEffects.displayEffects(EventTypeEnum.FOURS_FOG.getPoiType());
}
CallerHmiManager.INSTANCE.showWarning(WarningDirectionEnum.ALERT_WARNING_TOP);
}
tvEventAddress.setText(mNoveltyInfo.getAddr());
tvEventDistance.setText("距离 " + (int) mNoveltyInfo.getDistance() + "");
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);
}
if (!CollectionUtils.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);
if (V2XSQLiteUtils.isZanEvent(mNoveltyInfo.getInfoId())) {
ivEventZan.setVisibility(GONE);
} else {
ivEventZan.setVisibility(VISIBLE);
}
// 用户上报的才会展示拨打电话
if (!TextUtils.isEmpty(mNoveltyInfo.getUploadType())
&& mNoveltyInfo.getUploadType().equals("1")) {
requestUserInfo(mNoveltyInfo);
}
ivEventReportTrue.setOnClickListener(v -> {
triggerReportTrue(mNoveltyInfo);
});
ivEventReportErr.setOnClickListener(v -> {
triggerReportErr(mNoveltyInfo);
});
ivEventCallChart.setOnClickListener(v -> {
ivEventCallChart.setVisibility(GONE);
triggerCallChart(mNoveltyInfo);
});
ivEventZan.setOnClickCallListener(v -> {
triggerZan(mNoveltyInfo);
});
ivReportHead.setOnClickListener(v -> {
triggerIVReportHead(mNoveltyInfo);
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 展示事件的图片/视频资源
* */
private void showRoadVideoInfo(V2XEventShowEntity v2XEventShowEntity) {
if (v2XEventShowEntity != null) {
/*
* MarkerExploreWay 具体事件
* V2XRoadEventEntity 包含MarkerExploreWay 事件的二次封装(tts播报内容 事件类型等)
* V2XMessageEntity 三次封装(是否进行事件与本机连线 是否显示通话功能等)
* V2XEventShowEntity 包含V2XRoadEventEntity
* */
Log.d(TAG, "马上展示图片/视频资源全屏");
V2XMessageEntity v2XMessageEntity = new V2XMessageEntity<>();
v2XMessageEntity.setContent(v2XEventShowEntity);
V2XRoadVideoCarScenario.getInstance().init(v2XMessageEntity);
}
}
/**
* 展示直播信息
*
* @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(V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_LIVE_CAR_WARNING);
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);
// 打开直播后,窗口倒计时暂停关闭,直播被关闭后继续倒计时
if (mV2XWindow != null) {
if (mV2XWindow instanceof V2XRoadEventWindow) {
((V2XRoadEventWindow) mV2XWindow).stopCountDown();
}
}
}
}
private void bezierAnimation(int[] loc) {
if (mWindowManagerView == null) {
Log.d(TAG, "bezierAnimation:null");
mWindowManagerView = new WindowManagerView.Builder(mContext.getApplicationContext())
.contentView(R.layout.module_common_bezier_layout)
.size(WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT)
.position(loc[0], loc[1])
.gravity(Gravity.TOP | Gravity.LEFT)
.showInWindowManager();
}
try {
if (mWindowManagerView.isShowing()) {
return;
}
mWindowManagerView.show();
} catch (Exception e) {
e.printStackTrace();
}
BezierAnimationView bezierAnimationView = mWindowManagerView.findViewById(R.id.bezier_view);
bezierAnimationView.bezierAnimationStart();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// mWindowManagerView.dismiss();
}
}, 2000);
}
public int[] getLocation(View v) {
int[] loc = new int[4];
int[] location = new int[2];
v.getLocationOnScreen(location);
loc[0] = location[0];
loc[1] = location[1];
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(w, h);
loc[2] = v.getMeasuredWidth();
loc[3] = v.getMeasuredHeight();
//base = computeWH();
return loc;
}
/**
* 为了给车聊聊更多的信息需要重新查询一次
*
* @param noveltyInfo
*/
private void requestUserInfo(MarkerExploreWay noveltyInfo) {
Logger.d(MODULE_NAME, "上报事件的用户SN" + noveltyInfo.getSn());
// 获取道路事件周边的直播车机
if (!TextUtils.isEmpty(noveltyInfo.getSn())) {
BridgeApi.INSTANCE.refreshModel()
.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());
// 重新设置用户信息
mNoveltyInfo.setUserInfo(mUserInfo);
// M1低配车机限制
// 不展示打电话按钮
// 不能查看用户详情
if (DebugConfig.isMapBased()) {
// 只有自研车机才会 有车聊聊通话
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);
}
});
}
}
//
// /**
// * 延迟关闭窗体
// */
// @Override
// public void delayedCloseWindow() {
//// itemView.postDelayed(() -> {
//// // 移除窗体
//// V2XServiceManager
//// .getIMogoWindowManager()
//// .removeView(V2XRoadEventScenario.getInstance().getV2XWindow().getView());
//// V2XRoadEventScenario.getInstance().close();
//// }, 1000);
// }
}

View File

@@ -1,133 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.utils.RoadConditionUtils;
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils;
import com.mogo.eagle.core.function.v2x.events.view.HeartLikeView;
import com.mogo.eagle.core.function.v2x.events.view.HeartUnLikeView;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.V2XHistoryScenarioData;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
/**
* 出行面板违章停车
*
* @author donghongyu
*/
public class V2XScenarioHistoryIllegalParkVH extends V2XHistoryBaseViewHolder<V2XHistoryScenarioData> {
private TextView mTvAddress;
private TextView mTvIllegalNum;
private TextView mTagEventType;
private TextView mTagEventEvaluate;
private HeartLikeView mLlIllegalParkingLike;
private HeartUnLikeView mLlIllegalParkingUnLike;
private MarkerExploreWay mExploreWay;
private V2XHistoryScenarioData mOldScenarioData;
public V2XScenarioHistoryIllegalParkVH(ViewGroup viewGroup) {
super(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_v2x_scennario_history, viewGroup, false));
mTvAddress = itemView.findViewById(R.id.tvAddress);
mTvIllegalNum = itemView.findViewById(R.id.tvIllegalNum);
mTagEventType = itemView.findViewById(R.id.tagEventType);
mTagEventEvaluate = itemView.findViewById(R.id.tagEventEvaluate);
mLlIllegalParkingLike = itemView.findViewById(R.id.llIllegalParkingLike);
mLlIllegalParkingUnLike = itemView.findViewById(R.id.llIllegalParkingUnLike);
}
@Override
public void initView(V2XHistoryScenarioData viewData) {
try {
mOldScenarioData = viewData;
mExploreWay = GsonUtil.objectFromJson(viewData.getEventJsonData(), MarkerExploreWay.class);
mTvAddress.setText(mExploreWay.getAddr());
try {
mTvIllegalNum.setText("违章人数:" + (int) mExploreWay.getItems().get(0).getIllegalCount());
} catch (Exception e) {
e.printStackTrace();
}
if (!viewData.isDispose()) {
hideControlButton(View.VISIBLE);
} else {
hideControlButton(View.GONE);
}
mLlIllegalParkingLike.setOnClickCallListener(v -> {
Logger.d(V2XConst.MODULE_NAME, "反馈有用");
roadReportTrue();
});
mLlIllegalParkingUnLike.setOnClickCallListener(v -> {
Logger.d(V2XConst.MODULE_NAME, "反馈无用");
roadReportErr();
});
} catch (Exception e) {
e.printStackTrace();
}
}
void hideControlButton(int gone) {
mTagEventEvaluate.setVisibility(gone);
mLlIllegalParkingLike.setVisibility(gone);
mLlIllegalParkingUnLike.setVisibility(gone);
}
@Override
public void delayedCloseWindow() {
try {
hideControlButton(View.GONE);
// 进行数据库存储
V2XHistoryScenarioData v2XHistoryScenarioData = new V2XHistoryScenarioData();
v2XHistoryScenarioData.setScenarioType(mOldScenarioData.getScenarioType());
v2XHistoryScenarioData.setTriggerTime(mOldScenarioData.getTriggerTime());
v2XHistoryScenarioData.setEventJsonData(mOldScenarioData.getEventJsonData());
v2XHistoryScenarioData.setEventJsonDataHashCode(mOldScenarioData.getEventJsonDataHashCode());
v2XHistoryScenarioData.setDispose(true);
V2XSQLiteUtils.updateScenarioHistoryData(mOldScenarioData, v2XHistoryScenarioData);
mOldScenarioData.setDispose(true);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反馈路况正确
*/
private void roadReportTrue() {
delayedCloseWindow();
if (mExploreWay != null) {
RoadConditionUtils.sendShareReceiverInfo(
mExploreWay.getInfoId(),
mExploreWay.getPoiType(),
2);
}
}
/**
* 反馈路况错误
*/
private void roadReportErr() {
delayedCloseWindow();
if (mExploreWay != null) {
RoadConditionUtils.sendShareReceiverInfo(
mExploreWay.getInfoId(),
mExploreWay.getPoiType(),
3);
}
}
}

View File

@@ -1,181 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi;
import com.mogo.eagle.core.function.v2x.events.fragment.V2XEventPanelFragment;
import com.mogo.eagle.core.function.v2x.events.utils.ChartingUtil;
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils;
import com.mogo.eagle.core.function.v2x.events.utils.V2XUtils;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.util.SpanUtils;
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.common.entity.V2XHistoryScenarioData;
import com.mogo.module.common.entity.V2XPushMessageEntity;
import com.mogo.service.imageloader.IMogoImageloader;
import com.mogo.service.imageloader.MogoImageView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* 出行动态中的他人故障求助
*
* @author donghongyu
*/
public class V2XScenarioHistoryOtherSeekHelpVH extends V2XHistoryBaseViewHolder<V2XHistoryScenarioData> {
private TextView mTagEventType;
private TextView mTagEventEvaluate;
private MogoImageView mIvFaultHelpHead;
private TextView mTvFaultHelpName;
private TextView mTvFaultHelpEventTime;
private TextView mTvFaultHelpDistance;
private ImageView mIvFaultHelpEventCall;
private MarkerExploreWay mNoveltyInfo;
// 上传事件的用户信息
private MarkerUserInfo mUserInfo = new MarkerUserInfo();
private V2XHistoryScenarioData mOldScenarioData;
public V2XScenarioHistoryOtherSeekHelpVH(ViewGroup viewGroup) {
super(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_v2x_scennario_history_other_help, viewGroup, false));
mTagEventType = itemView.findViewById(R.id.tagEventType);
mTagEventEvaluate = itemView.findViewById(R.id.tagEventEvaluate);
mIvFaultHelpHead = itemView.findViewById(R.id.ivFaultHelpHead);
mTvFaultHelpName = itemView.findViewById(R.id.tvFaultHelpName);
mTvFaultHelpEventTime = itemView.findViewById(R.id.tvFaultHelpEventTime);
mTvFaultHelpDistance = itemView.findViewById(R.id.tvFaultHelpDistance);
mIvFaultHelpEventCall = itemView.findViewById(R.id.ivFaultHelpEventCall);
}
@Override
public void initView(V2XHistoryScenarioData viewData) {
try {
mOldScenarioData = viewData;
V2XPushMessageEntity xPushMessageEntity = GsonUtil.objectFromJson(viewData.getEventJsonData(), V2XPushMessageEntity.class);
mUserInfo.setSn(xPushMessageEntity.getSn());
mUserInfo.setUserHead(xPushMessageEntity.getHeadImgUrl());
mUserInfo.setUserName(xPushMessageEntity.getDisplayName());
mUserInfo.setGender(xPushMessageEntity.getSex());
mUserInfo.setAge(xPushMessageEntity.getAge());
mTvFaultHelpName.setText(xPushMessageEntity.getDisplayName());
if (!TextUtils.isEmpty(xPushMessageEntity.getHeadImgUrl())) {
IMogoImageloader imageLoader = BridgeApi.INSTANCE.imageLoader();
if (imageLoader != null) {
imageLoader.displayImage(xPushMessageEntity.getHeadImgUrl(), mIvFaultHelpHead);
}
}
if (xPushMessageEntity.getDistance() > 1000) {
SpanUtils.with(mTvFaultHelpDistance)
.append("" + (int) xPushMessageEntity.getDistance() / 1000)
.setFontSize((int) itemView.getResources().getDimension(R.dimen.module_v2x_event_distance_title))
.append("公里")
.setFontSize((int) itemView.getResources().getDimension(R.dimen.dp_32))
.create();
} else {
SpanUtils.with(mTvFaultHelpDistance)
.append("" + (int) xPushMessageEntity.getDistance())
.setFontSize((int) itemView.getResources().getDimension(R.dimen.module_v2x_event_distance_title))
.append("")
.setFontSize((int) itemView.getResources().getDimension(R.dimen.dp_32))
.create();
}
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.CHINA);
String eventTime = String.format("%s发布求助信息",
sdf.format(new Date(xPushMessageEntity.getCreateTime())));
mTvFaultHelpEventTime.setText(eventTime);
try {
MarkerLocation markerLocation = new MarkerLocation();
markerLocation.setLon(xPushMessageEntity.getLon());
markerLocation.setLat(xPushMessageEntity.getLat());
mNoveltyInfo = new MarkerExploreWay();
mNoveltyInfo.setLocation(markerLocation);
mNoveltyInfo.setUserInfo(mUserInfo);
} catch (Exception e) {
e.printStackTrace();
}
// M1低配车机限制
// 不展示打电话按钮
// 不能查看用户详情
if (DebugConfig.isMapBased()) {
// 只有自研车机才会 有车聊聊通话
if (DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_SELF_INNOVATE) {
// 判断是否可以打电话
ChartingUtil.isCanCall(b -> {
if (b) {
// 判断是否可以打电话
ChartingUtil.isOnLine(xPushMessageEntity.getSn(), b1 -> {
if (b1) {
mIvFaultHelpEventCall.setVisibility(VISIBLE);
} else {
mIvFaultHelpEventCall.setVisibility(GONE);
}
});
} else {
mIvFaultHelpEventCall.setVisibility(GONE);
}
});
mIvFaultHelpEventCall.setOnClickListener(v -> {
if (!V2XUtils.isFastClick()) {
BridgeApi.INSTANCE.refreshModel().respondingToHelp(mUserInfo.getSn());
try {
triggerCallChart(mNoveltyInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void delayedCloseWindow() {
try {
hideControlButton(View.GONE);
// 进行数据库存储
V2XHistoryScenarioData v2XHistoryScenarioData = new V2XHistoryScenarioData();
v2XHistoryScenarioData.setScenarioType(mOldScenarioData.getScenarioType());
v2XHistoryScenarioData.setTriggerTime(mOldScenarioData.getTriggerTime());
v2XHistoryScenarioData.setEventJsonData(mOldScenarioData.getEventJsonData());
v2XHistoryScenarioData.setEventJsonDataHashCode(mOldScenarioData.getEventJsonDataHashCode());
v2XHistoryScenarioData.setDispose(true);
V2XSQLiteUtils.updateScenarioHistoryData(mOldScenarioData, v2XHistoryScenarioData);
mOldScenarioData.setDispose(true);
V2XEventPanelFragment.Companion.getInstance().hidePanel();
} catch (Exception e) {
e.printStackTrace();
}
}
void hideControlButton(int gone) {
mTagEventEvaluate.setVisibility(gone);
}
}

View File

@@ -1,139 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.utils.RoadConditionUtils;
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils;
import com.mogo.eagle.core.function.v2x.events.view.HeartLikeView;
import com.mogo.eagle.core.function.v2x.events.view.HeartUnLikeView;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.util.TimeUtils;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.V2XHistoryScenarioData;
import com.mogo.module.common.enums.EventTypeEnum;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
/**
* 出行面板道路事件面板
*
* @author donghongyu
*/
public class V2XScenarioHistoryRoadEventVH extends V2XHistoryBaseViewHolder<V2XHistoryScenarioData> {
private TextView mTvAddress;
private TextView mTvIllegalNum;
private ImageView mIvIconP;
private TextView mTagEventType;
private TextView mTagEventEvaluate;
private HeartLikeView mLlIllegalParkingLike;
private HeartUnLikeView mLlIllegalParkingUnLike;
private MarkerExploreWay mExploreWay;
private V2XHistoryScenarioData mOldScenarioData;
public V2XScenarioHistoryRoadEventVH(ViewGroup viewGroup) {
super(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_v2x_scennario_history, viewGroup, false));
mTvAddress = itemView.findViewById(R.id.tvAddress);
mTvIllegalNum = itemView.findViewById(R.id.tvIllegalNum);
mIvIconP = itemView.findViewById(R.id.ivIconP);
mTagEventType = itemView.findViewById(R.id.tagEventType);
mTagEventEvaluate = itemView.findViewById(R.id.tagEventEvaluate);
mLlIllegalParkingLike = itemView.findViewById(R.id.llIllegalParkingLike);
mLlIllegalParkingUnLike = itemView.findViewById(R.id.llIllegalParkingUnLike);
}
@Override
public void initView(V2XHistoryScenarioData viewData) {
try {
mOldScenarioData = viewData;
mExploreWay = GsonUtil.objectFromJson(viewData.getEventJsonData(), MarkerExploreWay.class);
mIvIconP.setVisibility(View.GONE);
mTvAddress.setText(mExploreWay.getAddr());
mTagEventType.setText(EventTypeEnum.getPoiTypeStr(mExploreWay.getPoiType()));
try {
mTvIllegalNum.setText(mExploreWay.getUserInfo().getUserName() + "的分享 " +
TimeUtils.millis2String(mOldScenarioData.getTriggerTime(), "MM月dd日 HH:mm"));
} catch (Exception e) {
e.printStackTrace();
}
if (!viewData.isDispose()) {
hideControlButton(View.VISIBLE);
} else {
hideControlButton(View.GONE);
}
mLlIllegalParkingLike.setOnClickCallListener(v -> {
Logger.d(V2XConst.MODULE_NAME, "反馈有用");
roadReportTrue();
});
mLlIllegalParkingUnLike.setOnClickCallListener(v -> {
Logger.d(V2XConst.MODULE_NAME, "反馈无用");
roadReportErr();
});
} catch (Exception e) {
e.printStackTrace();
}
}
void hideControlButton(int gone) {
mTagEventEvaluate.setVisibility(gone);
mLlIllegalParkingLike.setVisibility(gone);
mLlIllegalParkingUnLike.setVisibility(gone);
}
@Override
public void delayedCloseWindow() {
try {
hideControlButton(View.GONE);
// 进行数据库存储
V2XHistoryScenarioData v2XHistoryScenarioData = new V2XHistoryScenarioData();
v2XHistoryScenarioData.setScenarioType(mOldScenarioData.getScenarioType());
v2XHistoryScenarioData.setTriggerTime(mOldScenarioData.getTriggerTime());
v2XHistoryScenarioData.setEventJsonData(mOldScenarioData.getEventJsonData());
v2XHistoryScenarioData.setEventJsonDataHashCode(mOldScenarioData.getEventJsonDataHashCode());
v2XHistoryScenarioData.setDispose(true);
V2XSQLiteUtils.updateScenarioHistoryData(mOldScenarioData, v2XHistoryScenarioData);
mOldScenarioData.setDispose(true);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反馈路况正确
*/
private void roadReportTrue() {
delayedCloseWindow();
if (mExploreWay != null) {
RoadConditionUtils.sendShareReceiverInfo(
mExploreWay.getInfoId(),
mExploreWay.getPoiType(),
2);
}
}
/**
* 反馈路况错误
*/
private void roadReportErr() {
delayedCloseWindow();
if (mExploreWay != null) {
RoadConditionUtils.sendShareReceiverInfo(
mExploreWay.getInfoId(),
mExploreWay.getPoiType(),
3);
}
}
}

View File

@@ -1,19 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* @author lixiaopeng
* @description
* @since 2020/11/16
*/
public class V2XSurroundingDetailVH extends RecyclerView.ViewHolder{
public V2XSurroundingDetailVH(@NonNull View itemView) {
super(itemView);
}
}

View File

@@ -1,19 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.adapter.holder;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* @author lixiaopeng
* @description
* @since 2020/7/29
*/
public class V2XSurroundingViewHolder extends RecyclerView.ViewHolder{
public V2XSurroundingViewHolder(@NonNull View itemView) {
super(itemView);
}
}

View File

@@ -23,10 +23,7 @@ public class V2XConst {
* 事件面板名称
*/
public static final String MODULE_NAME_EVENT_PANEL = "MODULE_EVENT_PANEL";
/**
* 事件面板路径
*/
public static final String PATH_EVENT_PANEL = "/event/panel";
/**
* V2X 场景广播 Action

View File

@@ -1,438 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment
import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.View
import android.widget.ImageView
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import com.mogo.commons.debug.DebugConfig
import com.mogo.commons.mvp.MvpFragment
import com.mogo.eagle.core.function.v2x.R
import com.mogo.eagle.core.function.v2x.events.adapter.V2XEventPagerAdapter
import com.mogo.eagle.core.function.v2x.events.adapter.V2XSurroundingDetailAdapter
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst.MODULE_NAME
import com.mogo.eagle.core.function.v2x.events.entity.panel.BackRefreshInfo
import com.mogo.eagle.core.function.v2x.events.entity.panel.SurroundingConstruction
import com.mogo.eagle.core.function.v2x.events.fragment.presenter.EventPanelPresenter
import com.mogo.eagle.core.function.v2x.events.listener.SurroundingDetailItemListener
import com.mogo.eagle.core.function.v2x.events.utils.TrackUtils
import com.mogo.eagle.core.function.v2x.events.view.V2XEventPanelHistoryCountView
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceCallbackListener
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceConstants
import com.mogo.module.common.entity.MarkerExploreWay
import com.mogo.module.common.MogoApisHandler
import com.mogo.module.common.enums.EventTypeEnum
import com.mogo.module.common.view.SpacesItemDecoration
import com.mogo.module.v2x.voice.V2XVoiceManager
import com.mogo.service.statusmanager.IMogoStatusChangedListener
import com.mogo.service.statusmanager.StatusDescriptor
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
/**
* 事件面板主fragment
*
* @author tongchenfei
*/
class V2XEventPanelFragment : MvpFragment<V2XEventPanelFragment, EventPanelPresenter>(), SurroundingDetailItemListener,IMogoStatusChangedListener{
private val TAG = "V2XEventPanelFragment"
private var isFirstLoad = false
private var fragments: Array<Fragment>? = null
private var mediator: TabLayoutMediator? = null
private var mV2XEventPanelHistoryCountView: V2XEventPanelHistoryCountView? = null
private var mClPanelContainer: ConstraintLayout? = null
private var mVpEventPanel: ViewPager2? = null
private var mRgTabSelect: RadioGroup? = null
private var mBtnHidePanels: ImageView? = null
private var mRbScenarioHistory: RadioButton? = null
private var mRbSurroundingEvent: RadioButton? = null
private var mRbShareEvents: RadioButton? = null
private var mBackImage: ImageView? = null
private var mTopBriefTv: TextView? = null
private var mDetailRecyclerView: RecyclerView? = null
private lateinit var mSurroundingDetailAdapter: V2XSurroundingDetailAdapter
var markerExploreWays = mutableListOf<MarkerExploreWay>()
private var mV2XScenarioHistoryFragment: V2XScenarioHistoryFragment? = null
private var mV2XShareEventsFragment: V2XShareEventsFragment? = null
private var mV2XSurroundingFragment: V2XSurroundingFragment? = null
companion object {
private var fragment: V2XEventPanelFragment? = null
fun getInstance(): V2XEventPanelFragment {
if (fragment == null) {
synchronized(this) {
if (fragment == null) {
fragment = V2XEventPanelFragment()
}
}
}
return fragment as V2XEventPanelFragment
}
}
// 打开出行动态TAB
private val mCheckHistoryEventCb = V2XVoiceCallbackListener { _: String?, _: Intent? ->
try {
mRbScenarioHistory?.isChecked = true
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
EventBus.getDefault().register(this)
}
// 打开周边事件TAB
private val mCheckSurroundingCb = V2XVoiceCallbackListener { _: String?, _: Intent? ->
try {
mRbSurroundingEvent?.isChecked = true
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
// 打开我的分享TAB
private val mCheckShearEventCb = V2XVoiceCallbackListener { _: String?, _: Intent? ->
try {
mRbShareEvents?.isChecked = true
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
// 打关闭事件面板
private val mCloeEventCb = V2XVoiceCallbackListener { _: String?, _: Intent? ->
try {
TrackUtils.trackV2xHistoryEvent(5)
hidePanel()
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
override fun getLayoutId(): Int {
return R.layout.module_v2x_event_panel_fragment_event_panel
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
Logger.d(MODULE_NAME, "事件面板初始化……")
try {
mV2XScenarioHistoryFragment = V2XScenarioHistoryFragment()
mV2XShareEventsFragment = V2XShareEventsFragment()
mV2XSurroundingFragment = V2XSurroundingFragment()
fragments = arrayOf(
mV2XScenarioHistoryFragment!!,
mV2XSurroundingFragment!!,
mV2XShareEventsFragment!!
)
mClPanelContainer = mRootView.findViewById(R.id.clPanelContainer)
mVpEventPanel = mRootView.findViewById(R.id.vpEventPanel)
mRgTabSelect = mRootView.findViewById(R.id.rgTabSelect)
mBtnHidePanels = mRootView.findViewById(R.id.btnHidePanels)
mRbScenarioHistory = mRootView.findViewById(R.id.rbScenarioHistory)
mRbSurroundingEvent = mRootView.findViewById(R.id.rbSurroundingEvent)
mRbShareEvents = mRootView.findViewById(R.id.rbShareEvents)
mBackImage = mRootView.findViewById(R.id.back_image)
mTopBriefTv = mRootView.findViewById(R.id.tv_brief_detail)
mDetailRecyclerView = mRootView.findViewById(R.id.surrounding_detail_recycleview)
initDetail()
// M1 不基于地图的版本直接展示事件面板,且不可关闭
if (!DebugConfig.isMapBased()) {
mClPanelContainer?.visibility = View.VISIBLE
mBtnHidePanels?.visibility = View.GONE
}
//禁用预加载
mVpEventPanel?.offscreenPageLimit = ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
mVpEventPanel?.adapter = V2XEventPagerAdapter(this, fragments!!)
mVpEventPanel?.isUserInputEnabled = false; //true:滑动false禁止滑动
mRgTabSelect?.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rbScenarioHistory -> {
// 更改选中是否加粗
mRbScenarioHistory?.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
mRbSurroundingEvent?.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
mRbShareEvents?.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
TrackUtils.trackV2xHistoryEvent(2)
mVpEventPanel?.setCurrentItem(0, false)
}
R.id.rbSurroundingEvent -> {
// 更改选中是否加粗
mRbScenarioHistory?.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
mRbSurroundingEvent?.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
mRbShareEvents?.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
TrackUtils.trackV2xHistoryEvent(3)
mVpEventPanel?.setCurrentItem(1, false)
}
R.id.rbShareEvents -> {
// 更改选中是否加粗
mRbScenarioHistory?.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
mRbSurroundingEvent?.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
mRbShareEvents?.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
TrackUtils.trackV2xHistoryEvent(4)
mVpEventPanel?.setCurrentItem(2, false)
}
}
}
mBtnHidePanels?.setOnClickListener {
TrackUtils.trackV2xHistoryEvent(5)
hidePanel()
}
mBackImage?.setOnClickListener {
EventBus.getDefault().post(BackRefreshInfo())
showBaseUi(true)
}
mV2XEventPanelHistoryCountView = V2XEventPanelHistoryCountView(context)
mV2XEventPanelHistoryCountView!!.setOnClickListener {
if (mClPanelContainer == null) {
mClPanelContainer = mRootView.findViewById(R.id.clPanelContainer);
}
if (mClPanelContainer != null) {
if (!isPanelShow()) {
TrackUtils.trackV2xHistoryEvent(1)
showPanel()
}
}
}
// 模拟手动点击,默认选择第二个,周边事件
// http://jira.zhidaohulian.com/browse/E84XAD-250
mRgTabSelect?.check(R.id.rbSurroundingEvent)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onDestroyView() {
EventBus.getDefault().unregister(this)
MogoApisHandler.getInstance().apis.statusManagerApi.unregisterStatusChangedListener(MODULE_NAME, StatusDescriptor.VR_MODE, this)
mediator?.detach()
// 避免内存泄漏
fragment = null
mClPanelContainer = null
super.onDestroyView()
}
override fun createPresenter(): EventPanelPresenter {
return EventPanelPresenter(this)
}
/*
* 语音查询热心指数需求
* */
fun showPanelWithSelectedItem(item: Int) {
showPanel()
selectWithItem(item)
}
override fun onItemClickListener(v: View?, position: Int, exploreWay: MarkerExploreWay?) {
markerExploreWays[position].isFabulous = true
mSurroundingDetailAdapter.notifyItemChanged(position)
}
private fun initDetail() {
mDetailRecyclerView!!.addItemDecoration(SpacesItemDecoration(resources.getDimension(R.dimen.share_item_padding).toInt()))
mSurroundingDetailAdapter = V2XSurroundingDetailAdapter(activity, markerExploreWays, this)
mDetailRecyclerView!!.adapter = mSurroundingDetailAdapter
val linearLayoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
mDetailRecyclerView!!.layoutManager = linearLayoutManager
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun updateSurroundingDetail(data: SurroundingConstruction) {
loadSurroundingDetail(data)
}
private fun loadSurroundingDetail(detailData: SurroundingConstruction?) {
showBaseUi(false)
if (detailData != null) {
markerExploreWays.clear()
markerExploreWays.addAll(detailData.construtList.toMutableList())
mSurroundingDetailAdapter.notifyDataSetChanged()
val originStr = String.format(BridgeApi.context().resources.getString(R.string.v2x_surrounding_detail_top_brief), markerExploreWays.size)
val spannableString = SpannableString(originStr + EventTypeEnum.getTypeName(detailData.poiType))
spannableString.setSpan(ForegroundColorSpan(Color.parseColor("#459DFF")),
7, originStr.length - EventTypeEnum.getTypeName(detailData.poiType)?.length!!, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
//设置字体大小true表示前面的字体大小 dip
spannableString.setSpan(AbsoluteSizeSpan(BridgeApi.context().resources.getDimension(R.dimen.module_v2x_surrounding_top_textsize).toInt(), true),
7, originStr.length - EventTypeEnum.getTypeName(detailData.poiType)?.length!!, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
spannableString.setSpan(StyleSpan(Typeface.BOLD), 7,
originStr.length - EventTypeEnum.getTypeName(detailData.poiType)?.length!!, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
mTopBriefTv?.text = (spannableString)
}
}
/**
* 是否显示基础页面
*/
private fun showBaseUi(isShow: Boolean) {
if (isShow) {
mBackImage?.visibility = View.GONE
mTopBriefTv?.visibility = View.GONE
mDetailRecyclerView?.visibility = View.GONE
mRgTabSelect?.visibility = View.VISIBLE
mVpEventPanel?.visibility = View.VISIBLE
if (DebugConfig.isMapBased()) {
mBtnHidePanels?.visibility = View.VISIBLE
}
} else {
mBackImage?.visibility = View.VISIBLE
mTopBriefTv?.visibility = View.VISIBLE
mDetailRecyclerView?.visibility = View.VISIBLE
mRgTabSelect?.visibility = View.GONE
mVpEventPanel?.visibility = View.GONE
if (DebugConfig.isMapBased()) {
mBtnHidePanels?.visibility = View.GONE
}
}
}
/*
* 语音查询事件面板内容
* */
private fun selectWithItem(item: Int) {
when (item) {
0 -> {
try {
mRbScenarioHistory?.isChecked = true
mV2XScenarioHistoryFragment?.fromVoice = true
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
1 -> {
try {
if (mRbSurroundingEvent?.isChecked == true) {
mV2XSurroundingFragment?.ttsForVoiceCheckout()
} else {
mRbSurroundingEvent?.isChecked = true
mV2XSurroundingFragment?.fromVoice = true
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
2 -> {
try {
if (mRbShareEvents?.isChecked == true) {
mV2XShareEventsFragment?.ttsForVoiceCheckout()
} else {
mRbShareEvents?.isChecked = true
mV2XShareEventsFragment?.fromVoice = true
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
}
}
fun showPanel() {
Logger.d(MODULE_NAME, "in fragment show panel")
mClPanelContainer?.visibility = View.VISIBLE
if (DebugConfig.isMapBased()) {
V2XVoiceManager.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CLOSE_WINDOW_UN_WAKEUP, mCloeEventCb)
}
// 注册语音交互
V2XVoiceManager.registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_HISTORY_EVENT_UN_WAKEUP, mCheckHistoryEventCb)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_SURROUNDING_EVENT_UN_WAKEUP, mCheckSurroundingCb)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_SHEAR_EVENT_UN_WAKEUP, mCheckShearEventCb)
try {
if (isFirstLoad) {
mV2XScenarioHistoryFragment?.presenter?.loadHistory()
mV2XShareEventsFragment?.presenter?.loadShareEventList()
}
} catch (e: Exception) {
e.printStackTrace()
}
isFirstLoad = true
}
fun hidePanel() {
if (DebugConfig.isMapBased()) {
Logger.d(MODULE_NAME, "in fragment hide panel")
mClPanelContainer?.visibility = View.GONE
// 注册语音交互
V2XVoiceManager.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_HISTORY_EVENT_UN_WAKEUP)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_SURROUNDING_EVENT_UN_WAKEUP)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_SHEAR_EVENT_UN_WAKEUP)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CLOSE_WINDOW_UN_WAKEUP)
}
}
fun isPanelShow(): Boolean {
return mClPanelContainer?.visibility == View.VISIBLE
}
// 修改未处理消息
fun changeEventCount() {
// val historyMessage = V2XSQLiteUtils.getScenarioHistoryUnDisposeData()
// if (historyMessage != null) {
// mV2XEventPanelHistoryCountView?.changeMsgCount(historyMessage.size)
// } else {
// mV2XEventPanelHistoryCountView?.changeMsgCount(0)
// }
}
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
if (isTrue) {
// 在vr模式
mV2XEventPanelHistoryCountView?.visibility = View.GONE
}else{
mV2XEventPanelHistoryCountView?.visibility = View.VISIBLE
}
}
}

View File

@@ -1,167 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment
import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import android.view.View
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.function.v2x.R.dimen
import com.mogo.eagle.core.function.v2x.R.layout
import com.mogo.eagle.core.function.v2x.events.adapter.V2XScenarioHistoryAdapter
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.v2xStatus
import com.mogo.eagle.core.function.v2x.events.fragment.presenter.ScenarioHistoryPresenter
import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XStatusChangedListener
import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusDescriptor
import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusDescriptor.EventPanelWindow_UI
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils
import com.mogo.eagle.core.function.v2x.events.utils.V2XUtils
import com.mogo.eagle.core.function.v2x.events.view.V2XListEmptyView.OnControlListener
import com.mogo.eagle.core.network.utils.GsonUtil
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.Utils
import com.mogo.module.common.entity.V2XHistoryScenarioData
import com.mogo.module.common.view.SpacesItemDecoration
import kotlinx.android.synthetic.main.module_v2x_event_panel_fragment_scenario_history.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
/**
* 出行动态V2X 提示过的场景历史
*
* @author donghongyu
*/
class V2XScenarioHistoryFragment : MvpFragment<V2XScenarioHistoryFragment?, ScenarioHistoryPresenter?>() {
private val TAG = "V2XScenarioHistoryFragment"
var fromVoice = false
private var mV2XScenarioHistoryAdapter: V2XScenarioHistoryAdapter? = null
private val mV2XHistoryScenarioData = ArrayList<V2XHistoryScenarioData>()
private var mListener: IMoGoV2XStatusChangedListener? = null
override fun getLayoutId(): Int {
return layout.module_v2x_event_panel_fragment_scenario_history
}
override fun getTagName(): String {
return TAG
}
@SuppressLint("LongLogTag") override fun initViews() {
Log.d(TAG, "initViews --------> ")
recyclerView.addItemDecoration(SpacesItemDecoration(resources.getDimension(dimen.share_item_padding).toInt()))
mV2XScenarioHistoryAdapter = V2XScenarioHistoryAdapter(mV2XHistoryScenarioData)
recyclerView.adapter = mV2XScenarioHistoryAdapter
recyclerView.addItemDecoration(SpacesItemDecoration(14)) // 配置列表朝向
val layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = layoutManager
initListener()
viewEmpty.setTripMessage("暂无交通事件")
viewEmpty.setRefreshVisibility(false)
}
/**
* 初始化页面用到得监听
*/
private fun initListener() {
viewEmpty.setOnControlListener(object : OnControlListener {
override fun onShearClick() {
// TODO
// val share = share()
// if (share != null) {
// share.showShareDialog()
// getInstance().hidePanel()
// }
}
override fun onRefreshClick() {}
})
mListener = object : IMoGoV2XStatusChangedListener {
override fun onStatusChanged(descriptor: V2XStatusDescriptor, isTrue: Boolean) {
Logger.d(TAG, "$descriptor initViews --------> $isTrue")
if (descriptor == EventPanelWindow_UI) {
mPresenter!!.loadHistory()
}
}
override fun init(context: Context) {
Logger.d(TAG, "init --------> ")
}
}
val v2xStatus = v2xStatus()
v2xStatus?.registerStatusChangedListener(TAG, EventPanelWindow_UI, mListener)
}
/**
* 列表加载数据
*
* @param v2XHistoryScenarioData 最新数据
*/
fun loadHistory(v2XHistoryScenarioData: List<V2XHistoryScenarioData>) {
Logger.d(TAG, "查询到历史消息:" + GsonUtil.jsonFromObject(v2XHistoryScenarioData))
ThreadUtils.runOnUiThread {
mV2XHistoryScenarioData.clear()
if (v2XHistoryScenarioData.size > 0) {
viewEmpty.visibility = View.GONE
clHistoryList.visibility = View.VISIBLE
mV2XHistoryScenarioData.addAll(v2XHistoryScenarioData)
} else {
viewEmpty.visibility = View.VISIBLE
clHistoryList.visibility = View.GONE
}
mV2XScenarioHistoryAdapter?.notifyDataSetChanged()
ttsForHistoryFirstToday()
if (fromVoice) {
ttsForVoiceCheckout()
fromVoice = false
}
}
}
/*
* 手动点击出行动态 TTS播报
* */
private fun ttsForHistoryFirstToday() {
val hasBroadTts = V2XUtils.isFirstTodayWithKey("TTS_FOR_HISTORY_SELECTED")
if (!hasBroadTts) {
if (mV2XHistoryScenarioData.size > 0) {
AIAssist.getInstance(Utils.getApp()).speakTTSVoice("小智为您记录了今天的出行事件", null)
} else {
AIAssist.getInstance(Utils.getApp()).speakTTSVoice("小智在这里为您记录今天的出行事件", null)
}
}
}
/*
* 语音查询出行动态 TTS播报
* */
fun ttsForVoiceCheckout() {
if (mV2XHistoryScenarioData.size > 0) {
AIAssist.getInstance(Utils.getApp()).speakTTSVoice("为您找到以下动态请查看", null)
} else {
AIAssist.getInstance(Utils.getApp()).speakTTSVoice("今天暂无出行动态,试试对我说分享拥堵给其他车友吧", null)
}
}
override fun onResume() {
super.onResume()
// 清除V2X事件数据库中过期的数据数据有效期为24小时
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
V2XSQLiteUtils.clearYesterdayScenarioHistoryData()
mPresenter!!.loadHistory()
}
}
override fun createPresenter(): ScenarioHistoryPresenter {
return ScenarioHistoryPresenter(this)
}
override fun onDestroyView() {
super.onDestroyView()
val v2xStatus = v2xStatus()
v2xStatus?.unregisterStatusChangedListener(TAG, EventPanelWindow_UI, mListener)
}
}

View File

@@ -1,267 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.adapter.V2XShareEventAdapter;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventDescription;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventItem;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventItemEnum;
import com.mogo.eagle.core.function.v2x.events.entity.panel.V2XShareEventLoadMoreItem;
import com.mogo.eagle.core.function.v2x.events.fragment.presenter.ShareEventsPresenter;
import com.mogo.eagle.core.function.v2x.events.listener.AdapterCallback;
import com.mogo.eagle.core.function.v2x.events.network.V2XRefreshCallback;
import com.mogo.eagle.core.function.v2x.events.network.V2XShareNetworkModel;
import com.mogo.eagle.core.function.v2x.events.utils.V2XUtils;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.mogo.eagle.core.utilcode.util.Utils;
import com.mogo.module.common.view.LinearLayoutCommonManager;
import com.mogo.module.common.view.SpacesItemDecoration;
import com.mogo.module.common.view.NetworkLoadingView;
import java.util.ArrayList;
public class V2XShareEventsFragment extends MvpFragment<V2XShareEventsFragment, ShareEventsPresenter> implements AdapterCallback {
private static final String TAG = "V2XShareEventsFragment";
private RecyclerView recyclerView;
private V2XShareEventAdapter adapter;
private ArrayList dataArrayList = new ArrayList();
public Boolean fromVoice = false;
private int pageNum = 1;
private V2XShareNetworkModel v2XShareNetworkModel;
private V2XShareEventDescription resultData;
//动画
private NetworkLoadingView loadingView;
@Override
protected int getLayoutId() {
return R.layout.module_v2x_event_share_recylerview;
}
@Override
public String getTagName() {
return TAG;
}
@Override
protected void initViews() {
v2XShareNetworkModel = new V2XShareNetworkModel(getContext());
initRecyclerView();
initData();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return mRootView;
}
private void initRecyclerView() {
recyclerView = mRootView.findViewById(R.id.road_case_share_list);
recyclerView.addItemDecoration(new SpacesItemDecoration((int) getResources().getDimension(R.dimen.share_item_padding)));
adapter = new V2XShareEventAdapter(getActivity(), dataArrayList, this);
recyclerView.setAdapter(adapter);
LinearLayoutCommonManager linearLayoutManager =
new LinearLayoutCommonManager(getActivity(), LinearLayoutCommonManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
loadingView = mRootView.findViewById(R.id.network_loading_imageview);
}
private void initData() {
getShareEventResponse();
}
/*
* 获取热心指数,分享列表等分享内容
* */
@Override
public void getShareEventResponse() {
pageNum = 1;
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
animationAction(View.VISIBLE);
}
});
v2XShareNetworkModel.getShareEventResponse(pageNum, 10, new V2XRefreshCallback() {
@Override
public void onSuccess(Object result) {
if (result instanceof V2XShareEventDescription) {
resultData = (V2XShareEventDescription) result;
if (resultData != null && resultData.getResult() != null
&& resultData.getResult().getEnthusiasmIndex() != null) {
if (dataArrayList.size() > 0) {
dataArrayList.clear();
}
dataArrayList.add(resultData.getResult().getEnthusiasmIndex());
if (fromVoice == true) {
try {
ttsForVoiceCheckout();
} catch (Exception e) {
}
}
}
} else if (result instanceof V2XShareEventItem) {
Log.d("V2XShareEventsFragment","onSuccess--loadSuccessWithShareEventList");
loadSuccessWithShareEventList(result);
}
}
@Override
public void onFail(String msg) {
if (dataArrayList.size() > 0) {
dataArrayList.clear();
Log.d("V2XShareEventsFragment","onFail--clear");
adapter.notifyDataSetChanged();
}
loadingView.stopWithError(msg, View.VISIBLE);
loadingView.refresButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getShareEventResponse();
}
});
}
});
}
/*
* 语音打开我的分享,TTS播报
* */
public void ttsForVoiceCheckout() {
int shareNum = resultData.getResult().getEnthusiasmIndex().getShareNum();
int approveNum = resultData.getResult().getEnthusiasmIndex().getLikeNum();
double enthusiasm = resultData.getResult().getEnthusiasmIndex().getEnthusiasmIndex();
Log.d(TAG, String.valueOf(enthusiasm) + "TTS播报热心指数个数");
String ttsString = "";
if (enthusiasm <= 2) {
ttsString = "您目前已完成" + shareNum + "次分享,获得" + approveNum + "次车友认同,热心指数" + enthusiasm
+ "颗星,老铁请再接再厉,对我说,上报路况。分享更多路况帮助其他车友。";
} else if (2 < enthusiasm && enthusiasm < 5) {
ttsString = "您目前已完成" + shareNum + "次分享,获得" + approveNum + "次车友认同,热心指数" + enthusiasm
+ "颗星,老铁您的热心温暖了无数车友,加油距离五颗星不远了。";
} else {
ttsString = "您目前已完成" + shareNum + "次分享,获得" + approveNum + "次车友认同,热心指数" + enthusiasm
+ "颗星,实至名归,老铁你就是大家一直赞扬的热心车友,请继续保持。";
}
AIAssist.getInstance(Utils.getApp()).speakTTSVoice(ttsString, null);
fromVoice = false;
}
/*
* 我的分享列表数据处理
* */
private void loadSuccessWithShareEventList(Object result) {
animationAction(View.GONE);
V2XShareEventItem resultData = (V2XShareEventItem) result;
V2XShareEventLoadMoreItem item = new V2XShareEventLoadMoreItem();
if (resultData != null && resultData.getResult() != null) {
if (resultData.getResult().getPage() != null) {
int total = resultData.getResult().getPage().getTotal();
if (total == 0) {
//空白
item.setViewType(V2XShareEventItemEnum.ITEM_TYPE_SHARE_EMPTY);
dataArrayList.add(item);
int len = dataArrayList.size();
} else {
if (dataArrayList.size() > 0) {
Object data = dataArrayList.get(dataArrayList.size() - 1);
if (data instanceof V2XShareEventLoadMoreItem) {
dataArrayList.remove(dataArrayList.size() - 1);
}
}
if (resultData.getResult().getPage().getContent().size() > 0) {
//当前页有数据
dataArrayList.addAll(resultData.getResult().getPage().getContent());
item.setViewType(V2XShareEventItemEnum.ITEM_TYPE_LOAD_MORE_STATUS);
} else {
//当前页没有数据
item.setViewType(V2XShareEventItemEnum.ITEM_TYPE_NO_MORE);
}
if (total > 10) {
dataArrayList.add(item);
}
}
}
Log.d(TAG, "分享列表:" + dataArrayList.get(0));
} else {
//空白
item.setViewType(V2XShareEventItemEnum.ITEM_TYPE_SHARE_EMPTY);
dataArrayList.add(item);
}
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
}
private void animationAction(int visible) {
if (visible == View.VISIBLE) {
if (loadingView != null) {
loadingView.start();
}
} else {
if (loadingView != null) {
loadingView.stop();
}
}
}
@NonNull
@Override
protected ShareEventsPresenter createPresenter() {
Log.d(TAG, "createPresenter");
ttsForSharedFirstToday();
return new ShareEventsPresenter(this);
}
private void ttsForSharedFirstToday() {
boolean hasBroadTts = V2XUtils.isFirstTodayWithKey("TTS_FOR_SHARED_SELECTED");
Log.d(TAG,"shouldBroadTts"+hasBroadTts);
if (!hasBroadTts) {
AIAssist.getInstance(Utils.getApp()).speakTTSVoice("您可以在这里查看历史的分享记录", null);
}
}
@Override
public void loadMoreShareEventList() {
Log.d(TAG, "page--" + pageNum);
animationAction(View.VISIBLE);
pageNum += 1;
v2XShareNetworkModel.getShareEventList(pageNum, 10, new V2XRefreshCallback() {
@Override
public void onSuccess(Object result) {
loadSuccessWithShareEventList(result);
}
@Override
public void onFail(String msg) {
loadingView.stopWithError("网络异常,点击刷新重试", View.INVISIBLE);
}
});
}
}

View File

@@ -1,491 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.adapter.V2XSurroundingAdapter;
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi;
import com.mogo.eagle.core.function.v2x.events.entity.panel.BackRefreshInfo;
import com.mogo.eagle.core.function.v2x.events.entity.panel.SurroundingConstruction;
import com.mogo.eagle.core.function.v2x.events.fragment.presenter.SurroundingEventPresenter;
import com.mogo.eagle.core.function.v2x.events.listener.SurroundingItemClickListener;
import com.mogo.eagle.core.function.v2x.events.utils.V2XUtils;
import com.mogo.eagle.core.function.v2x.events.widgets.SurroundingEventView;
import com.mogo.eagle.core.function.v2x.events.widgets.SurroundingMarginDecoration;
import com.mogo.eagle.core.utilcode.util.Utils;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.marker.anim.OnMarkerAnimationListener;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.common.view.NetworkLoadingView;
import com.mogo.service.IMogoServiceApis;
import com.mogo.eagle.core.data.constants.MogoServicePaths;
import com.mogo.eagle.core.utilcode.mogo.thread.WorkThreadHandler;
import com.mogo.service.module.IMogoMarkerService;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static android.view.View.OVER_SCROLL_NEVER;
/**
* 周边事件
*/
public class V2XSurroundingFragment extends MvpFragment<SurroundingEventView, SurroundingEventPresenter> implements SurroundingEventView,
View.OnClickListener, SurroundingItemClickListener {
private static final String TAG = "V2XSurroundingFragment";
private RelativeLayout mSurroundingLayout;
private RecyclerView mRecyclerView;
private TextView mTotalTv;
private RelativeLayout mTopLayout;
private RelativeLayout mEmptyLayout;
private TextView mTopFreshTv;
private TextView mShareTv;
private TextView mFreshTv;
private V2XSurroundingAdapter mAdapter;
private SurroundingEventPresenter surroundingEventPresenter;
private List<SurroundingConstruction> poiInfosList = new ArrayList<>();
private IMogoServiceApis mApis;
private NetworkLoadingView mloadingImage;
public Boolean fromVoice = false;
@Override
protected int getLayoutId() {
return R.layout.module_event_panel_fragment_surrounding;
}
@Override
public String getTagName() {
return TAG;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return mRootView;
}
@Override
protected void initViews() {
mSurroundingLayout = findViewById(R.id.layout_surrounding_event);
mRecyclerView = findViewById(R.id.surrounding_recycleview);
mTotalTv = findViewById(R.id.tv_brief);
mTopLayout = findViewById(R.id.layout_top);
mEmptyLayout = findViewById(R.id.layout_empty_data_show);
mTopFreshTv = findViewById(R.id.tv_top_refresh);
mShareTv = findViewById(R.id.tv_main_share);
mFreshTv = findViewById(R.id.tv_main_refresh);
mloadingImage = mRootView.findViewById(R.id.loading_iv);
mTopFreshTv.setOnClickListener(this);
mShareTv.setOnClickListener(this);
mFreshTv.setOnClickListener(this);
// mRecyclerView.setHasFixedSize(true);
mRecyclerView.setOverScrollMode(OVER_SCROLL_NEVER);
GridLayoutManager layoutManage = new GridLayoutManager(getContext(), 2);
int spacingInPixels = getContext().getResources().getDimensionPixelSize(R.dimen.module_v2x_surrounding_item_bottom_right_textsize);
int spacingInPixelsLeft = getContext().getResources().getDimensionPixelSize(R.dimen.module_v2x_surrounding_item_maigin_left);
mRecyclerView.addItemDecoration(new SurroundingMarginDecoration(spacingInPixels, spacingInPixelsLeft));
mRecyclerView.setLayoutManager(layoutManage);
mAdapter = new V2XSurroundingAdapter(getActivity(), poiInfosList, this);
mRecyclerView.setAdapter(mAdapter);
initData();
}
@NonNull
@Override
protected SurroundingEventPresenter createPresenter() {
surroundingEventPresenter = new SurroundingEventPresenter(getContext(), this);
return surroundingEventPresenter;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
EventBus.getDefault().register(this);
mApis = (IMogoServiceApis) ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(getContext());
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.tv_main_share) {
//弹出框面板消失,出现分享弹框
V2XEventPanelFragment.Companion.getInstance().hidePanel();
// TODO
// if (mApis != null && mApis.getShareManager() != null) {
// mApis.getShareManager().showShareDialog();
// }
} else if (id == R.id.tv_main_refresh || id == R.id.tv_top_refresh) { //刷新
initData();
}
}
/**
* 获取和刷新数据
*/
private void initData() {
mTopLayout.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.GONE);
mEmptyLayout.setVisibility(View.GONE);
mloadingImage.start();
surroundingEventPresenter.getSurroundingEventData();
}
/**
* 展示列表数据
*/
@Override
public void showSurroudingData(List<MarkerExploreWay> exploreWayList) {
mloadingImage.stop();
if (exploreWayList != null && exploreWayList.size() > 0) {
//展示数据
mTopLayout.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
mEmptyLayout.setVisibility(View.GONE);
poiInfosList.clear();
//对数据进行分类
poiInfosList.addAll(handleMapToList(getPoiTypeMap(exploreWayList)));
mAdapter.notifyDataSetChanged();
//总条数
String originStr = String.format(getContext().getResources().getString(R.string.v2x_surrounding_top_brief), exploreWayList.size());
SpannableString spannableString = new SpannableString(originStr);
spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#459DFF")),
7, originStr.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置字体大小true表示前面的字体大小 dip
spannableString.setSpan(new AbsoluteSizeSpan((int) getContext().getResources().getDimension(R.dimen.module_v2x_surrounding_top), true),
7, originStr.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new StyleSpan(Typeface.BOLD), 7,
originStr.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTotalTv.setText(spannableString);
ttsForSurroundingFirstToday(exploreWayList.size());
} else {
mTopLayout.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.GONE);
mEmptyLayout.setVisibility(View.VISIBLE);
}
if (fromVoice == true) {
ttsForVoiceCheckout();
fromVoice = false;
}
}
/**
* 手动点击周边事件 TTS播报
*/
private void ttsForSurroundingFirstToday(int eventCount) {
boolean hasBroadTts = V2XUtils.isFirstTodayWithKey("TTS_FOR_SURROUNDING_SELECTED");
if (!hasBroadTts) {
if (eventCount > 0) {
AIAssist.getInstance(Utils.getApp()).
speakTTSVoice("发现周边" + eventCount + "条交通信息", null);
} else {
Logger.e(TAG,"周边没有发现交通信息");
}
}
}
/*
* 语音查询周边事件 TTS播报
* */
public void ttsForVoiceCheckout() {
if (poiInfosList.size() > 0) {
AIAssist.getInstance(Utils.getApp()).
speakTTSVoice("为您找到周边以下事件请查看", null);
} else {
AIAssist.getInstance(Utils.getApp()).
speakTTSVoice("周边5公里内无事件试试对我说分享路况给其他车友吧", null);
}
}
private Map<String, SurroundingConstruction> getPoiTypeMap(List<MarkerExploreWay> list) {
Map<String, SurroundingConstruction> mPoiTypeMarkers = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
MarkerExploreWay exploreWay = list.get(i);
if (!mPoiTypeMarkers.containsKey(exploreWay.getPoiType())) {
mPoiTypeMarkers.put(exploreWay.getPoiType(), new SurroundingConstruction(exploreWay.getPoiType()));
}
SurroundingConstruction construction = mPoiTypeMarkers.get(exploreWay.getPoiType());
construction.addMarkerExploreWay(exploreWay);
}
Log.d(TAG, "getPoiTypeMap mPoiTypeMarkers.size() = " + mPoiTypeMarkers.size());
return mPoiTypeMarkers;
}
private List<SurroundingConstruction> handleMapToList(Map<String, SurroundingConstruction> map) {
Collection<? extends SurroundingConstruction> valueCollection = map.values();
List<SurroundingConstruction> list = new ArrayList<>(valueCollection);
List<SurroundingConstruction> resultSurroundingList = new ArrayList<>();
List<SurroundingConstruction> outSurroundingList = new ArrayList<>();
if (list != null && list.size() > 0) {
List<String> prioritySorts = prioritySort();
for (String poiType : prioritySorts) {
for (SurroundingConstruction construction : list) {
if (!prioritySorts.contains(construction.getPoiType())) {
outSurroundingList.add(construction);
continue;
} else if (poiType.equals(construction.getPoiType())) {
resultSurroundingList.add(construction);
}
}
}
}
if (outSurroundingList != null && outSurroundingList.size() > 0) {
resultSurroundingList.addAll(outSurroundingList);
}
Log.d(TAG, "handleMapToList resultSurroundingList.size() = " + resultSurroundingList.size());
return resultSurroundingList;
}
public static List<String> prioritySort() {
List<String> poiTypes = new LinkedList<>();
// 封路
poiTypes.add("10003");
// 结冰
poiTypes.add("10011");
// 浓雾
poiTypes.add("10010");
// 交通检查
poiTypes.add("10002");
// 交通事故
poiTypes.add("10013");
// 拥堵
poiTypes.add("10007");
// 道路施工
poiTypes.add("10006");
// 积水
poiTypes.add("10008");
//实时路况
poiTypes.add("10015");
return poiTypes;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onBackRefresh(final BackRefreshInfo event) {
if (event == null) {
return;
}
initData();
}
/**
* 处理marker的显示
*
* @param v
* @param position
* @param construction
*/
@Override
public void onItemClickListener(View v, int position, SurroundingConstruction construction) {
if (construction != null) {
if (!DebugConfig.isMapBased()) {
EventBus.getDefault().post(construction);
} else {
//卡片消失
V2XEventPanelFragment.Companion.getInstance().hidePanel();
//清除道路事件
IMogoMarkerManager marker = BridgeApi.INSTANCE.marker();
if (marker != null) {
marker.removeMarkers(ServiceConst.CARD_TYPE_ROAD_CONDITION);
}
try {
//处理 marker的显示
List<MarkerExploreWay> exploreWayList = construction.getConstrutList();
Logger.d(TAG, "onItemClickListener exploreWayList.size() = " + exploreWayList.size());
if (exploreWayList != null && exploreWayList.size() > 0) {
for (int i = 0; i < exploreWayList.size(); i++) {
MarkerExploreWay exploreWay = exploreWayList.get(i);
MarkerShowEntity markerShowEntity = new MarkerShowEntity();
markerShowEntity.setBindObj(exploreWay);
markerShowEntity.setChecked(false);
markerShowEntity.setTextContent(exploreWay.getAddr());
markerShowEntity.setMarkerLocation(exploreWay.getLocation());
markerShowEntity.setMarkerType(ServiceConst.CARD_TYPE_ROAD_CONDITION);
WorkThreadHandler.getInstance().postDelayed(() -> {
IMogoMarkerService markerService = BridgeApi.INSTANCE.markerService();
if (markerService == null) {
return;
}
IMogoMarker mogoMarker = markerService.drawMarker(markerShowEntity);
// 点击监听,天际弹窗展示详情
if (mogoMarker != null) {
mogoMarker.startScaleAnimation(0, 1.2f, 0, 1.2f, 300, new AccelerateInterpolator(), new OnMarkerAnimationListener() {
@Override
public void onAnimStart() {
Logger.d(TAG, " onItemClickListener onAnimStart -----> ");
}
@Override
public void onAnimEnd() {
if (mogoMarker.isDestroyed()) {
return;
}
Logger.d(TAG, " onItemClickListener onAnimEnd ------> ");
mogoMarker.startScaleAnimation(1.2f, 1, 1.2f, 1, 100, new LinearInterpolator(), null);
}
});
mogoMarker.setOwner(markerShowEntity.getMarkerType());
mogoMarker.setObject(markerShowEntity);
}
}, i * 100L);
}
//自适应显示
showBonndsRoadtion(exploreWayList);
} else {
Logger.e(TAG, "onItemClickListener exploreWayList == null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 子类信息tts播报
*/
AIAssist.getInstance(Utils.getApp()).
speakTTSVoice(construction.getTypeNameTTS(construction.getPoiType()), null);
}
}
/**
* 自适应显示
*
* @param exploreWayList
*/
private void showBonndsRoadtion(List<MarkerExploreWay> exploreWayList) {
Logger.d(TAG, "showBonndsRoadtion exploreWayList.size() = " + exploreWayList.size());
Rect rect = new Rect(
(int) getContext().getResources().getDimension(R.dimen.module_v2x_map_left),
(int) getContext().getResources().getDimension(R.dimen.module_v2x_map_top),
(int) getContext().getResources().getDimension(R.dimen.module_v2x_map_right),
(int) getContext().getResources().getDimension(R.dimen.module_v2x_map_bottom));
moveNotFresh();
//第一个参数:调用者,第二个参数:当前自车的位置,第三个参数:需要显示在范围内的点(不包含自车的位置)
//第四个参数显示范围的UI边界,第五个参数:是否锁定自车位置(看业务需要)
IMogoMapUIController mapUiController = BridgeApi.INSTANCE.mapUiController();
if (mapUiController != null) {
mapUiController.showBounds(ServiceConst.CARD_TYPE_ROAD_CONDITION, null, getMogoList(exploreWayList), rect, false);
}
}
private void moveNotFresh() {
IMogoStatusManager statusManager = BridgeApi.INSTANCE.statusManager();
if (statusManager != null) {
statusManager.setUserInteractionStatus(TAG, true, false);
}
}
/**
* 构造经纬度列表
*
* @return
*/
private List<MogoLatLng> getMogoList(List<MarkerExploreWay> markerExploreWayList) {
List<MogoLatLng> list = new ArrayList<>();
if (markerExploreWayList != null && markerExploreWayList.size() > 0) {
if (markerExploreWayList.size() < 6) {
for (int i = 0; i < markerExploreWayList.size(); i++) {
MarkerLocation location = markerExploreWayList.get(i).getLocation();
if (location != null) {
MogoLatLng mogoLatLng = new MogoLatLng(location.getLat(), location.getLon());
list.add(mogoLatLng);
} else {
Logger.e(TAG, "getMogoList() < 6 location == null");
}
}
} else {
for (int i = 0; i < 6; i++) {
MarkerLocation location = markerExploreWayList.get(i).getLocation();
if (location != null) {
MogoLatLng mogoLatLng = new MogoLatLng(location.getLat(), location.getLon());
list.add(mogoLatLng);
} else {
Logger.e(TAG, "getMogoList() location == null");
}
}
}
} else {
Logger.e(TAG, "getMogoList() markerExploreWay == null");
}
return list;
}
@Override
public void onDestroy() {
super.onDestroy();
if (poiInfosList != null) {
poiInfosList.clear();
poiInfosList = null;
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
EventBus.getDefault().unregister(this);
}
}

View File

@@ -1,11 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment.presenter
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.function.v2x.events.fragment.V2XEventPanelFragment
/**
* 事件面板presenter
*
* @author tongchenfei
*/
class EventPanelPresenter(view: V2XEventPanelFragment) : Presenter<V2XEventPanelFragment>(view)

View File

@@ -1,27 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment.presenter;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.function.v2x.events.fragment.V2XScenarioHistoryFragment;
import com.mogo.eagle.core.function.v2x.events.utils.V2XSQLiteUtils;
import com.mogo.module.common.entity.V2XHistoryScenarioData;
import com.mogo.eagle.core.utilcode.mogo.thread.WorkThreadHandler;
import java.util.List;
/**
* @author donghongyu
*/
public class ScenarioHistoryPresenter extends Presenter<V2XScenarioHistoryFragment> {
public ScenarioHistoryPresenter(V2XScenarioHistoryFragment view) {
super(view);
}
public void loadHistory() {
WorkThreadHandler.getInstance().post(() -> {
List<V2XHistoryScenarioData> v2XHistoryScenarioData = V2XSQLiteUtils.getScenarioHistoryData();
mView.loadHistory(v2XHistoryScenarioData);
});
}
}

View File

@@ -1,18 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment.presenter;
import com.mogo.commons.mvp.IView;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.function.v2x.events.fragment.V2XShareEventsFragment;
import com.mogo.eagle.core.utilcode.mogo.thread.WorkThreadHandler;
public class ShareEventsPresenter extends Presenter<V2XShareEventsFragment> {
public ShareEventsPresenter(IView view) { super((V2XShareEventsFragment) view); }
public void loadShareEventList() {
WorkThreadHandler.getInstance().post(() -> {
mView.getShareEventResponse();
});
}
}

View File

@@ -1,112 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.fragment.presenter;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.v2x.events.entity.panel.Center;
import com.mogo.eagle.core.function.v2x.events.entity.panel.SurroundingRequest;
import com.mogo.eagle.core.function.v2x.events.entity.panel.SurroundingResponse;
import com.mogo.eagle.core.function.v2x.events.network.V2XApiServiceFactory;
import com.mogo.eagle.core.function.v2x.events.widgets.SurroundingEventView;
import com.mogo.eagle.core.network.RequestOptions;
import com.mogo.eagle.core.network.SubscribeImpl;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.service.IMogoServiceApis;
import com.mogo.eagle.core.data.constants.MogoServicePaths;
import com.mogo.service.network.IMogoNetwork;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.RequestBody;
/**
* @author lixiaopeng
* @description
* @since 2020/7/29
*/
public class SurroundingEventPresenter extends Presenter<SurroundingEventView> {
private Context mContext;
private IMogoNetwork mNetWork;
private IMogoServiceApis mApis;
private static final String TAG = "V2XSurroundingFragment";
public SurroundingEventPresenter(Context context, SurroundingEventView view) {
super(view);
mContext = context;
mNetWork =
((IMogoServiceApis) ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(view.getContext())).getNetworkApi();
mApis = (IMogoServiceApis) ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(getContext());
}
@Override
public void onCreate(@NonNull LifecycleOwner owner) {
super.onCreate(owner);
}
public void getSurroundingEventData() {
MogoLocation location = mApis.getMapServiceApi().getSingletonLocationClient(mContext).getLastKnowLocation();
if (location == null) {
return;
}
Center center = new Center(location.getLatitude(), location.getLongitude());
String[] poiTypes = {"10002", "10003", "10006", "10007", "10008", "10010", "10011", "10013", "10015"};
SurroundingRequest request = new SurroundingRequest(center, poiTypes, 5, 300);
V2XApiServiceFactory.getDevaApiService(mContext).getSurroundingEventList(MoGoAiCloudClientConfig.getInstance().getSn(), convert(GsonUtil.jsonFromObject(request)))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SubscribeImpl<SurroundingResponse>(RequestOptions.create(getContext())) {
@Override
public void onError(Throwable e) {
super.onError(e);
mView.showSurroudingData(null);
Logger.e(TAG, "onError e = " + e);
e.printStackTrace();
}
@Override
public void onSuccess(SurroundingResponse data) {
super.onSuccess(data);
Logger.d(TAG, "onSuccess ------> ");
if (data != null && data.getResult() != null) {
mView.showSurroudingData(data.getResult().getExploreWay());
}
}
@Override
public void onError(String message, int code) {
super.onError(message, code);
mView.showSurroudingData(null);
Logger.e(TAG, "onError message = " + message + " >>> code = " + code);
}
});
}
public static RequestBody convert(String json) {
// String json = GsonUtil.getGson().toJson( map );
Logger.d(TAG, "request params: %s", json);
RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json);
return requestBody;
}
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
super.onDestroy(owner);
}
@Override
public void onLifecycleChanged(@NonNull LifecycleOwner owner, @NonNull Lifecycle.Event event) {
super.onLifecycleChanged(owner, event);
}
}

View File

@@ -1,113 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.provider;
import static com.mogo.eagle.core.function.v2x.events.consts.V2XConst.MODULE_NAME;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.function.v2x.events.V2XEventManager;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.fragment.V2XEventPanelFragment;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.service.eventpanel.IEventPanelProvider;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.ModuleType;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-2114:03
* desc : V2X的管理
* version: 2.0
*/
@Route(path = V2XConst.PATH_EVENT_PANEL)
public class V2XEventPanelModuleProvider implements
IEventPanelProvider {
private final String TAG = "EventPanelModuleProvider";
@Override
public Fragment createFragment(Context context, Bundle data) {
Logger.d(MODULE_NAME, "事件模版 createFragment。。。。");
return V2XEventPanelFragment.Companion.getInstance();
}
@Override
public View createView(Context context) {
return null;
}
@NonNull
@Override
public String getModuleName() {
return V2XConst.MODULE_NAME_EVENT_PANEL;
}
@Override
public IMogoModuleLifecycle getCardLifecycle() {
return null;
}
@Override
public IMogoMapListener getMapListener() {
return null;
}
@Override
public int getType() {
return ModuleType.TYPE_CARD_FRAGMENT;
}
@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) {
V2XEventManager.INSTANCE.init(context);
Logger.d(MODULE_NAME, "事件模版 模块初始化。。。。");
}
@Override
public void showPanelWithSelectedItem(int item) {
V2XEventPanelFragment.Companion.getInstance().showPanelWithSelectedItem(item);
}
@Override
public void showPanel() {
V2XEventPanelFragment.Companion.getInstance().showPanel();
}
@Override
public void hidePanel() {
V2XEventPanelFragment.Companion.getInstance().hidePanel();
}
}

View File

@@ -35,12 +35,12 @@ public interface IV2XScenario {
/**
* 展示按钮
*/
void showButton();
default void showButton() {}
/**
* 关闭按钮
*/
void closeButton();
default void closeButton() {}
/**
* 绘制POI

View File

@@ -1,61 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.scenario.scene.road;
import android.content.Intent;
import android.view.View;
import android.widget.TextView;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XButton;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XButtonListener;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceCallbackListener;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceConstants;
import com.mogo.module.v2x.voice.V2XVoiceManager;
/**
* 道路实况按钮
*/
public class V2XRoadEventButton implements IV2XButton {
private TextView tv;
private IV2XButtonListener mListener;
private V2XVoiceCallbackListener mVoiceListener = (String command, Intent intent) -> {
if (mListener != null) {
mListener.onAction();
}
close();
};
@Override
public void setOnActionListener(IV2XButtonListener listener) {
mListener = listener;
}
@Override
public void show() {
// 注册语音交互
registerVoice();
}
@Override
public void close() {
if (tv != null) {
tv.setVisibility(View.GONE);
// 反注册语音交互
mListener = null;
}
unRegisterVoice();
}
@Override
public void registerVoice() {
V2XVoiceManager.INSTANCE
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_COMMON_CONFIRM, mVoiceListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CONFIRM_UN_WAKEUP, mVoiceListener);
}
@Override
public void unRegisterVoice() {
V2XVoiceManager.INSTANCE
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_COMMON_CONFIRM)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CONFIRM_UN_WAKEUP);
}
}

View File

@@ -1,27 +1,19 @@
package com.mogo.eagle.core.function.v2x.events.scenario.scene.road;
import android.view.View;
import android.view.ViewGroup;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XStatusManager;
import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager;
import com.mogo.eagle.core.function.v2x.events.scenario.impl.AbsV2XScenario;
import com.mogo.eagle.core.function.v2x.events.scenario.scene.livecar.V2XRoadLiveCarScenario;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XWindow;
import com.mogo.eagle.core.function.v2x.events.utils.ADASUtils;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.util.Utils;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.common.entity.V2XRoadEventEntity;
import com.mogo.service.analytics.IMogoAnalytics;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.windowview.IMogoTopViewManager;
import com.mogo.service.windowview.IMogoTopViewStatusListener;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import java.util.HashMap;
import java.util.Map;
@@ -32,13 +24,11 @@ import java.util.Map;
* desc : 道路预警场景
* version: 1.0
*/
public class V2XRoadEventScenario extends AbsV2XScenario<V2XRoadEventEntity> implements IMogoTopViewStatusListener {
public class V2XRoadEventScenario extends AbsV2XScenario<V2XRoadEventEntity> implements IMoGoWarningStatusListener {
private static final String TAG = "V2XRoadEventScenario";
public V2XRoadEventScenario() {
setV2XButton(new V2XRoadEventButton());
setV2XMarker(new V2XRoadEventMarker());
setV2XWindow(new V2XRoadEventWindow());
}
@Override
@@ -72,29 +62,17 @@ public class V2XRoadEventScenario extends AbsV2XScenario<V2XRoadEventEntity> imp
try {
if (getV2XMessageEntity() != null && getV2XMessageEntity().getContent() != null) {
//只展示不播报 不广播
boolean onlyShow = getV2XMessageEntity().isOnlyShow();
if (onlyShow == false) {
if (!onlyShow) {
// 设置TTS
getV2XMessageEntity().getContent().getTts(false);
// 广播给ADASzzz
ADASUtils.broadcastToADAS(
BridgeApi.INSTANCE.context(),
getV2XMessageEntity().getContent());
}
IMogoStatusManager statusManager = BridgeApi.INSTANCE.statusManager();
boolean isMainPageOnResume = false;
if (statusManager != null && statusManager.isMainPageOnResume()) {
isMainPageOnResume = true;
showWindow();
}
IMogoAnalytics analytics = BridgeApi.INSTANCE.analytics();
if (analytics != null) {
// 地图主动推送/触发消息 埋点
@@ -119,46 +97,11 @@ public class V2XRoadEventScenario extends AbsV2XScenario<V2XRoadEventEntity> imp
@Override
public void showWindow() {
if (getV2XWindow() != null) {
// 关闭直播弹窗
try {
IV2XWindow v2XWindow = V2XRoadLiveCarScenario.getInstance().getV2XWindow();
if (v2XWindow != null) {
IMogoTopViewManager topViewManager = BridgeApi.INSTANCE.topViewManager();
if (topViewManager != null) {
topViewManager.removeSubView(v2XWindow.getView());
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 关闭之前的事件弹窗
boolean isShowEventWindow = false;
IMoGoV2XStatusManager statusManager = BridgeApi.INSTANCE.v2xStatus();
if (statusManager != null) {
isShowEventWindow = statusManager.isRoadEventWindowShow();
}
if (isShowEventWindow) {
((V2XRoadEventWindow) getV2XWindow()).updateTopWindowInfo(getV2XMessageEntity().getContent());
} else {
ViewGroup.LayoutParams layoutParams =
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
(int) Utils.getApp().getResources().getDimension(R.dimen.module_v2x_event_window_height));
IMogoTopViewManager topViewManager = BridgeApi.INSTANCE.topViewManager();
if (topViewManager != null) {
topViewManager.addView(getV2XWindow().getView(), layoutParams, this);
}
getV2XWindow().show(getV2XMessageEntity().getContent());
}
if (statusManager != null) {
statusManager.setRoadEventWindowShow(TAG, true);
}
V2XMessageEntity<V2XRoadEventEntity> entity = getV2XMessageEntity();
V2XRoadEventEntity content = entity != null ? entity.getContent() : null;
if (content != null) {
CallerHmiManager.INSTANCE.showWarningV2X(entity.getType(), content.getAlarmContent(), content.getTts(), TAG, null, !entity.isOnlyShow(), 5000L);
}
}
@Override
@@ -184,70 +127,45 @@ public class V2XRoadEventScenario extends AbsV2XScenario<V2XRoadEventEntity> imp
}
}
@Override
public void closeButton() {
if (getV2XButton() != null) {
getV2XButton().close();
}
IMoGoV2XStatusManager statusManager = BridgeApi.INSTANCE.v2xStatus();
if (statusManager != null) {
statusManager.setRoadEventButtonShow(TAG, false);
}
}
@Override
public void drawPOI() {
if (getV2XMarker() != null) {
IV2XMarker marker = getV2XMarker();
if (marker != null) {
// 重置告警信息
V2XStatusManager.getInstance().setAlarmInfo(getV2XMessageEntity().getContent());
getV2XMarker().drawPOI(getV2XMessageEntity().getContent());
marker.drawPOI(getV2XMessageEntity().getContent());
}
}
@Override
public void clearPOI() {
if (getV2XMarker() != null) {
getV2XMarker().clearPOI();
IV2XMarker marker = getV2XMarker();
if (marker != null) {
marker.clearPOI();
}
}
@Override
public void onViewAdded(View view) {
//Logger.d(MODULE_NAME, "展示 Window 动画结束");
IMogoStatusManager statusManager = BridgeApi.INSTANCE.statusManager();
boolean isMainPageOnResume = false;
if (statusManager != null) {
isMainPageOnResume = statusManager.isMainPageOnResume();
public void onShow() {
Logger.d(V2XConst.MODULE_NAME, "弹窗展示");
IMoGoV2XStatusManager status = BridgeApi.INSTANCE.v2xStatus();
if (status != null) {
status.setRoadEventWindowShow(TAG, true);
}
if (isMainPageOnResume) {
if (getV2XMessageEntity() != null && getV2XMessageEntity().isNeedAddLine() == true) {
drawPOI();
}
V2XMessageEntity<V2XRoadEventEntity> entity = getV2XMessageEntity();
if (entity != null && entity.isNeedAddLine()) {
drawPOI();
}
}
@Override
public void onViewRemoved(View view) {
Logger.d(V2XConst.MODULE_NAME, "关闭 Window 动画结束");
release();
}
@Override
public void beforeViewAddAnim(View view) {
//Logger.d(MODULE_NAME, "展示 Window 开始");
}
@Override
public void beforeViewRemoveAnim(View view) {
//Logger.d(MODULE_NAME, "关闭 Window 开始");
public void onDismiss() {
Logger.d(V2XConst.MODULE_NAME, "弹窗消失");
IMoGoV2XStatusManager status = BridgeApi.INSTANCE.v2xStatus();
if (status != null) {
status.setRoadEventWindowShow(TAG, false);
}
// 重置场景提示的消息
setV2XMessageEntity(null);
clearPOI();
closeButton();
release();
}
}

View File

@@ -1,312 +0,0 @@
package com.mogo.eagle.core.function.v2x.events.scenario.scene.road;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.function.v2x.R;
import com.mogo.eagle.core.function.v2x.events.adapter.V2XRoadEventAdapter;
import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi;
import com.mogo.eagle.core.function.v2x.events.entity.net.V2XLiveCarRes;
import com.mogo.eagle.core.function.v2x.events.listener.V2XWindowStatusListener;
import com.mogo.eagle.core.function.v2x.events.network.V2XRefreshCallback;
import com.mogo.eagle.core.function.v2x.events.network.V2XRefreshModel;
import com.mogo.eagle.core.function.v2x.events.scenario.scene.V2XBasWindow;
import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XWindow;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceCallbackListener;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoiceConstants;
import com.mogo.eagle.core.function.v2x.events.voice.V2XVoicePagingListener;
import com.mogo.module.common.entity.V2XEventShowEntity;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.common.entity.V2XRoadEventEntity;
import com.mogo.module.common.enums.EventTypeEnum;
import com.mogo.module.v2x.voice.V2XVoiceManager;
import com.mogo.service.windowview.IMogoTopViewManager;
import java.util.ArrayList;
import java.util.List;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/14 2:37 PM
* desc : 显示事件的列表
* version: 1.0
*/
public class V2XRoadEventWindow extends V2XBasWindow
implements V2XRefreshCallback<V2XLiveCarRes>, IV2XWindow<V2XRoadEventEntity> {
private String TAG = "V2XRoadEventDetailWindow";
// 关闭按钮
private ImageView mBtnCloseWindow;
// 展示列表
private RecyclerView mRecyclerView;
// 列表数据适配器
private V2XRoadEventAdapter mV2XRoadEventAdapter;
// 列表展示
private final List<V2XEventShowEntity> mItemList = new ArrayList<>();
// 当前展示的位置
private int mCurPosition;
// 处理道路事件30秒倒计时
private final Handler handlerV2XEvent = new Handler();
private Runnable runnableV2XEvent;
private int mExpireTime = 20000;
// 关闭弹窗回调
private V2XVoiceCallbackListener v2XVoiceCallbackCloseWindowListener = (command, intent) -> close();
// 翻页回调监听
private V2XVoicePagingListener v2XVoicePagingCallbackListener = new V2XVoicePagingListener() {
@Override
public void onNextCallback() {
if (mRecyclerView != null && mCurPosition >= 0 && mCurPosition < mV2XRoadEventAdapter.getItemCount() - 1) {
mRecyclerView.scrollToPosition(mCurPosition + 1);
}
}
@Override
public void onPrevCallback() {
if (mRecyclerView != null && mCurPosition > 0 && mCurPosition <= mV2XRoadEventAdapter.getItemCount() - 1) {
mRecyclerView.scrollToPosition(mCurPosition - 1);
}
}
};
public V2XRoadEventWindow() {
this(BridgeApi.INSTANCE.context(), null);
}
public V2XRoadEventWindow(Context context) {
this(context, null);
}
public V2XRoadEventWindow(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public V2XRoadEventWindow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
/**
* 初始化视图
*/
private void initView(Context context) {
//Logger.d(MODULE_NAME, "V2X===初始化道路事件小窗口View。。。。。");
// 填充布局
LayoutInflater.from(context).inflate(BridgeApi.INSTANCE.statusManager() != null && BridgeApi.INSTANCE.statusManager().isVrMode() ?
R.layout.window_road_event_detail_vr : R.layout.window_road_event_detail, this);
// 详情列表
mBtnCloseWindow = findViewById(R.id.btnCloseWindow);
// 详情列表
mRecyclerView = findViewById(R.id.rvRoadEventList);
mBtnCloseWindow.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
close();
}
});
mV2XRoadEventAdapter = new V2XRoadEventAdapter(mItemList, this);
mRecyclerView.setAdapter(mV2XRoadEventAdapter);
// 设置切换样式
new PagerSnapHelper().attachToRecyclerView(mRecyclerView);
// 配置列表朝向
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (recyclerView.getChildCount() > 0) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//获得当前显示在第一个item的位置
mCurPosition = layoutManager.findFirstCompletelyVisibleItemPosition();
// 用户处于交互的时候延后隐藏时间
startCountDown();
}
}
}
});
}
/**
* 展示道路事件详情Windows
*/
@Override
public void show(V2XRoadEventEntity entity) {
//Logger.d(MODULE_NAME, "V2X===道路事件详情:展示 Window" + entity);
// 注册语音交互
V2XVoiceManager.INSTANCE
.registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CLOSE_WINDOW, v2XVoiceCallbackCloseWindowListener)
.registerUnWakeVoice(V2XVoiceConstants.COMMAND_V2X_TO_CLOSE_WINDOW_UN_WAKEUP, v2XVoiceCallbackCloseWindowListener)
.registerPagingCallback(v2XVoicePagingCallbackListener);
// 更新头部的窗体视图
updateTopWindowInfo(entity);
// 倒计时
mExpireTime = entity.getExpireTime();
startCountDown();
}
/**
* 更新头部的窗体视图
*/
public void updateTopWindowInfo(V2XRoadEventEntity v2XRoadEventEntity) {
//Logger.d(MODULE_NAME, "V2X===道路事件详情:更新 Window" + v2XRoadEventEntity);
// 清空数据
mItemList.clear();
if (v2XRoadEventEntity != null) {
// 道路事件行驶到了50米附近弹出事件纠错框给用户
//Logger.d(MODULE_NAME, "V2X===道路事件:" + v2XRoadEventEntity);
// 进行类型分发
if (EventTypeEnum.TRAFFIC_CHECK.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.ROAD_CLOSED.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ROAD_WORK.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_BLOCK_UP.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_PONDING.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_FOG.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ICE.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ACCIDENT.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ACCIDENT_01.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ACCIDENT_02.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ACCIDENT_03.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ACCIDENT_04.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_ACCIDENT_05.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_LIVING.getPoiType().equals(v2XRoadEventEntity.getPoiType())
|| EventTypeEnum.FOURS_NEALY.getPoiType().equals(v2XRoadEventEntity.getPoiType())) {
// 展示道路事件本身详情
if (mItemList.isEmpty()) {
V2XEventShowEntity v2XEventShowEntity = new V2XEventShowEntity();
v2XEventShowEntity.setViewType(V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING);
v2XEventShowEntity.setV2XRoadEventEntity(v2XRoadEventEntity);
mItemList.add(v2XEventShowEntity);
}
// 获取道路事件周边的直播车机
V2XRefreshModel v2XRefreshModel = BridgeApi.INSTANCE.refreshModel();
if (v2XRefreshModel != null) {
v2XRefreshModel
.queryNearbyVehicleLiveByLocation(
this,
v2XRoadEventEntity.getLocation().getLon(),
v2XRoadEventEntity.getLocation().getLat());
}
}
}
// 刷新列表
mV2XRoadEventAdapter.notifyDataSetChanged();
}
@Override
public void onSuccess(V2XLiveCarRes result) {
//Logger.d(MODULE_NAME, "V2X===事件周边的直播车机:" + result);
try {
if (!mItemList.isEmpty() &&
result != null &&
result.getResult() != null &&
result.getResult().getInfo() != null &&
result.getResult().getInfo().size() > 0) {
mItemList.get(0).setV2XLiveCarList(result.getResult().getInfo());
}
// 刷新列表
mV2XRoadEventAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFail(String msg) {
}
/**
* 关闭详情展示框
*/
@Override
public void close() {
//Logger.d(MODULE_NAME, "V2X===关闭 Window");
// 注册语音交互
V2XVoiceManager.INSTANCE.unRegisterPagingCallback();
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)
.unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_LIVE_ROAD)
.unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_LIVE_UN_WAKEUP)
.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);
// 停止倒计时
if (handlerV2XEvent != null && runnableV2XEvent != null) {
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
runnableV2XEvent = null;
}
//移除窗体
IMogoTopViewManager topViewManager = BridgeApi.INSTANCE.topViewManager();
if (topViewManager != null) {
topViewManager.removeView(this);
}
}
@Override
public View getView() {
return this;
}
@Override
public void setWindowStatusListener(V2XWindowStatusListener listener) {
}
/**
* 窗体倒计时
*/
public void startCountDown() {
// 倒计时
if (runnableV2XEvent == null) {
runnableV2XEvent = () -> {
//Logger.d(MODULE_NAME, "V2X=== Window 30秒倒计时结束。。。");
// 移出Window详细信息
close();
};
} else {
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
}
//Logger.d(MODULE_NAME, "V2X=== Window 展示开始倒计时:" + mExpireTime);
handlerV2XEvent.postDelayed(runnableV2XEvent, mExpireTime);
}
/**
* 停止倒计时
*/
public void stopCountDown() {
// 停止倒计时
if (handlerV2XEvent != null && runnableV2XEvent != null) {
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
runnableV2XEvent = null;
}
}
@Override
protected void release() {
super.release();
}
}

View File

@@ -1,7 +1,6 @@
package com.mogo.eagle.core.function.v2x.events.utils;
import com.mogo.eagle.core.function.v2x.events.consts.V2XConst;
import com.mogo.eagle.core.function.v2x.events.fragment.V2XEventPanelFragment;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.mogo.sqlite.SQLIDao;
@@ -95,7 +94,7 @@ public class V2XSQLiteUtils {
try {
int result = getScenarioHistoryDao().update(oldScenarioData, newScenarioData);
Logger.d(V2XConst.MODULE_NAME, "修改数据成功:" + result);
V2XEventPanelFragment.Companion.getInstance().changeEventCount();
//V2XEventPanelFragment.Companion.getInstance().changeEventCount();
} catch (Exception e) {
e.printStackTrace();
}
@@ -171,7 +170,7 @@ public class V2XSQLiteUtils {
// 存储新数据
V2XSQLiteUtils.getScenarioHistoryDao().insert(v2XHistoryScenarioData);
}
V2XEventPanelFragment.Companion.getInstance().changeEventCount();
//V2XEventPanelFragment.Companion.getInstance().changeEventCount();
} catch (Exception e) {
e.printStackTrace();
}

View File

@@ -168,13 +168,7 @@ class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener,
private fun redLightWarning() {
Logger.d(TAG, "=====闯红灯预警=====")
ThreadUtils.runOnUiThread {
CallerHmiManager.showWarningV2X(
EventTypeEnum.TYPE_USECASE_ID_IVP.poiType.toInt(),
EventTypeEnum.TYPE_USECASE_ID_IVP.content,
EventTypeEnum.TYPE_USECASE_ID_IVP.tts,
EventTypeEnum.TYPE_USECASE_ID_IVP.poiType,
null
)
CallerHmiManager.showWarningV2X(EventTypeEnum.TYPE_USECASE_ID_IVP.poiType.toInt(), EventTypeEnum.TYPE_USECASE_ID_IVP.content, EventTypeEnum.TYPE_USECASE_ID_IVP.tts, EventTypeEnum.TYPE_USECASE_ID_IVP.poiType, null, true, 5000L)
}
}
@@ -192,11 +186,7 @@ class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener,
EventTypeEnum.getWarningTts(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType),
speed
)
CallerHmiManager.showWarningV2X(
EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType.toInt(),
content, tts,
EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, null
)
CallerHmiManager.showWarningV2X(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType.toInt(), content, tts, EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, null, true, 5000L)
}
}

View File

@@ -129,20 +129,16 @@ class VipCarManager : IMogoOnMessageListener<VipMessage>, IMoGoTrafficLightListe
//如果上次结果和本次灯态结果变化比较大则已变灯控制HMI展示弹窗
if (abs(currentResult!!.remain - it.remain) > 5 && currentResult.isGreen()) {
Logger.d(TAG, "调用showWarningV2X to show")
CallerHmiManager.showWarningV2X(EventTypeEnum.TYPE_VIP_IDENTIFICATION.poiType.toInt(),
EventTypeEnum.TYPE_VIP_IDENTIFICATION.content,
EventTypeEnum.TYPE_VIP_IDENTIFICATION.tts,
EventTypeEnum.TYPE_VIP_IDENTIFICATION.poiType,
object : IMoGoWarningStatusListener {
override fun onShow() {}
override fun onDismiss() {
Logger.d(
TAG,
"showWarningV2X vip dismiss , resetConditions"
)
resetConditions()
}
})
CallerHmiManager.showWarningV2X(EventTypeEnum.TYPE_VIP_IDENTIFICATION.poiType.toInt(), EventTypeEnum.TYPE_VIP_IDENTIFICATION.content, EventTypeEnum.TYPE_VIP_IDENTIFICATION.tts, EventTypeEnum.TYPE_VIP_IDENTIFICATION.poiType, object : IMoGoWarningStatusListener {
override fun onShow() {}
override fun onDismiss() {
Logger.d(
TAG,
"showWarningV2X vip dismiss , resetConditions"
)
resetConditions()
}
}, true, 5000L)
}
}

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvRoadEventList"
android:layout_width="match_parent"
android:layout_height="@dimen/module_v2x_event_window_height"
android:minHeight="@dimen/module_v2x_event_window_height"
android:orientation="horizontal"
android:overScrollMode="never"
android:padding="@dimen/module_v2x_widow_top_gaps"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/item_v2x_event_detail" />
<ImageView
android:id="@+id/btnCloseWindow"
android:layout_width="@dimen/dp_88"
android:layout_height="@dimen/dp_88"
android:layout_marginEnd="@dimen/dp_32"
android:layout_marginBottom="@dimen/dp_40"
android:background="@drawable/module_common_close_selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/module_v2x_road_event_window_width_vr"
android:layout_height="@dimen/module_v2x_road_event_window_height_vr"
android:layout_marginTop="@dimen/dp_8">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvRoadEventList"
android:layout_width="match_parent"
android:layout_height="@dimen/module_v2x_road_event_window_height_vr"
android:minHeight="@dimen/module_v2x_event_window_height"
android:orientation="horizontal"
android:overScrollMode="never"
android:padding="@dimen/module_v2x_widow_top_gaps"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/item_v2x_event_detail_vr" />
<ImageView
android:id="@+id/btnCloseWindow"
android:layout_width="@dimen/dp_88"
android:layout_height="@dimen/dp_88"
android:layout_marginEnd="@dimen/dp_32"
android:layout_marginBottom="@dimen/dp_40"
android:background="@drawable/module_common_close_selector"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -159,13 +159,6 @@ public class MogoServicePaths {
@Deprecated
public static final String PATH_MARKER_SERVICE = "/mogomarker/api";
/**
* 事件面板
*/
@Keep
@Deprecated
public static final String PATH_EVENT_PANEL = "/event/panel";
/**
* 位置上报
*/

View File

@@ -52,13 +52,7 @@ interface IMoGoWaringProvider {
* @param ttsContent tts语音播报消息
* @param tag tag绑定弹窗的标志
*/
fun showWarningV2X(
v2xType: Int,
alertContent: String?,
ttsContent: String?,
tag: String?,
listenerIMoGo: IMoGoWarningStatusListener?
)
fun showWarningV2X(v2xType: Int, alertContent: String?, ttsContent: String?, tag: String?, listenerIMoGo: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long)
/**
* 关闭指定floatTag 的 VR下V2X预警弹窗

View File

@@ -74,14 +74,8 @@ object CallerHmiManager : CallerBase() {
* @param ttsContent tts语音播报消息
* @param tag tag绑定弹窗的标志
*/
fun showWarningV2X(
v2xType: Int,
alertContent: String?,
ttsContent: String?,
tag: String?,
listenerIMoGo: IMoGoWarningStatusListener?
) {
waringProviderApi.showWarningV2X(v2xType, alertContent, ttsContent, tag, listenerIMoGo)
fun showWarningV2X(v2xType: Int, alertContent: String?, ttsContent: String?, tag: String?, listenerIMoGo: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long = 5000L) {
waringProviderApi.showWarningV2X(v2xType, alertContent, ttsContent, tag, listenerIMoGo, playTts, expireTime)
}
/**

View File

@@ -38,6 +38,11 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
kapt.includeCompileClasspath = false
@@ -65,6 +70,9 @@ dependencies {
api rootProject.ext.dependencies.life_cycle_scope
api rootProject.ext.dependencies.view_model_scope
api rootProject.ext.dependencies.live_data_scope
api rootProject.ext.dependencies.androidxlifecycleprocess
api rootProject.ext.dependencies.androidxccorektx
api rootProject.ext.dependencies.life_cycle_java8
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,331 @@
package com.mogo.eagle.core.utilcode.reminder
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.lifecycle.*
import androidx.lifecycle.Lifecycle.Event
import androidx.lifecycle.Lifecycle.Event.ON_CREATE
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.ActivityReminder
import kotlinx.coroutines.*
import kotlinx.coroutines.android.asCoroutineDispatcher
import java.lang.IllegalStateException
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArraySet
object Reminder {
private val heap by lazy {
PriorityQueue<IReminder>()
}
private val queue by lazy {
LinkedList<IReminder>()
}
private val listeners by lazy {
CopyOnWriteArrayList<IReminder.IGlobalStateChangeListener>()
}
private val reminderListeners by lazy {
ConcurrentHashMap<IReminder, IReminder.IStateChangeListener>()
}
private val enqueued by lazy {
CopyOnWriteArraySet<String>()
}
private val showed by lazy {
ConcurrentHashMap<String, State>()
}
private val attaches by lazy {
ConcurrentHashMap<LifecycleOwner, MutableList<IReminder>>()
}
private val scope by lazy {
CoroutineScope(Handler(Looper.getMainLooper()).asCoroutineDispatcher("reminder-scope") + SupervisorJob())
}
private const val MSG_WHAT_FOR_OVERRIDE_MAX_PROTECT_DURATION = 0x1010
private const val MSG_WHAT_FOR_UN_OVERRIDE_MAX_PROTECT_DURATION = 0x1011
private val handler by lazy { Handler(Looper.getMainLooper()) {
if (it.what == MSG_WHAT_FOR_OVERRIDE_MAX_PROTECT_DURATION) {
val reminder = it.obj as? IReminder
if (reminder != null) {
markUnShowed(reminder.key())
if (reminder.isOverride()) {
queue.remove(reminder)
reminderListeners.remove(reminder)
enqueued -= reminder.key()
dequeue()
}
}
}
if (it.what == MSG_WHAT_FOR_UN_OVERRIDE_MAX_PROTECT_DURATION) {
val reminder = it.obj as? IReminder
if (reminder != null) {
markUnShowed(reminder.key())
if (!reminder.isOverride()) {
heap.remove(reminder)
enqueued -= reminder.key()
reminderListeners.remove(reminder)
dequeueHeap()
}
}
}
return@Handler true
} }
private val attachToObserver = LifecycleEventObserver { source, event ->
if (event == ON_DESTROY) {
recycle(source)
}
}
fun enqueue(attachTo: LifecycleOwner, reminder: IReminder) {
enqueue(attachTo, reminder, null)
}
fun enqueue(attachTo: LifecycleOwner, reminder: IReminder, listener: IReminder.IStateChangeListener?) {
val key = reminder.key()
if (key.isEmpty()) {
throw IllegalStateException("reminder: ${reminder.javaClass.name}'s key can't be empty.")
}
if (enqueued.contains(key)) {
return
}
enqueued += key
attaches.getOrPut(attachTo, {
mutableListOf()
}).also {
it.add(reminder)
}
listener?.let {
reminderListeners[reminder] = it
}
scope.launch {
if (reminder is ActivityReminder) {
attachTo.lifecycleScope.launchWhenCreated {
tryDequeue(reminder)
}
} else {
attachTo.lifecycleScope.launchWhenResumed {
tryDequeue(reminder)
}
}
attachTo.lifecycle.addObserver(attachToObserver)
}
}
private fun tryDequeue(reminder: IReminder) {
if (!reminder.isOverride()) {
heap += reminder
dequeueHeap()
} else {
queue += reminder
val pre = findPreShowedReminder()
if (pre != null) {
pre.hide()
} else {
dequeue()
}
}
}
private fun recycle(attachTo: LifecycleOwner) {
val reminders = attaches.remove(attachTo) ?: return
try {
reminders.forEach {
if (it.isShowing()) {
it.hide()
}
enqueued.remove(it.key())
showed.remove(it.key())
if (it.isOverride()) {
queue.remove(it)
} else {
heap.remove(it)
}
}
} catch (t: Throwable) {
t.printStackTrace()
}
}
private fun dequeueHeap() {
if (heap.isEmpty()) return
val head = heap.peek() ?: return
val key = head.key()
if (isMarkShowed(key) || head.isShowing()) {
return
}
if (head.doShowOnTurn()) {
head.show()
markShowed(key, false)
doProtectAction(head)
head.lifecycleOwner().lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Event) {
if (event == ON_CREATE) {
removeProtectAction(false)
notifyGlobalStateChanged(head, true)
reminderListeners[head]?.onShow(head)
}
if (event == ON_DESTROY) {
notifyGlobalStateChanged(head, false)
reminderListeners[head]?.onHide(head)
reminderListeners.remove(head)
enqueued -= key
heap.poll()
markUnShowed(key)
this@Reminder.dequeueHeap()
}
}
})
} else {
heap.poll()
dequeueHeap()
}
}
private fun markShowed(key: String, isOverride: Boolean) {
var state = showed[key]
if (state == null) {
state = State(key, isOverride = isOverride, isShowing = true)
showed[key] = state
}
}
private fun isMarkShowed(key: String): Boolean = showed[key]?.isShowing ?: false
private fun markUnShowed(key: String) = showed.remove(key)
private fun dequeue() {
while (!queue.isEmpty()) {
val head = queue.peek()
if (head != null) {
val key = head.key()
if (isMarkShowed(key)) {
break
}
if (head.doShowOnTurn()) {
head.show()
markShowed(key, true)
doProtectAction(head)
head.lifecycleOwner().lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Event) {
if (event == ON_CREATE) {
removeProtectAction(true)
notifyGlobalStateChanged(head, true)
reminderListeners[head]?.onShow(head)
}
if (event == ON_DESTROY) {
notifyGlobalStateChanged(head, false)
reminderListeners[head]?.onHide(head)
reminderListeners.remove(head)
queue -= head
enqueued -= head.key()
markUnShowed(key)
dequeue()
}
}
})
break
} else {
queue.poll()
}
} else {
queue.poll()
}
}
}
private fun doProtectAction(reminder: IReminder) {
val isOverride = reminder.isOverride()
val duration = reminder.maxProtectDuration()
if (duration > 0) {
if (isOverride) {
handler.removeMessages(MSG_WHAT_FOR_OVERRIDE_MAX_PROTECT_DURATION)
handler.sendMessageDelayed(Message.obtain(handler, MSG_WHAT_FOR_OVERRIDE_MAX_PROTECT_DURATION, reminder), duration)
} else {
handler.removeMessages(MSG_WHAT_FOR_UN_OVERRIDE_MAX_PROTECT_DURATION)
handler.sendMessageDelayed(Message.obtain(handler, MSG_WHAT_FOR_UN_OVERRIDE_MAX_PROTECT_DURATION, reminder), duration)
}
}
}
private fun removeProtectAction(isOverride: Boolean) {
if (isOverride) {
handler.removeMessages(MSG_WHAT_FOR_OVERRIDE_MAX_PROTECT_DURATION)
} else {
handler.removeMessages(MSG_WHAT_FOR_UN_OVERRIDE_MAX_PROTECT_DURATION)
}
}
private fun findPreShowedReminder(): IReminder? {
val key = showed.values.find { it.isOverride && it.isShowing }?.key ?: return null
return queue.find { it.key() == key }
}
fun registerGlobalStateChangeListener(listener: IReminder.IGlobalStateChangeListener) {
if (listeners.contains(listener)) {
return
}
listeners += listener
}
fun unRegisterGlobalStateChangeListener(listener: IReminder.IGlobalStateChangeListener) {
if (!listeners.contains(listener)) {
return
}
listeners -= listener
}
private fun notifyGlobalStateChanged(reminder: IReminder, isShow: Boolean) {
listeners.forEach {
if (isShow) {
it.onShow(reminder)
} else {
it.onHide(reminder)
}
}
}
fun hasShowedReminder(attachTo: LifecycleOwner): Boolean {
val reminders = attaches[attachTo]
if (reminders == null || reminders.isEmpty()) {
return false
}
return reminders.find { it.isShowing() } != null
}
fun dismissAll(attachTo: LifecycleOwner) {
val reminders = attaches[attachTo]
if (reminders == null || reminders.isEmpty()) {
return
}
try {
reminders.forEach {
if (it.isOverride()) {
queue.remove(it)
} else {
heap.remove(it)
}
if (it.isShowing()) {
it.hide()
}
}
} catch (t: Throwable) {
t.printStackTrace()
}
}
internal data class State(val key: String, val isOverride: Boolean = false, var isShowing: Boolean = false)
}

View File

@@ -0,0 +1,257 @@
package com.mogo.eagle.core.utilcode.reminder.api
import android.app.Activity
import android.app.Application
import android.os.Bundle
import android.view.View
import android.widget.ListPopupWindow
import android.widget.PopupWindow
import androidx.annotation.IntRange
import androidx.core.view.doOnAttach
import androidx.core.view.doOnDetach
import androidx.lifecycle.*
import com.mogo.eagle.core.utilcode.util.R
import com.mogo.eagle.core.utilcode.util.Utils
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit
interface IReminder : Comparable<IReminder> {
fun key(): String = this.javaClass.name + this.hashCode().toString()
/**
* 返回此[IReminder]生命周期感知的LifecycleOwner,如:
* - [androidx.fragment.app.FragmentActivity]
* - [androidx.fragment.app.Fragment]
* - [androidx.fragment.app.DialogFragment]
* - [android.view.View]
* - [PopupWindow]
* - [ListPopupWindow]
* - 其它具有生命周期感知的类
*/
fun lifecycleOwner(): LifecycleOwner
/**
* 当前[IReminder]的显示优先级,只针对不可覆盖的[IReminder][IReminder.isOverride]返回false生效;
* 注:此返回值越大,优先级越高
*/
@IntRange(from = 0)
fun priority(): Int = 0
/**
* 子类实现此方法时,要执行真正的展示逻辑
*/
fun show()
/**
* 子类实现此方法时,要调用真实的显示控件消失方法
*/
fun hide()
/**
* 子类实现此方法时,要返回真实显示控件的显示状态
*/
fun isShowing(): Boolean
/**
* 是否是可覆盖的:
* 说明:
* 1.可覆盖的[IReminder]和不覆盖的[IReminder]可以同时展示, 上层业务可以根据[IReminder]的显示位置和具体业务决定是返回true/false
* 2.可覆盖的[IReminder]之前是互斥显示的
* 当中只有一个可覆盖的[IReminder] 展示, 后一个会将当前替换显示。
* 3.不可覆盖的[IReminder]之间,按优先级([IReminder.priority]返回值大小)排队展示
*/
fun isOverride() = false
/**
* 轮到此[IReminder]展示的时候是否展示
*/
fun doShowOnTurn() = true
/**
* 调用[IReminder.show]方法后,如果在此时间内没有真正展示,会将此[IReminder]从队列中移除执行dequeue操作
*/
fun maxProtectDuration(): Long = TimeUnit.SECONDS.toMillis(2)
override fun compareTo(other: IReminder): Int {
return other.priority() - this.priority()
}
interface IStateChangeListener {
fun onShow(reminder: IReminder)
fun onHide(reminder: IReminder)
}
interface IGlobalStateChangeListener : IStateChangeListener
// ------------------------ 以下是扩展函数只能在IReminder类中使用 --------------------------------------------------
companion object {
private val popupWindowLifecycleMap by lazy {
ConcurrentHashMap<PopupWindow, LifecycleOwner>()
}
private val listPopupWindowLifecycleMap by lazy {
ConcurrentHashMap<ListPopupWindow, LifecycleOwner>()
}
private val activityNameLifeCycleMap by lazy {
ConcurrentHashMap<String, LifecycleOwner>()
}
}
val <T: View> T.lifecycleOwner: LifecycleOwner
get() = getTag(R.id.view_lifecycle_owner) as? LifecycleOwner ?: object : LifecycleOwner, LifecycleEventObserver {
private val lifecycle = LifecycleRegistry(this)
init {
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View?) {
lifecycle.let {
if (it.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
it.currentState = Lifecycle.State.CREATED
}
}
}
override fun onViewDetachedFromWindow(v: View?) {
lifecycle.let {
if (it.currentState.isAtLeast(Lifecycle.State.CREATED)) {
it.currentState = Lifecycle.State.DESTROYED
}
}
}
})
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
lifecycle.currentState = event.targetState
}
override fun getLifecycle(): Lifecycle {
return lifecycle
}
}.also {
setTag(R.id.view_lifecycle_owner, it)
}
val <T: PopupWindow> T.lifecycleOwner: LifecycleOwner
get() = popupWindowLifecycleMap[this]
?: object : LifecycleOwner, LifecycleEventObserver {
private val lifecycle = LifecycleRegistry(this)
private var register = false
override fun getLifecycle(): Lifecycle {
val contentView = this@lifecycleOwner.contentView
?: throw IllegalStateException("Please ensure ${this@lifecycleOwner.javaClass.simpleName}'s getContentView() can't return null.")
if (!register) {
contentView.lifecycleOwner.lifecycle.addObserver(this)
register = true
}
return lifecycle
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
val state = event.targetState
lifecycle.currentState = state
if (state == Lifecycle.State.DESTROYED) {
popupWindowLifecycleMap.remove(this@lifecycleOwner)
}
}
}.also {
popupWindowLifecycleMap[this] = it
}
val <T: ListPopupWindow> T.lifecycleOwner: LifecycleOwner
get() = listPopupWindowLifecycleMap[this] ?: object : LifecycleOwner, LifecycleEventObserver {
private val lifecycle = LifecycleRegistry(this)
private var register = false
override fun getLifecycle(): Lifecycle {
val contentView = listView ?: throw IllegalStateException("Please ensure ${this@lifecycleOwner.javaClass.simpleName}'s getListView[() can't return null.")
if (!register) {
contentView.lifecycleOwner.lifecycle.addObserver(this)
register = true
}
return lifecycle
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
val state = event.targetState
lifecycle.currentState = state
if (state == Lifecycle.State.DESTROYED) {
listPopupWindowLifecycleMap.remove(this@lifecycleOwner)
}
}
}.also {
listPopupWindowLifecycleMap[this] = it
}
fun createLifeCycleOwnerByActivityName(activityClassName: String): LifecycleOwner {
return activityNameLifeCycleMap[activityClassName] ?: object : LifecycleOwner, Application.ActivityLifecycleCallbacks {
private val lifecycle = LifecycleRegistry(this)
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
if (activity.javaClass.name == activityClassName) {
lifecycle.currentState = Lifecycle.State.CREATED
}
}
override fun onActivityStarted(activity: Activity) {
if (activity.javaClass.name == activityClassName) {
lifecycle.currentState = Lifecycle.State.STARTED
}
}
override fun onActivityResumed(activity: Activity) {
if (activity.javaClass.name == activityClassName) {
lifecycle.currentState = Lifecycle.State.RESUMED
}
}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {
if (activity.javaClass.name == activityClassName) {
lifecycle.currentState = Lifecycle.State.DESTROYED
activityNameLifeCycleMap.remove(activityClassName)
Utils.getApp().unregisterActivityLifecycleCallbacks(this)
}
}
private var register = false
override fun getLifecycle(): Lifecycle {
if (!register) {
Utils.getApp().registerActivityLifecycleCallbacks(this)
register = true
}
return lifecycle
}
}.also {
activityNameLifeCycleMap[activityClassName] = it
}
}
}

View File

@@ -0,0 +1,13 @@
package com.mogo.eagle.core.utilcode.reminder.api.impl
import androidx.lifecycle.LifecycleOwner
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
import com.mogo.eagle.core.utilcode.util.AppStateManager
abstract class ActivityReminder(private val activityClassName: String): IReminder {
override fun lifecycleOwner(): LifecycleOwner = createLifeCycleOwnerByActivityName(activityClassName)
override fun isShowing() = if (AppStateManager.isActive()) AppStateManager.currentActivity()?.javaClass?.name == activityClassName else false
}

View File

@@ -0,0 +1,38 @@
package com.mogo.eagle.core.utilcode.reminder.api.impl
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
class FragmentReminder(private val fm: FragmentManager? = null, private val fragment: Fragment): IReminder {
override fun lifecycleOwner(): LifecycleOwner = fragment
override fun show() {
fm?.let {
val bt = it.beginTransaction()
bt.add(fragment, "").commitAllowingStateLoss()
try {
it.executePendingTransactions()
} catch (t: Throwable) {
t.printStackTrace()
}
}
}
override fun hide() {
fm?.let {
val bt = it.beginTransaction()
bt.remove(fragment)
bt.commitAllowingStateLoss()
try {
it.executePendingTransactions()
} catch (t: Throwable) {
t.printStackTrace()
}
}
}
override fun isShowing(): Boolean = fragment.isVisible
}

View File

@@ -0,0 +1,16 @@
package com.mogo.eagle.core.utilcode.reminder.api.impl
import android.widget.ListPopupWindow
import androidx.lifecycle.LifecycleOwner
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
abstract class ListPopupWindowReminder(private val pop: ListPopupWindow): IReminder {
override fun lifecycleOwner(): LifecycleOwner = pop.lifecycleOwner
override fun hide() {
pop.dismiss()
}
override fun isShowing(): Boolean = pop.isShowing
}

View File

@@ -0,0 +1,16 @@
package com.mogo.eagle.core.utilcode.reminder.api.impl
import android.widget.PopupWindow
import androidx.lifecycle.LifecycleOwner
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
abstract class PopupWindowReminder(private val popupWindow: PopupWindow): IReminder {
override fun lifecycleOwner(): LifecycleOwner = popupWindow.lifecycleOwner
override fun hide() {
popupWindow.dismiss()
}
override fun isShowing(): Boolean = popupWindow.isShowing
}

View File

@@ -0,0 +1,13 @@
package com.mogo.eagle.core.utilcode.reminder.api.impl
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.LifecycleOwner
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
abstract class ViewReminder(private val content: View): IReminder {
override fun lifecycleOwner(): LifecycleOwner = content.lifecycleOwner
override fun isShowing() = ViewCompat.isAttachedToWindow(content) && content.visibility == View.VISIBLE
}

View File

@@ -1,354 +0,0 @@
package com.mogo.eagle.core.utilcode.util;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.HashMap;
public class ActivityLifecycleManager {
private Application mApplication;
/**
* 当前出于 Start 状态的 Activity
*/
private ArrayList<Activity> mStartedActivities = new ArrayList<>();
private ArrayList<AppStateListener> mAppStateListeners = new ArrayList<>();
/**
* 当前存活的 Activity
*/
private HashMap<Activity, ActivityTrace> mAliveActivities = new HashMap<>();
/**
* App 是否出于前台
*/
private volatile boolean mIsAppActive = false;
private Activity mCurrentResumedActivity;
/**
* Home 键事件广播的接受器
*/
private HomeKeyEventReceiver mHomeKeyEventReceiver;
/**
* Home 键事件监听者列表
*/
private ArrayList<HomeKeyEventListener> mHomeKeyEventListeners = new ArrayList<>();
private DefActivityLifecycleCallbacks mInnerActivityListener = new DefActivityLifecycleCallbacks() {
@Override
public void onActivityStarted(Activity activity) {
if (mStartedActivities.isEmpty()) {
mIsAppActive = true;
notifyAppStateChanged(AppStateListener.ACTIVE);
}
mStartedActivities.add(activity);
ActivityTrace trace = mAliveActivities.get(activity);
if (trace != null) {
trace.startCnt++;
}
}
@Override
public void onActivityStopped(Activity activity) {
mStartedActivities.remove(activity);
if (mStartedActivities.isEmpty()) {
mIsAppActive = false;
notifyAppStateChanged(AppStateListener.INACTIVE);
}
ActivityTrace trace = mAliveActivities.get(activity);
if (trace != null) {
trace.stopCnt++;
}
}
@Override
public void onActivityResumed(Activity activity) {
mCurrentResumedActivity = activity;
ActivityTrace trace = mAliveActivities.get(activity);
if (trace != null) {
trace.resumeCnt++;
}
}
@Override
public void onActivityPaused(Activity activity) {
ActivityTrace trace = mAliveActivities.get(activity);
if (trace != null) {
trace.pauseCnt++;
}
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
mAliveActivities.put(activity, new ActivityTrace(activity));
}
@Override
public void onActivityDestroyed(Activity activity) {
mAliveActivities.remove(activity);
}
};
private ActivityLifecycleManager() {
}
public static ActivityLifecycleManager getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static final ActivityLifecycleManager INSTANCE = new ActivityLifecycleManager();
}
public void start(Application application) {
this.mApplication = application;
registerInnerActivityListener();
registerHomeKeyEventReceiver();
}
public void stop() {
unregisterActivityLifecycleCallbacks(mInnerActivityListener);
unregisterHomeKeyEventReceiver();
}
/**
* 注册 Activity 生命周期的回调
*
* @param callbacks Activity 生命周期的回调
*/
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callbacks) {
if (mApplication == null) {
return;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return;
}
mApplication.registerActivityLifecycleCallbacks(callbacks);
}
/**
* 取消注册 Activity 生命周期的回调
*
* @param callbacks Activity 生命周期的回调
*/
public void unregisterActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callbacks) {
if (mApplication == null) {
return;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return;
}
mApplication.unregisterActivityLifecycleCallbacks(callbacks);
}
/**
* 应用是否出于前台
*/
public boolean isAppActive() {
return mIsAppActive;
}
public void setAppActive(boolean appActive) {
mIsAppActive = appActive;
}
public Activity getCurrentActivity() {
return mCurrentResumedActivity;
}
/**
* 添加应用状态的监听
*/
public void addAppStateListener(AppStateListener listener) {
synchronized (mAppStateListeners) {
mAppStateListeners.add(listener);
}
}
/**
* 移除应用状态的监听
*
* @param listener
*/
public void removeAppStateListener(AppStateListener listener) {
synchronized (mAppStateListeners) {
mAppStateListeners.remove(listener);
}
}
/**
* 添加 home 键的事件监听
*/
public void addHomeKeyEventListener(HomeKeyEventListener listener) {
if (listener == null) {
return;
}
synchronized (mHomeKeyEventListeners) {
mHomeKeyEventListeners.add(listener);
}
}
/**
* 移除 home 键的事件监听
*/
public void removeHomeKeyEventListener(HomeKeyEventListener listener) {
if (listener == null) {
return;
}
synchronized (mHomeKeyEventListeners) {
mHomeKeyEventListeners.remove(listener);
}
}
/**
* 注册Activity生命周期的监听
*/
private void registerInnerActivityListener() {
registerActivityLifecycleCallbacks(mInnerActivityListener);
}
private void notifyAppStateChanged(int state) {
Object[] listeners = collectAppStateListeners();
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
((AppStateListener) listeners[i]).onStateChanged(state);
}
}
}
private Object[] collectAppStateListeners() {
Object[] listeners = null;
synchronized (mAppStateListeners) {
if (mAppStateListeners.size() > 0) {
listeners = mAppStateListeners.toArray();
}
}
return listeners;
}
private Object[] collectHomeKeyEventListeners() {
Object[] listeners = null;
synchronized (mHomeKeyEventListeners) {
if (mHomeKeyEventListeners.size() > 0) {
listeners = mHomeKeyEventListeners.toArray();
}
}
return listeners;
}
private void registerHomeKeyEventReceiver() {
android.content.IntentFilter filter = new android.content.IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mHomeKeyEventReceiver = new HomeKeyEventReceiver();
mApplication.registerReceiver(mHomeKeyEventReceiver, filter);
}
private void unregisterHomeKeyEventReceiver() {
mApplication.unregisterReceiver(mHomeKeyEventReceiver);
}
private void onHomeKeyPressed() {
Object[] listeners = collectHomeKeyEventListeners();
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
((HomeKeyEventListener) listeners[i]).onHomeKeyPressed();
}
}
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static abstract class DefActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
public interface AppStateListener {
int INACTIVE = 0;
int ACTIVE = 1;
/**
* App 状态的回调
*/
void onStateChanged(int state);
}
/**
* home 键的监听
*/
public interface HomeKeyEventListener {
void onHomeKeyPressed();
}
/**
* Activity 的生命周期调用痕迹
*/
static class ActivityTrace {
Activity activity;
int resumeCnt;
int pauseCnt;
int startCnt;
int stopCnt;
ActivityTrace(Activity activity) {
this.activity = activity;
}
}
private final class HomeKeyEventReceiver extends BroadcastReceiver {
private final String SYSTEM_DIALOG_REASON_KEY = "reason";
private final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
onHomeKeyPressed();
}
}
}
}
}

View File

@@ -0,0 +1,99 @@
package com.mogo.eagle.core.utilcode.util
import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import androidx.lifecycle.Lifecycle.Event
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import java.lang.ref.WeakReference
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
interface IAppStateListener {
fun onAppStateChanged(isForeground: Boolean)
}
object AppStateManager {
private val currentActivityHolder by lazy {
AtomicReference<WeakReference<Activity>>()
}
private val appStateListeners by lazy {
CopyOnWriteArrayList<IAppStateListener>()
}
private val isActive by lazy { AtomicBoolean(false) }
private val activityLifeCycleCallback = object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {
currentActivityHolder.set(WeakReference(activity))
}
override fun onActivityPaused(activity: Activity) {
currentActivityHolder.set(null)
}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
}
fun init(app: Application) {
app.registerActivityLifecycleCallbacks(activityLifeCycleCallback)
ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Event) {
if (event == Event.ON_START) {
isActive.set(true)
notifyAppStateChanged(true)
}
if (event == Event.ON_STOP) {
isActive.set(false)
notifyAppStateChanged(false)
}
}
})
}
fun isActive(): Boolean = isActive.get()
fun currentActivity() = currentActivityHolder.get()?.get()
fun registerAppStateListener(listener: IAppStateListener) {
if (appStateListeners.contains(listener)) {
return
}
appStateListeners += listener
}
fun unRegisterAppStateListener(listener: IAppStateListener) {
if (!appStateListeners.contains(listener)) {
return
}
appStateListeners -= listener
}
private fun notifyAppStateChanged(isForeground: Boolean) {
appStateListeners.forEach {
it.onAppStateChanged(isForeground)
}
}
}

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="tag_click_time" type="id" />
<item name="view_lifecycle_owner" type="id" />
</resources>

View File

@@ -43,7 +43,6 @@ dependencies {
implementation rootProject.ext.dependencies.rxjava
api rootProject.ext.dependencies.mogoaicloudrealtime
implementation rootProject.ext.dependencies.amapnavi3dmap
implementation rootProject.ext.dependencies.androidxlifecycleprocess
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogo_core_utils

View File

@@ -23,6 +23,7 @@ import com.mogo.commons.network.NetConfigUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.mogo.toast.TipDrawable;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.AppStateManager;
import com.mogo.eagle.core.utilcode.util.AppUtils;
import com.mogo.eagle.core.utilcode.util.CleanUtils;
import com.mogo.eagle.core.utilcode.util.ThreadPoolService;
@@ -49,6 +50,7 @@ public abstract class AbsMogoApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
AppStateManager.INSTANCE.init(this);
sApp = this;
FinalizeCrashFixer.fix();
initARouter();

View File

@@ -1,6 +1,8 @@
package com.mogo.commons.crash;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.AppStateManager;
import com.mogo.eagle.core.utilcode.util.IAppStateListener;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
@@ -35,19 +37,19 @@ public class FinalizeCrashFixer {
* 只有线程在运行状态才会关闭线程
*/
public static void fix() {
ProcessLifecycleOwner.get().getLifecycle().addObserver((LifecycleEventObserver) (source, event) -> {
if (event == Lifecycle.Event.ON_START) {
//前后台则重新反射关闭一遍,避免线程被再次开启
Logger.d("FinalizeCrashFixer", "--- 切换到前台 ---");
realFix();
AppStateManager.INSTANCE.registerAppStateListener(new IAppStateListener() {
@Override
public void onAppStateChanged(boolean isForeground) {
if (isForeground) {
//前后台则重新反射关闭一遍,避免线程被再次开启
Logger.d("FinalizeCrashFixer", "--- 切换到前台 ---");
realFix();
} else {
//前后台则重新反射关闭一遍,避免线程被再次开启
Logger.d("FinalizeCrashFixer", "--- 切换到后台 ---");
realFix();
}
}
if (event == Lifecycle.Event.ON_STOP) {
//前后台则重新反射关闭一遍,避免线程被再次开启
Logger.d("FinalizeCrashFixer", "--- 切换到后台 ---");
realFix();
}
});
}

View File

@@ -5,6 +5,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.module.extensions.R;
import com.mogo.eagle.core.data.constants.MogoServicePaths;

View File

@@ -72,7 +72,6 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
protected IMogoStatusManager mMogoStatusManager;
protected View mEntrance;
protected View mEventPanel;
protected FrameLayout mFloatingLayout;
protected View mCoverUpLayout;
@@ -95,7 +94,6 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
getWindow().setBackgroundDrawable(null);
mEntrance = findViewById(R.id.module_main_id_entrance_fragment_container);
mEventPanel = findViewById(R.id.module_main_id_event_panel_fragment_container);
mFloatingLayout = findViewById(R.id.module_main_id_floating_view);
mCoverUpLayout = findViewById(R.id.module_main_id_cover_up);
@@ -119,14 +117,12 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
// 隐藏布局
protected void hideLayout() {
mEntrance.setVisibility(View.GONE);
mEventPanel.setVisibility(View.GONE);
mFloatingLayout.setVisibility(View.GONE);
}
// 显示布局
protected void showLayout() {
mEntrance.setVisibility(View.VISIBLE);
mEventPanel.setVisibility(View.VISIBLE);
mFloatingLayout.setVisibility(View.VISIBLE);
}
@@ -182,8 +178,6 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
if (mServiceApis == null) {
mServiceApis = MogoApisHandler.getInstance().getApis();
}
//mServiceApis.getShareManager().resetContext(this);
mMogoStatusManager = mServiceApis.getStatusManagerApi();
mMogoStatusManager.setMainPageLaunchedStatus(TAG, true);
AutopilotServiceManage.getInstance().init(getContext());
@@ -275,7 +269,7 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
protected void loadContainerModules() {
MogoModulesManager.getInstance().loadEntrancesModule(R.id.module_main_id_entrance_fragment_container);
MogoModulesManager.getInstance().loadEventPanelModule(R.id.module_main_id_event_panel_fragment_container);
//MogoModulesManager.getInstance().loadEventPanelModule(R.id.module_main_id_event_panel_fragment_container);
}
@Override
@@ -355,7 +349,9 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
@Override
protected void onStop() {
super.onStop();
mMogoStatusManager.setMainPageIsBackgroundStatus(TAG, true);
if (mMogoStatusManager != null) {
mMogoStatusManager.setMainPageIsBackgroundStatus(TAG, true);
}
if (shouldCloseADASPanelWhenPause()) {
mServiceApis.getAdasControllerApi().closeADAS();
}

View File

@@ -180,7 +180,7 @@ public class SchemeIntent implements IMogoStatusChangedListener {
* */
private void handleShowEventPanel(int item) {
Logger.d(TAG, "语音打开事件面板" + item);
mApis.getEventPanelManager().showPanelWithSelectedItem(item);
//mApis.getEventPanelManager().showPanelWithSelectedItem(item);
}
@Override

View File

@@ -39,14 +39,6 @@ public interface MogoModulesHandler {
*/
void loadBaseModule();
/**
* 加载事件面板
*
* @param containerId
*/
void loadEventPanelModule(int containerId);
/**
* 释放各个模块资源
*/

View File

@@ -137,12 +137,6 @@ public class MogoModulesManager implements MogoModulesHandler {
addFragment( provider, containerId );
}
@Override
public void loadEventPanelModule( int containerId ) {
IMogoModuleProvider provider = MogoApisHandler.getInstance().getApis().getEventPanelManager();
addFragment( provider, containerId );
}
@Override
public void loadBaseModule() {
List< MogoModule > baseModules = MogoModulePaths.getBaseModules();

View File

@@ -61,15 +61,15 @@
android:layout_height="match_parent" />
<!-- 右边事件面板 -->
<FrameLayout
android:id="@+id/module_main_id_event_panel_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/module_main_id_entrance_fragment_container_marginLeft"
android:paddingLeft="@dimen/module_main_event_panel_fragment_paddingLeft"
android:paddingTop="@dimen/module_main_event_panel_fragment_paddingTop"
android:paddingRight="@dimen/module_main_event_panel_fragment_paddingRight"
android:paddingBottom="@dimen/module_main_event_panel_fragment_paddingBottom" />
<!-- <FrameLayout-->
<!-- android:id="@+id/module_main_id_event_panel_fragment_container"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_marginLeft="@dimen/module_main_id_entrance_fragment_container_marginLeft"-->
<!-- android:paddingLeft="@dimen/module_main_event_panel_fragment_paddingLeft"-->
<!-- android:paddingTop="@dimen/module_main_event_panel_fragment_paddingTop"-->
<!-- android:paddingRight="@dimen/module_main_event_panel_fragment_paddingRight"-->
<!-- android:paddingBottom="@dimen/module_main_event_panel_fragment_paddingBottom" />-->
<!-- 目的地车友 -->
<FrameLayout

View File

@@ -107,7 +107,6 @@ abstract class StatusChangedAdapter implements IMogoStatusChangedListener {
}
};
}
MogoApisHandler.getInstance().getApis().getEventPanelManager().hidePanel();
if (mCarsChattingProvider == null) {
mCarsChattingProvider = (ICarsChattingProvider) ARouter.getInstance().build(CallChattingProviderConstant.CAR_CALL_PROVIDER).navigation();
}

View File

@@ -9,7 +9,6 @@ import com.mogo.service.cloud.location.IMogoLocationInfoService;
import com.mogo.service.cloud.passport.IMogoPassportManager;
import com.mogo.service.cloud.socket.IMogoSocketManager;
import com.mogo.service.datamanager.IMogoDataManager;
import com.mogo.service.eventpanel.IEventPanelProvider;
import com.mogo.service.fragmentmanager.IMogoFragmentManager;
import com.mogo.service.imageloader.IMogoImageloader;
import com.mogo.service.intent.IMogoIntentManager;
@@ -147,13 +146,6 @@ public interface IMogoServiceApis extends IProvider {
*/
IMogoMarkerService getMarkerService();
/**
* 获取事件面板manager
*
* @return eventPanelProvider
*/
IEventPanelProvider getEventPanelManager();
/**
* 获取位置上报服务接口
*

View File

@@ -1,27 +0,0 @@
package com.mogo.service.eventpanel;
import com.mogo.service.module.IMogoModuleProvider;
/**
* 事件面板provider接口
*
* @author tongchenfei
*/
public interface IEventPanelProvider extends IMogoModuleProvider {
/**
* 显示面板并选中某个item
*/
void showPanelWithSelectedItem(int item);
/**
* 显示面板,默认选中第一个
*/
void showPanel();
/**
* 隐藏面板
*/
void hidePanel();
}

View File

@@ -14,7 +14,6 @@ import com.mogo.service.cloud.location.IMogoLocationInfoService;
import com.mogo.service.cloud.passport.IMogoPassportManager;
import com.mogo.service.cloud.socket.IMogoSocketManager;
import com.mogo.service.datamanager.IMogoDataManager;
import com.mogo.service.eventpanel.IEventPanelProvider;
import com.mogo.service.fragmentmanager.IMogoFragmentManager;
import com.mogo.service.imageloader.IMogoImageloader;
import com.mogo.service.impl.analytics.impl.MogoAnalyticsImpl;
@@ -133,11 +132,6 @@ public class MogoServiceApis implements IMogoServiceApis {
return getApiInstance(IMogoMarkerService.class, MogoServicePaths.PATH_MARKER_SERVICE);
}
@Override
public IEventPanelProvider getEventPanelManager() {
return getApiInstance(IEventPanelProvider.class, MogoServicePaths.PATH_EVENT_PANEL);
}
@Override
public IMogoLocationInfoService getLocationInfoApi() {
return getApiInstance(IMogoLocationInfoService.class, MogoServicePaths.PATH_LOCATION_INFO);