@@ -70,6 +70,7 @@ dependencies {
|
||||
implementation project(':core:mogo-core-res')
|
||||
implementation project(':core:mogo-core-data')
|
||||
implementation project(':core:mogo-core-utils')
|
||||
implementation project(':core:mogo-core-res')
|
||||
implementation project(':core:mogo-core-function-api')
|
||||
implementation project(':core:mogo-core-function-call')
|
||||
// implementation project(':core:mogo-core-res')
|
||||
|
||||
@@ -8,16 +8,19 @@ import android.view.WindowManager
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData
|
||||
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
|
||||
import com.mogo.eagle.core.function.call.monitor.CallerMonitorManager
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
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.notice.NoticeBannerView
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeFloatView
|
||||
import com.mogo.eagle.core.function.hmi.ui.camera.CameraListView
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
|
||||
import com.mogo.module.common.enums.EventTypeEnum
|
||||
import com.mogo.utils.logger.Logger
|
||||
@@ -32,9 +35,15 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
MoGoWarningContract.View {
|
||||
|
||||
var mWarningFloat: WarningFloat.Builder? = null
|
||||
private var cameraListView: CameraListView? = null
|
||||
private var cameraViewFloat: WarningFloat.Builder? = null
|
||||
|
||||
override fun initViews() {
|
||||
|
||||
ivCameraIcon.setOnClickListener {
|
||||
if (cameraViewFloat == null) {
|
||||
showCameraList(CallerMonitorManager.getCameraList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
@@ -61,7 +70,6 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
viewCheckStatus.visibility = visibility
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 展示VR下V2X预警
|
||||
*
|
||||
@@ -289,9 +297,80 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
*/
|
||||
override fun showNoticeNormal(normalData: NoticeNormalData) {
|
||||
if (floatView == null) {
|
||||
floatView = this.getContext()?.let { NoticeFloatView(it) }
|
||||
floatView = this.context?.let { NoticeFloatView(it) }
|
||||
}
|
||||
floatView?.pushBeanChanged(normalData)
|
||||
}
|
||||
|
||||
private fun showCameraList(cameraList: List<Camera>?) {
|
||||
context?.let {
|
||||
if (cameraViewFloat == null) {
|
||||
if (cameraListView == null) {
|
||||
cameraListView = CameraListView(it)
|
||||
cameraListView!!.updateCameraData(cameraList)
|
||||
}
|
||||
cameraListView!!.setClickListener(object : CameraListView.ClickListener {
|
||||
override fun onClose(v: View) {
|
||||
dismissFloatView()
|
||||
}
|
||||
|
||||
override fun onShowLive(isShow: Boolean) {
|
||||
when {
|
||||
isShow -> ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_selected)
|
||||
else -> ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor)
|
||||
}
|
||||
}
|
||||
})
|
||||
cameraViewFloat = WarningFloat.with(it)
|
||||
.setTag("CameraListFloat")
|
||||
.setLayout(cameraListView!!)
|
||||
.setSidePattern(SidePattern.RIGHT)
|
||||
.setLocation(1742, 280)
|
||||
.setImmersionStatusBar(true)
|
||||
.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)
|
||||
})
|
||||
.addWarningStatusListener(object : IMoGoWarningStatusListener {
|
||||
override fun onDismiss() {
|
||||
cameraViewFloat = null
|
||||
cameraListView = null
|
||||
ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor)
|
||||
}
|
||||
})
|
||||
.show()
|
||||
} else {
|
||||
cameraViewFloat?.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun dismissFloatView() {
|
||||
cameraViewFloat?.let {
|
||||
WarningFloat.dismiss(it.config.floatTag, false)
|
||||
cameraViewFloat = null
|
||||
cameraListView = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.camera
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView.Adapter
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
|
||||
class CameraListAdapter: Adapter<CameraListAdapter.CameraListHolder> {
|
||||
|
||||
private var context: Context? = null
|
||||
var data: List<Camera>? = null
|
||||
private var clickListener: View.OnClickListener? = null
|
||||
|
||||
constructor(context: Context, data: List<Camera>?, clickListener: View.OnClickListener? = null) {
|
||||
this.context = context
|
||||
this.data = data
|
||||
this.clickListener = clickListener
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CameraListHolder {
|
||||
var view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_camera_info, parent, false)
|
||||
return CameraListHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CameraListHolder, position: Int) {
|
||||
data?.let {
|
||||
holder.cameraInfo.text = with(it[position]) {
|
||||
"${roadName}${crossingName}"
|
||||
}
|
||||
holder.bottomLine.visibility = if (it.size - 1 == position) View.INVISIBLE else View.VISIBLE
|
||||
if (position == 0) {
|
||||
// 顺义可直接查看摄像头视频的地址,用来测试
|
||||
holder.itemView.tag = "https://video.zhidaohulian.com/live/origin_13_48.flv?txSecret=397b1296eb548c737871fca242ff7ec5&txTime=6AABBEB2"
|
||||
} else {
|
||||
holder.itemView.tag = it[position].flvUrl
|
||||
}
|
||||
holder.itemView.setOnClickListener(clickListener)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = data?.size ?: 0
|
||||
|
||||
class CameraListHolder : ViewHolder {
|
||||
var cameraInfo: TextView = itemView.findViewById(R.id.tvCameraInfo)
|
||||
var bottomLine: View = itemView.findViewById(R.id.viewBottomLine)
|
||||
|
||||
constructor(itemView: View): super(itemView)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.camera
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
|
||||
import com.shuyu.gsyvideoplayer.GSYVideoManager
|
||||
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
|
||||
import kotlinx.android.synthetic.main.view_camera_list.view.*
|
||||
import java.lang.Exception
|
||||
|
||||
/**
|
||||
* @author ChenFufeng
|
||||
* 行车超视距摄像头列表View
|
||||
*/
|
||||
class CameraListView : FrameLayout {
|
||||
|
||||
private val TAG = "CameraListView"
|
||||
|
||||
var cameraInfoList = ArrayList<Camera>()
|
||||
private var clickListener: ClickListener? = null
|
||||
private val gsyVideoOptionBuilder by lazy {
|
||||
GSYVideoOptionBuilder()
|
||||
}
|
||||
private val spannableStringBuilder by lazy {
|
||||
SpannableStringBuilder("当前设备暂无信号,切换其他摄像头 3S")
|
||||
}
|
||||
|
||||
private val spannableStringBuilder2 by lazy {
|
||||
SpannableStringBuilder("当前路口信号丢失,3S 后自动关闭")
|
||||
}
|
||||
private var isCloseStatus = true
|
||||
private val valueAnimator by lazy {
|
||||
ValueAnimator.ofInt(3, 0)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
)
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_camera_list, this, true)
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
rvCameraList.layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
rvCameraList.adapter = CameraListAdapter(context, cameraInfoList) {
|
||||
it.tag?.let { tag ->
|
||||
isCloseStatus = false
|
||||
showLiveView()
|
||||
clickListener?.onShowLive(true)
|
||||
val flvUrl = tag as String
|
||||
gsyVideoOptionBuilder.setUrl(flvUrl)
|
||||
.setCacheWithPlay(false)
|
||||
.setAutoFullWithSize(false)
|
||||
.setPlayTag(TAG).build(svpPlayer)
|
||||
svpPlayer.startButton.performClick()
|
||||
}
|
||||
}
|
||||
ivCloseIcon.setOnClickListener {
|
||||
when {
|
||||
isCloseStatus -> clickListener?.onClose(it)
|
||||
else -> {
|
||||
hideLiveView()
|
||||
isCloseStatus = true
|
||||
}
|
||||
}
|
||||
clickListener?.onShowLive(false)
|
||||
}
|
||||
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
|
||||
svpPlayer.setPlayListener(object : SimpleVideoPlayer.PlayListener {
|
||||
override fun onPlayEvent(event: Int) {
|
||||
when (event) {
|
||||
SimpleVideoPlayer.PLAY_EVT_PLAY_LOADING -> {
|
||||
|
||||
}
|
||||
SimpleVideoPlayer.PLAY_EVT_PLAY_BEGIN -> {
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
else -> {
|
||||
showNoSignalView()
|
||||
valueAnimator.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
// 后期可改为动态获取3s起始位置,暂时写死
|
||||
spannableStringBuilder.setSpan(
|
||||
ForegroundColorSpan(Color.parseColor("#2966EE")),
|
||||
spannableStringBuilder.length - 2,
|
||||
spannableStringBuilder.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
spannableStringBuilder2.setSpan(
|
||||
ForegroundColorSpan(Color.parseColor("#2966EE")),
|
||||
spannableStringBuilder2.length - 8,
|
||||
spannableStringBuilder2.length - 6,
|
||||
Spanned.SPAN_INCLUSIVE_INCLUSIVE
|
||||
)
|
||||
valueAnimator.duration = 3000
|
||||
valueAnimator.addUpdateListener {
|
||||
when (val currentValue = it.animatedValue as Int) {
|
||||
0 -> {
|
||||
if (cameraInfoList.isNullOrEmpty()) {
|
||||
clickListener?.onClose(ivSignalIcon)
|
||||
} else {
|
||||
hideNoSignalView()
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
if (cameraInfoList.isNullOrEmpty()) {
|
||||
spannableStringBuilder2.replace(9, 10, currentValue.toString())
|
||||
tvTipContent.text = spannableStringBuilder2
|
||||
} else {
|
||||
spannableStringBuilder.replace(17, 18, currentValue.toString())
|
||||
tvTipContent.text = spannableStringBuilder
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateCameraData(cameraInfoList: List<Camera>?) {
|
||||
if (cameraInfoList.isNullOrEmpty()) {
|
||||
showNoSignalView()
|
||||
valueAnimator.start()
|
||||
} else {
|
||||
this.cameraInfoList.clear()
|
||||
this.cameraInfoList.addAll(cameraInfoList)
|
||||
}
|
||||
}
|
||||
|
||||
fun setClickListener(clickListener: ClickListener) {
|
||||
this.clickListener = clickListener
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun refreshCameraList() {
|
||||
rvCameraList.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
stopLive()
|
||||
valueAnimator.cancel()
|
||||
}
|
||||
|
||||
private fun stopLive() {
|
||||
svpPlayer.removeAllViews()
|
||||
try {
|
||||
GSYVideoManager.releaseAllVideos()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLiveView() {
|
||||
tvCameraTitle.visibility = View.GONE
|
||||
rvCameraList.visibility = View.GONE
|
||||
svpPlayer.visibility = View.VISIBLE
|
||||
progressBar.visibility = View.VISIBLE
|
||||
ivCloseIcon.setBackgroundResource(R.drawable.icon_back)
|
||||
}
|
||||
|
||||
private fun hideLiveView() {
|
||||
tvCameraTitle.visibility = View.VISIBLE
|
||||
rvCameraList.visibility = View.VISIBLE
|
||||
svpPlayer.visibility = View.GONE
|
||||
progressBar.visibility = View.GONE
|
||||
stopLive()
|
||||
ivCloseIcon.setBackgroundResource(R.drawable.icon_close_nor)
|
||||
}
|
||||
|
||||
private fun showNoSignalView() {
|
||||
ivSignalIcon.visibility = View.VISIBLE
|
||||
tvTipContent.visibility = View.VISIBLE
|
||||
tvCameraTitle.visibility = View.GONE
|
||||
rvCameraList.visibility = View.GONE
|
||||
svpPlayer.visibility = View.GONE
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun hideNoSignalView() {
|
||||
ivSignalIcon.visibility = View.GONE
|
||||
tvTipContent.visibility = View.GONE
|
||||
hideLiveView()
|
||||
clickListener?.onShowLive(false)
|
||||
}
|
||||
|
||||
interface ClickListener {
|
||||
fun onShowLive(isShow: Boolean)
|
||||
fun onClose(v: View)
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.util.Log
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
@@ -85,5 +85,15 @@
|
||||
app:layout_constraintStart_toEndOf="@+id/viewPerspectiveSwitch"
|
||||
app:layout_goneMarginStart="50px" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivCameraIcon"
|
||||
android:layout_width="130px"
|
||||
android:layout_height="130px"
|
||||
app:layout_constraintEnd_toStartOf="@id/viewTrafficLightVr"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="38px"
|
||||
android:layout_marginEnd="30px"
|
||||
android:background="@drawable/icon_camera_nor"
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="130px"
|
||||
android:paddingStart="64px"
|
||||
android:paddingEnd="64px"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivCameraIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/icon_rideo_nor"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCameraInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="53px"
|
||||
app:layout_constraintStart_toEndOf="@id/ivCameraIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginStart="28px"
|
||||
android:maxWidth="570px"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textSize="38px"
|
||||
android:textColor="#FFFFFF"
|
||||
tools:text="衡州大道路口大道路口道路口大衡州大道路口大道路口道路口大"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:id="@+id/viewBottomLine"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:background="#6A78BB"
|
||||
/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.eagle.core.widget.RoundConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:roundLayoutRadius="30px"
|
||||
android:minWidth="777px"
|
||||
android:minHeight="485px"
|
||||
android:background="@color/notice_check_dialog_bg_color">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCameraTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24px"
|
||||
android:text="视频设备"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="42px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvCameraList"
|
||||
android:layout_width="778px"
|
||||
android:layout_height="664px"
|
||||
android:layout_marginTop="24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvCameraTitle" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivSignalIcon"
|
||||
android:layout_width="190px"
|
||||
android:layout_height="142px"
|
||||
android:background="@drawable/icon_signal"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="81px"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTipContent"
|
||||
android:layout_width="448px"
|
||||
android:layout_height="100px"
|
||||
android:text="当前设备暂无信号,切换其他摄像头 3S"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/ivSignalIcon"
|
||||
android:layout_marginTop="60px"
|
||||
android:gravity="center"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="36px"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
|
||||
android:id="@+id/svpPlayer"
|
||||
android:layout_width="778px"
|
||||
android:layout_height="487px"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<androidx.core.widget.ContentLoadingProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivCloseIcon"
|
||||
android:layout_width="86px"
|
||||
android:layout_height="86px"
|
||||
android:background="@drawable/icon_close_nor"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginStart="30px"
|
||||
android:layout_marginTop="17px"
|
||||
/>
|
||||
|
||||
</com.mogo.eagle.core.widget.RoundConstraintLayout>
|
||||
@@ -56,11 +56,15 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.mogo_core_res
|
||||
implementation rootProject.ext.dependencies.mogo_core_data
|
||||
implementation rootProject.ext.dependencies.mogo_core_function_api
|
||||
implementation rootProject.ext.dependencies.mogo_core_function_call
|
||||
implementation rootProject.ext.dependencies.modulecommon
|
||||
} else {
|
||||
implementation project(':core:mogo-core-utils')
|
||||
implementation project(':core:mogo-core-res')
|
||||
implementation project(':core:mogo-core-data')
|
||||
implementation project(':core:mogo-core-function-api')
|
||||
implementation project(':core:mogo-core-function-call')
|
||||
implementation project(':modules:mogo-module-common')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.mogo.eagle.core.function.monitoring
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.function.monitoring.net.CameraListServices
|
||||
import com.mogo.module.common.MogoApisHandler
|
||||
import com.mogo.module.common.constants.HostConst
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class CronTaskManager {
|
||||
private val TAG = "CronTaskManager"
|
||||
private val CRON_TASK_TYPE = 1011
|
||||
|
||||
private val netWork by lazy {
|
||||
MogoApisHandler.getInstance().apis.networkApi
|
||||
}
|
||||
private var disposable: Disposable? = null
|
||||
private var cameraList: List<Camera>? = null
|
||||
|
||||
private val cronHandler: Handler = object : Handler(Looper.getMainLooper()) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
when (msg.what) {
|
||||
CRON_TASK_TYPE -> {
|
||||
removeMessages(CRON_TASK_TYPE)
|
||||
requestCameraList()
|
||||
sendEmptyMessageDelayed(CRON_TASK_TYPE, 10000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestCameraList() {
|
||||
// 衡阳可直播的摄像头有限,先写死roadId便于调试
|
||||
disposable = netWork.create(CameraListServices::class.java, HostConst.CAMERA_STREAM_HOST)
|
||||
.getCameraList("10849")
|
||||
.subscribeOn(Schedulers.io())
|
||||
.map { cameraListInfo ->
|
||||
cameraListInfo.result?.crossings?.flatMap { crossing ->
|
||||
crossing.cameras.filter { camera ->
|
||||
!camera.flvUrl.isNullOrEmpty() && !camera.rtmpUrl.isNullOrEmpty()
|
||||
}
|
||||
} ?: ArrayList()
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
cameraList = it
|
||||
}, {
|
||||
it.printStackTrace()
|
||||
})
|
||||
}
|
||||
|
||||
fun startCronTask() {
|
||||
cronHandler.sendEmptyMessageDelayed(CRON_TASK_TYPE, 0)
|
||||
}
|
||||
|
||||
fun getCameraList() = cameraList
|
||||
|
||||
fun clear() {
|
||||
disposable?.dispose()
|
||||
cronHandler.removeMessages(CRON_TASK_TYPE)
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,22 @@ import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.eagle.core.data.camera.Camera;
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths;
|
||||
import com.mogo.eagle.core.function.api.monitoring.IMoGoMonitoringProvider;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
* @date 2021/10/29 11:09 上午
|
||||
*/
|
||||
@Route(path = MogoServicePaths.PATH_AI_MONITORING)
|
||||
public class MoGoMonitoringProvider implements IMoGoMonitoringProvider {
|
||||
|
||||
public String TAG = "MoGoMonitoringProvider";
|
||||
private CronTaskManager mCronTaskManager;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
@@ -26,11 +31,18 @@ public class MoGoMonitoringProvider implements IMoGoMonitoringProvider {
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
Logger.d(TAG, "初始化……");
|
||||
mCronTaskManager = new CronTaskManager();
|
||||
mCronTaskManager.startCronTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Camera> getCameraList() {
|
||||
return mCronTaskManager.getCameraList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
|
||||
mCronTaskManager.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mogo.eagle.core.function.monitoring.net
|
||||
|
||||
import com.mogo.eagle.core.data.camera.CameraListInfo
|
||||
import io.reactivex.Single
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface CameraListServices {
|
||||
@GET("/yycp-smartTransportationAiCloud-service/eagle/device/list")
|
||||
fun getCameraList(@Query("roadId") roadId: String?): Single<CameraListInfo?>
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.mogo.eagle.core.data.camera
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.mogo.eagle.core.data.BaseData
|
||||
import java.io.Serializable
|
||||
|
||||
|
||||
@Keep
|
||||
data class CameraListInfo (
|
||||
@SerializedName("result")
|
||||
var result: Result?
|
||||
): BaseData()
|
||||
|
||||
@Keep
|
||||
data class Result(
|
||||
@SerializedName("crossings")
|
||||
var crossings: List<Crossing>
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class Crossing(
|
||||
@SerializedName("cameras")
|
||||
var cameras: List<Camera>,
|
||||
@SerializedName("id")
|
||||
var id: Int,
|
||||
@SerializedName("lat")
|
||||
var lat: Double,
|
||||
@SerializedName("lights")
|
||||
var lights: List<Any>,
|
||||
@SerializedName("lon")
|
||||
var lon: Double
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class Camera(
|
||||
@SerializedName("areaName")
|
||||
var areaName: String,
|
||||
@SerializedName("bindingStat")
|
||||
var bindingStat: String,
|
||||
@SerializedName("category")
|
||||
var category: String,
|
||||
@SerializedName("cityName")
|
||||
var cityName: String,
|
||||
@SerializedName("createTime")
|
||||
var createTime: Long,
|
||||
@SerializedName("creator")
|
||||
var creator: String,
|
||||
@SerializedName("crossingId")
|
||||
var crossingId: Int,
|
||||
@SerializedName("crossingName")
|
||||
var crossingName: String,
|
||||
@SerializedName("desc")
|
||||
var desc: String,
|
||||
@SerializedName("flvUrl")
|
||||
var flvUrl: String?,
|
||||
@SerializedName("heading")
|
||||
var heading: Int,
|
||||
@SerializedName("headingDesc")
|
||||
var headingDesc: Any?,
|
||||
@SerializedName("id")
|
||||
var id: String,
|
||||
@SerializedName("ip")
|
||||
var ip: String,
|
||||
@SerializedName("lat")
|
||||
var lat: Double,
|
||||
@SerializedName("lon")
|
||||
var lon: Double,
|
||||
@SerializedName("mac")
|
||||
var mac: String,
|
||||
@SerializedName("name")
|
||||
var name: String,
|
||||
@SerializedName("proviceName")
|
||||
var proviceName: String,
|
||||
@SerializedName("roadName")
|
||||
var roadName: String,
|
||||
@SerializedName("rtmpUrl")
|
||||
var rtmpUrl: String?,
|
||||
@SerializedName("sn")
|
||||
var sn: String,
|
||||
@SerializedName("stat")
|
||||
var stat: String,
|
||||
@SerializedName("subCategory")
|
||||
var subCategory: Any?
|
||||
): Serializable
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.mogo.eagle.core.function.api.hmi.warning
|
||||
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package com.mogo.eagle.core.function.api.monitoring;
|
||||
|
||||
import com.mogo.eagle.core.data.camera.Camera;
|
||||
import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
* @date 2021/10/29 10:35 上午
|
||||
* 超视距功能,路测摄像头,前车摄像头监控
|
||||
*/
|
||||
public interface IMoGoMonitoringProvider extends IMoGoFunctionServerProvider {
|
||||
|
||||
List<Camera> getCameraList();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.mogo.eagle.core.function.call.hmi
|
||||
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
@@ -173,5 +174,4 @@ object CallerHmiManager : CallerBase() {
|
||||
fun showNormalBanner(noticeNormal: NoticeNormalData) {
|
||||
waringProviderApi.showNoticeNormalData(noticeNormal)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.mogo.eagle.core.function.call.monitor
|
||||
|
||||
import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.function.api.monitoring.IMoGoMonitoringProvider
|
||||
import com.mogo.eagle.core.function.call.base.CallerBase
|
||||
|
||||
object CallerMonitorManager {
|
||||
private val providerApi: IMoGoMonitoringProvider
|
||||
get() = CallerBase.getApiInstance(
|
||||
IMoGoMonitoringProvider::class.java,
|
||||
MogoServicePaths.PATH_AI_MONITORING)
|
||||
|
||||
fun getCameraList(): List<Camera>? {
|
||||
return providerApi.cameraList
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import android.util.AttributeSet;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* author : donghongyu
|
||||
@@ -49,6 +51,7 @@ public class RoundConstraintLayout extends ConstraintLayout {
|
||||
|
||||
private void setRoundPath() {
|
||||
//添加一个圆角矩形到path中, 如果要实现任意形状的View, 只需要手动添加path就行
|
||||
roundPath.reset();
|
||||
roundPath.addRoundRect(rectF, roundLayoutRadius, roundLayoutRadius, Path.Direction.CW);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ public class HostConst {
|
||||
public static final String TMC_HOST = "http://dzt-tmcServer.zhidaozhixing.com";
|
||||
public static final String IM_SOCKET_DOMAIN = "dzt-im.zhidaozhixing.com";
|
||||
public static final String WEBSOCKET_DOMAIN = "dzt-Instant.zhidaozhixing.com";
|
||||
public static final String CAMERA_STREAM_HOST = "http://dzt-smartTransportationAiCloud.zhidaozhixing.com";
|
||||
|
||||
public static final String SOCKET_CENTER_DOMAIN = "socketRegion";
|
||||
|
||||
|
||||