diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
index 4d41ff1..983505d 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
@@ -263,6 +263,10 @@
}
binding.deleteTaskButton.setOnClickListener {
+ if (selectedItems.isEmpty()) {
+ "请先勾选要批量删除的任务".show(requireContext())
+ return@setOnClickListener
+ }
val ids = ArrayList()
selectedItems.forEach { task ->
ids.add(task.id)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
index 4d41ff1..983505d 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
@@ -263,6 +263,10 @@
}
binding.deleteTaskButton.setOnClickListener {
+ if (selectedItems.isEmpty()) {
+ "请先勾选要批量删除的任务".show(requireContext())
+ return@setOnClickListener
+ }
val ids = ArrayList()
selectedItems.forEach { task ->
ids.add(task.id)
diff --git a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
index a2a0c30..82e7be5 100644
--- a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
@@ -1,6 +1,8 @@
package com.casic.br.ktd.view
+import android.content.res.Configuration
import android.os.Bundle
+import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.amap.api.maps.CoordinateConverter
@@ -19,10 +21,18 @@
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.PageNavigationManager
import com.pengxh.kt.lite.vm.LoadState
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
class AlarmDetailActivity : KotlinBaseActivity() {
+ private val kTag = "AlarmDetailActivity"
private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
override fun initEvent() {
@@ -32,6 +42,10 @@
PageNavigationManager.addActivity(this)
val alarmId = intent.getStringExtra(Constant.INTENT_PARAM)!!
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
alarmViewModel.getAlarmDetail(alarmId)
alarmViewModel.alarmDetail.observe(this) {
@@ -87,6 +101,39 @@
} else {
binding.emptyImageView.visibility = View.GONE
binding.videoPlayerView.visibility = View.VISIBLE
+
+ val videoPath = model.alarmVideo.combineImagePath()
+ Log.d(kTag, "initOnCreate => $videoPath")
+ val videoOption = GSYVideoOptionBuilder()
+ videoOption.setIsTouchWiget(true)
+ .setRotateViewAuto(false)
+ .setLockLand(false)
+ .setAutoFullWithSize(true)
+ .setShowFullAnimation(false)
+ .setNeedLockFull(true)
+ .setUrl(videoPath)
+ .setCacheWithPlay(false)
+ .setVideoTitle(model.taskName)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onPrepared(url: String, vararg objects: Any) {
+ super.onPrepared(url, *objects)
+ //开始播放了才能旋转和全屏
+ orientationUtils.isEnable = true
+ isPlay = true
+ }
+
+ override fun onQuitFullscreen(url: String, vararg objects: Any) {
+ super.onQuitFullscreen(url, *objects)
+ orientationUtils.backToProtVideo()
+ }
+ }).setLockClickListener { _, lock ->
+ orientationUtils.isEnable = !lock
+ }.build(binding.videoPlayerView)
+ binding.videoPlayerView.fullscreenButton.setOnClickListener {
+ //直接横屏
+ orientationUtils.resolveByClick()
+ binding.videoPlayerView.startWindowFullscreen(this, true, true)
+ }
}
}
}
@@ -112,4 +159,46 @@
override fun setupTopBarLayout() {
ImmersionBar.with(this).statusBarDarkFont(true).init()
}
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
index 4d41ff1..983505d 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
@@ -263,6 +263,10 @@
}
binding.deleteTaskButton.setOnClickListener {
+ if (selectedItems.isEmpty()) {
+ "请先勾选要批量删除的任务".show(requireContext())
+ return@setOnClickListener
+ }
val ids = ArrayList()
selectedItems.forEach { task ->
ids.add(task.id)
diff --git a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
index a2a0c30..82e7be5 100644
--- a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
@@ -1,6 +1,8 @@
package com.casic.br.ktd.view
+import android.content.res.Configuration
import android.os.Bundle
+import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.amap.api.maps.CoordinateConverter
@@ -19,10 +21,18 @@
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.PageNavigationManager
import com.pengxh.kt.lite.vm.LoadState
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
class AlarmDetailActivity : KotlinBaseActivity() {
+ private val kTag = "AlarmDetailActivity"
private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
override fun initEvent() {
@@ -32,6 +42,10 @@
PageNavigationManager.addActivity(this)
val alarmId = intent.getStringExtra(Constant.INTENT_PARAM)!!
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
alarmViewModel.getAlarmDetail(alarmId)
alarmViewModel.alarmDetail.observe(this) {
@@ -87,6 +101,39 @@
} else {
binding.emptyImageView.visibility = View.GONE
binding.videoPlayerView.visibility = View.VISIBLE
+
+ val videoPath = model.alarmVideo.combineImagePath()
+ Log.d(kTag, "initOnCreate => $videoPath")
+ val videoOption = GSYVideoOptionBuilder()
+ videoOption.setIsTouchWiget(true)
+ .setRotateViewAuto(false)
+ .setLockLand(false)
+ .setAutoFullWithSize(true)
+ .setShowFullAnimation(false)
+ .setNeedLockFull(true)
+ .setUrl(videoPath)
+ .setCacheWithPlay(false)
+ .setVideoTitle(model.taskName)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onPrepared(url: String, vararg objects: Any) {
+ super.onPrepared(url, *objects)
+ //开始播放了才能旋转和全屏
+ orientationUtils.isEnable = true
+ isPlay = true
+ }
+
+ override fun onQuitFullscreen(url: String, vararg objects: Any) {
+ super.onQuitFullscreen(url, *objects)
+ orientationUtils.backToProtVideo()
+ }
+ }).setLockClickListener { _, lock ->
+ orientationUtils.isEnable = !lock
+ }.build(binding.videoPlayerView)
+ binding.videoPlayerView.fullscreenButton.setOnClickListener {
+ //直接横屏
+ orientationUtils.resolveByClick()
+ binding.videoPlayerView.startWindowFullscreen(this, true, true)
+ }
}
}
}
@@ -112,4 +159,46 @@
override fun setupTopBarLayout() {
ImmersionBar.with(this).statusBarDarkFont(true).init()
}
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
index 811e69d..b25a889 100644
--- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
@@ -7,6 +7,8 @@
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Environment
import android.os.Handler
import android.os.Message
import android.util.Log
@@ -127,6 +129,9 @@
//甲烷浓度阈值
private var gasAlarmRule = 1000
+ //是否正在抓取视频
+ private var isRecordingVideo = false
+
override fun initViewBinding(): ActivityInspectionBinding {
return ActivityInspectionBinding.inflate(layoutInflater)
}
@@ -204,20 +209,39 @@
lng = aMapLocation.latitude.toString()
address = aMapLocation.address
speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat()
- alarmViewModel.addAlarm(
- taskId,
- deviceId,
- "甲烷浓度超过阈值",
- lat,
- lng,
- System.currentTimeMillis().timestampToCompleteDate(),
- gasAlarmRule.toString(),
- it.data,
- "0",
- "1",
- "",
- dataModel?.methane.toString(),
- )
+
+ if (it.data.endsWith(".png")) {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ it.data,
+ "0",
+ "1",
+ "",
+ dataModel?.methane.toString(),
+ )
+ } else {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ "",
+ "0",
+ "1",
+ it.data,
+ dataModel?.methane.toString(),
+ )
+ isRecordingVideo = false
+ }
}
}, true
)
@@ -606,8 +630,8 @@
aChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byChanNum.toInt()
startAChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
- dChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum +
- deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
+ dChannelNum =
+ deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum + deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
startDChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
var iAnalogStartChan = startAChannel
@@ -655,7 +679,9 @@
//打开激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.OPEN_SENSOR_COMMAND,
LocaleConstant.OPEN_SENSOR_COMMAND.size
)
@@ -748,6 +774,31 @@
}
/**
+ * 视频抓取,抓取15s的视频
+ * */
+ private fun recordVideo() {
+ if (!isRecordingVideo) {
+ isRecordingVideo = true
+ val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4"
+ Log.d(kTag, "开始抓取视频 => $videoPath")
+ hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath)
+ object : CountDownTimer(15 * 1000, 1000) {
+ override fun onTick(l: Long) {
+
+ }
+
+ override fun onFinish() {
+ //停止视频抓取
+ hkSDK.NET_DVR_StopSaveRealData(returnUserId)
+
+ //海康视频不能直接播放,需要转码。服务器转码
+ fileViewModel.uploadFile(File(videoPath), FileType.VIDEO)
+ }
+ }.start()
+ }
+ }
+
+ /**
* 画面抓取
* */
private fun captureImage(isAutoCapture: Boolean) {
@@ -770,7 +821,9 @@
private fun stopPreview() {
//关闭激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.CLOSE_SENSOR_COMMAND,
LocaleConstant.CLOSE_SENSOR_COMMAND.size
)
@@ -835,9 +888,9 @@
if (dataModel!!.methane >= gasAlarmRule) {
isAlarm = "1"
- captureImage(true)
+ recordVideo()
- //TODO 抓取报警时候的视频并上传
+ captureImage(true)
}
/***折线图**************************************************************************/
@@ -924,4 +977,13 @@
super.onSaveInstanceState(outState)
binding.mapView.onSaveInstanceState(outState)
}
+
+ //扩展函数
+ private fun Context.createVideoFileDir(): File {
+ val videoDir = File(this.getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ if (!videoDir.exists()) {
+ videoDir.mkdir()
+ }
+ return videoDir
+ }
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
index 4d41ff1..983505d 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
@@ -263,6 +263,10 @@
}
binding.deleteTaskButton.setOnClickListener {
+ if (selectedItems.isEmpty()) {
+ "请先勾选要批量删除的任务".show(requireContext())
+ return@setOnClickListener
+ }
val ids = ArrayList()
selectedItems.forEach { task ->
ids.add(task.id)
diff --git a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
index a2a0c30..82e7be5 100644
--- a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
@@ -1,6 +1,8 @@
package com.casic.br.ktd.view
+import android.content.res.Configuration
import android.os.Bundle
+import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.amap.api.maps.CoordinateConverter
@@ -19,10 +21,18 @@
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.PageNavigationManager
import com.pengxh.kt.lite.vm.LoadState
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
class AlarmDetailActivity : KotlinBaseActivity() {
+ private val kTag = "AlarmDetailActivity"
private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
override fun initEvent() {
@@ -32,6 +42,10 @@
PageNavigationManager.addActivity(this)
val alarmId = intent.getStringExtra(Constant.INTENT_PARAM)!!
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
alarmViewModel.getAlarmDetail(alarmId)
alarmViewModel.alarmDetail.observe(this) {
@@ -87,6 +101,39 @@
} else {
binding.emptyImageView.visibility = View.GONE
binding.videoPlayerView.visibility = View.VISIBLE
+
+ val videoPath = model.alarmVideo.combineImagePath()
+ Log.d(kTag, "initOnCreate => $videoPath")
+ val videoOption = GSYVideoOptionBuilder()
+ videoOption.setIsTouchWiget(true)
+ .setRotateViewAuto(false)
+ .setLockLand(false)
+ .setAutoFullWithSize(true)
+ .setShowFullAnimation(false)
+ .setNeedLockFull(true)
+ .setUrl(videoPath)
+ .setCacheWithPlay(false)
+ .setVideoTitle(model.taskName)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onPrepared(url: String, vararg objects: Any) {
+ super.onPrepared(url, *objects)
+ //开始播放了才能旋转和全屏
+ orientationUtils.isEnable = true
+ isPlay = true
+ }
+
+ override fun onQuitFullscreen(url: String, vararg objects: Any) {
+ super.onQuitFullscreen(url, *objects)
+ orientationUtils.backToProtVideo()
+ }
+ }).setLockClickListener { _, lock ->
+ orientationUtils.isEnable = !lock
+ }.build(binding.videoPlayerView)
+ binding.videoPlayerView.fullscreenButton.setOnClickListener {
+ //直接横屏
+ orientationUtils.resolveByClick()
+ binding.videoPlayerView.startWindowFullscreen(this, true, true)
+ }
}
}
}
@@ -112,4 +159,46 @@
override fun setupTopBarLayout() {
ImmersionBar.with(this).statusBarDarkFont(true).init()
}
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
index 811e69d..b25a889 100644
--- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
@@ -7,6 +7,8 @@
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Environment
import android.os.Handler
import android.os.Message
import android.util.Log
@@ -127,6 +129,9 @@
//甲烷浓度阈值
private var gasAlarmRule = 1000
+ //是否正在抓取视频
+ private var isRecordingVideo = false
+
override fun initViewBinding(): ActivityInspectionBinding {
return ActivityInspectionBinding.inflate(layoutInflater)
}
@@ -204,20 +209,39 @@
lng = aMapLocation.latitude.toString()
address = aMapLocation.address
speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat()
- alarmViewModel.addAlarm(
- taskId,
- deviceId,
- "甲烷浓度超过阈值",
- lat,
- lng,
- System.currentTimeMillis().timestampToCompleteDate(),
- gasAlarmRule.toString(),
- it.data,
- "0",
- "1",
- "",
- dataModel?.methane.toString(),
- )
+
+ if (it.data.endsWith(".png")) {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ it.data,
+ "0",
+ "1",
+ "",
+ dataModel?.methane.toString(),
+ )
+ } else {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ "",
+ "0",
+ "1",
+ it.data,
+ dataModel?.methane.toString(),
+ )
+ isRecordingVideo = false
+ }
}
}, true
)
@@ -606,8 +630,8 @@
aChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byChanNum.toInt()
startAChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
- dChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum +
- deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
+ dChannelNum =
+ deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum + deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
startDChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
var iAnalogStartChan = startAChannel
@@ -655,7 +679,9 @@
//打开激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.OPEN_SENSOR_COMMAND,
LocaleConstant.OPEN_SENSOR_COMMAND.size
)
@@ -748,6 +774,31 @@
}
/**
+ * 视频抓取,抓取15s的视频
+ * */
+ private fun recordVideo() {
+ if (!isRecordingVideo) {
+ isRecordingVideo = true
+ val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4"
+ Log.d(kTag, "开始抓取视频 => $videoPath")
+ hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath)
+ object : CountDownTimer(15 * 1000, 1000) {
+ override fun onTick(l: Long) {
+
+ }
+
+ override fun onFinish() {
+ //停止视频抓取
+ hkSDK.NET_DVR_StopSaveRealData(returnUserId)
+
+ //海康视频不能直接播放,需要转码。服务器转码
+ fileViewModel.uploadFile(File(videoPath), FileType.VIDEO)
+ }
+ }.start()
+ }
+ }
+
+ /**
* 画面抓取
* */
private fun captureImage(isAutoCapture: Boolean) {
@@ -770,7 +821,9 @@
private fun stopPreview() {
//关闭激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.CLOSE_SENSOR_COMMAND,
LocaleConstant.CLOSE_SENSOR_COMMAND.size
)
@@ -835,9 +888,9 @@
if (dataModel!!.methane >= gasAlarmRule) {
isAlarm = "1"
- captureImage(true)
+ recordVideo()
- //TODO 抓取报警时候的视频并上传
+ captureImage(true)
}
/***折线图**************************************************************************/
@@ -924,4 +977,13 @@
super.onSaveInstanceState(outState)
binding.mapView.onSaveInstanceState(outState)
}
+
+ //扩展函数
+ private fun Context.createVideoFileDir(): File {
+ val videoDir = File(this.getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ if (!videoDir.exists()) {
+ videoDir.mkdir()
+ }
+ return videoDir
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
index e90c1ee..4b03815 100644
--- a/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
@@ -19,6 +19,7 @@
import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.gyf.immersionbar.ImmersionBar
import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.WeakReferenceHandler
@@ -175,8 +176,7 @@
taskDetailAdapter.setOnClickedListener(object :
TaskDetailAdapter.OnClickedListener {
override fun onShowTextClicked(item: TaskDetailModel.DataModel.RowsModel) {
- //TODO 播放视频
- item.taskId.show(this@TaskDetailActivity)
+ navigatePageTo(item.taskId)
}
})
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
index 4d41ff1..983505d 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
@@ -263,6 +263,10 @@
}
binding.deleteTaskButton.setOnClickListener {
+ if (selectedItems.isEmpty()) {
+ "请先勾选要批量删除的任务".show(requireContext())
+ return@setOnClickListener
+ }
val ids = ArrayList()
selectedItems.forEach { task ->
ids.add(task.id)
diff --git a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
index a2a0c30..82e7be5 100644
--- a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
@@ -1,6 +1,8 @@
package com.casic.br.ktd.view
+import android.content.res.Configuration
import android.os.Bundle
+import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.amap.api.maps.CoordinateConverter
@@ -19,10 +21,18 @@
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.PageNavigationManager
import com.pengxh.kt.lite.vm.LoadState
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
class AlarmDetailActivity : KotlinBaseActivity() {
+ private val kTag = "AlarmDetailActivity"
private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
override fun initEvent() {
@@ -32,6 +42,10 @@
PageNavigationManager.addActivity(this)
val alarmId = intent.getStringExtra(Constant.INTENT_PARAM)!!
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
alarmViewModel.getAlarmDetail(alarmId)
alarmViewModel.alarmDetail.observe(this) {
@@ -87,6 +101,39 @@
} else {
binding.emptyImageView.visibility = View.GONE
binding.videoPlayerView.visibility = View.VISIBLE
+
+ val videoPath = model.alarmVideo.combineImagePath()
+ Log.d(kTag, "initOnCreate => $videoPath")
+ val videoOption = GSYVideoOptionBuilder()
+ videoOption.setIsTouchWiget(true)
+ .setRotateViewAuto(false)
+ .setLockLand(false)
+ .setAutoFullWithSize(true)
+ .setShowFullAnimation(false)
+ .setNeedLockFull(true)
+ .setUrl(videoPath)
+ .setCacheWithPlay(false)
+ .setVideoTitle(model.taskName)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onPrepared(url: String, vararg objects: Any) {
+ super.onPrepared(url, *objects)
+ //开始播放了才能旋转和全屏
+ orientationUtils.isEnable = true
+ isPlay = true
+ }
+
+ override fun onQuitFullscreen(url: String, vararg objects: Any) {
+ super.onQuitFullscreen(url, *objects)
+ orientationUtils.backToProtVideo()
+ }
+ }).setLockClickListener { _, lock ->
+ orientationUtils.isEnable = !lock
+ }.build(binding.videoPlayerView)
+ binding.videoPlayerView.fullscreenButton.setOnClickListener {
+ //直接横屏
+ orientationUtils.resolveByClick()
+ binding.videoPlayerView.startWindowFullscreen(this, true, true)
+ }
}
}
}
@@ -112,4 +159,46 @@
override fun setupTopBarLayout() {
ImmersionBar.with(this).statusBarDarkFont(true).init()
}
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
index 811e69d..b25a889 100644
--- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
@@ -7,6 +7,8 @@
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Environment
import android.os.Handler
import android.os.Message
import android.util.Log
@@ -127,6 +129,9 @@
//甲烷浓度阈值
private var gasAlarmRule = 1000
+ //是否正在抓取视频
+ private var isRecordingVideo = false
+
override fun initViewBinding(): ActivityInspectionBinding {
return ActivityInspectionBinding.inflate(layoutInflater)
}
@@ -204,20 +209,39 @@
lng = aMapLocation.latitude.toString()
address = aMapLocation.address
speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat()
- alarmViewModel.addAlarm(
- taskId,
- deviceId,
- "甲烷浓度超过阈值",
- lat,
- lng,
- System.currentTimeMillis().timestampToCompleteDate(),
- gasAlarmRule.toString(),
- it.data,
- "0",
- "1",
- "",
- dataModel?.methane.toString(),
- )
+
+ if (it.data.endsWith(".png")) {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ it.data,
+ "0",
+ "1",
+ "",
+ dataModel?.methane.toString(),
+ )
+ } else {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ "",
+ "0",
+ "1",
+ it.data,
+ dataModel?.methane.toString(),
+ )
+ isRecordingVideo = false
+ }
}
}, true
)
@@ -606,8 +630,8 @@
aChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byChanNum.toInt()
startAChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
- dChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum +
- deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
+ dChannelNum =
+ deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum + deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
startDChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
var iAnalogStartChan = startAChannel
@@ -655,7 +679,9 @@
//打开激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.OPEN_SENSOR_COMMAND,
LocaleConstant.OPEN_SENSOR_COMMAND.size
)
@@ -748,6 +774,31 @@
}
/**
+ * 视频抓取,抓取15s的视频
+ * */
+ private fun recordVideo() {
+ if (!isRecordingVideo) {
+ isRecordingVideo = true
+ val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4"
+ Log.d(kTag, "开始抓取视频 => $videoPath")
+ hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath)
+ object : CountDownTimer(15 * 1000, 1000) {
+ override fun onTick(l: Long) {
+
+ }
+
+ override fun onFinish() {
+ //停止视频抓取
+ hkSDK.NET_DVR_StopSaveRealData(returnUserId)
+
+ //海康视频不能直接播放,需要转码。服务器转码
+ fileViewModel.uploadFile(File(videoPath), FileType.VIDEO)
+ }
+ }.start()
+ }
+ }
+
+ /**
* 画面抓取
* */
private fun captureImage(isAutoCapture: Boolean) {
@@ -770,7 +821,9 @@
private fun stopPreview() {
//关闭激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.CLOSE_SENSOR_COMMAND,
LocaleConstant.CLOSE_SENSOR_COMMAND.size
)
@@ -835,9 +888,9 @@
if (dataModel!!.methane >= gasAlarmRule) {
isAlarm = "1"
- captureImage(true)
+ recordVideo()
- //TODO 抓取报警时候的视频并上传
+ captureImage(true)
}
/***折线图**************************************************************************/
@@ -924,4 +977,13 @@
super.onSaveInstanceState(outState)
binding.mapView.onSaveInstanceState(outState)
}
+
+ //扩展函数
+ private fun Context.createVideoFileDir(): File {
+ val videoDir = File(this.getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ if (!videoDir.exists()) {
+ videoDir.mkdir()
+ }
+ return videoDir
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
index e90c1ee..4b03815 100644
--- a/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
@@ -19,6 +19,7 @@
import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.gyf.immersionbar.ImmersionBar
import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.WeakReferenceHandler
@@ -175,8 +176,7 @@
taskDetailAdapter.setOnClickedListener(object :
TaskDetailAdapter.OnClickedListener {
override fun onShowTextClicked(item: TaskDetailModel.DataModel.RowsModel) {
- //TODO 播放视频
- item.taskId.show(this@TaskDetailActivity)
+ navigatePageTo(item.taskId)
}
})
}
diff --git a/app/src/main/java/com/casic/br/ktd/view/VideoPlayerActivity.kt b/app/src/main/java/com/casic/br/ktd/view/VideoPlayerActivity.kt
new file mode 100644
index 0000000..9b04bb6
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/view/VideoPlayerActivity.kt
@@ -0,0 +1,89 @@
+package com.casic.br.ktd.view
+
+import android.content.res.Configuration
+import android.os.Bundle
+import com.casic.br.ktd.databinding.ActivityVideoPlayerBinding
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.getScreenHeight
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.utils.Constant
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
+
+class VideoPlayerActivity : KotlinBaseActivity() {
+
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
+
+ override fun initEvent() {
+
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val params = window.attributes
+ params.width = (getScreenWidth() * 0.8).toInt()
+ params.height = (getScreenHeight() * 0.8).toInt()
+ window.attributes = params
+
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
+ val taskId = intent.getStringExtra(Constant.INTENT_PARAM)
+ }
+
+ override fun initViewBinding(): ActivityVideoPlayerBinding {
+ return ActivityVideoPlayerBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+
+ }
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d0fa65d..7df3629 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,10 @@
android:name=".view.TaskDetailActivity"
android:screenOrientation="landscape" />
+
diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
index 4d41ff1..983505d 100644
--- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
+++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt
@@ -263,6 +263,10 @@
}
binding.deleteTaskButton.setOnClickListener {
+ if (selectedItems.isEmpty()) {
+ "请先勾选要批量删除的任务".show(requireContext())
+ return@setOnClickListener
+ }
val ids = ArrayList()
selectedItems.forEach { task ->
ids.add(task.id)
diff --git a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
index a2a0c30..82e7be5 100644
--- a/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/AlarmDetailActivity.kt
@@ -1,6 +1,8 @@
package com.casic.br.ktd.view
+import android.content.res.Configuration
import android.os.Bundle
+import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.amap.api.maps.CoordinateConverter
@@ -19,10 +21,18 @@
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.PageNavigationManager
import com.pengxh.kt.lite.vm.LoadState
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
class AlarmDetailActivity : KotlinBaseActivity() {
+ private val kTag = "AlarmDetailActivity"
private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
override fun initEvent() {
@@ -32,6 +42,10 @@
PageNavigationManager.addActivity(this)
val alarmId = intent.getStringExtra(Constant.INTENT_PARAM)!!
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
alarmViewModel.getAlarmDetail(alarmId)
alarmViewModel.alarmDetail.observe(this) {
@@ -87,6 +101,39 @@
} else {
binding.emptyImageView.visibility = View.GONE
binding.videoPlayerView.visibility = View.VISIBLE
+
+ val videoPath = model.alarmVideo.combineImagePath()
+ Log.d(kTag, "initOnCreate => $videoPath")
+ val videoOption = GSYVideoOptionBuilder()
+ videoOption.setIsTouchWiget(true)
+ .setRotateViewAuto(false)
+ .setLockLand(false)
+ .setAutoFullWithSize(true)
+ .setShowFullAnimation(false)
+ .setNeedLockFull(true)
+ .setUrl(videoPath)
+ .setCacheWithPlay(false)
+ .setVideoTitle(model.taskName)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onPrepared(url: String, vararg objects: Any) {
+ super.onPrepared(url, *objects)
+ //开始播放了才能旋转和全屏
+ orientationUtils.isEnable = true
+ isPlay = true
+ }
+
+ override fun onQuitFullscreen(url: String, vararg objects: Any) {
+ super.onQuitFullscreen(url, *objects)
+ orientationUtils.backToProtVideo()
+ }
+ }).setLockClickListener { _, lock ->
+ orientationUtils.isEnable = !lock
+ }.build(binding.videoPlayerView)
+ binding.videoPlayerView.fullscreenButton.setOnClickListener {
+ //直接横屏
+ orientationUtils.resolveByClick()
+ binding.videoPlayerView.startWindowFullscreen(this, true, true)
+ }
}
}
}
@@ -112,4 +159,46 @@
override fun setupTopBarLayout() {
ImmersionBar.with(this).statusBarDarkFont(true).init()
}
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
index 811e69d..b25a889 100644
--- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt
@@ -7,6 +7,8 @@
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Environment
import android.os.Handler
import android.os.Message
import android.util.Log
@@ -127,6 +129,9 @@
//甲烷浓度阈值
private var gasAlarmRule = 1000
+ //是否正在抓取视频
+ private var isRecordingVideo = false
+
override fun initViewBinding(): ActivityInspectionBinding {
return ActivityInspectionBinding.inflate(layoutInflater)
}
@@ -204,20 +209,39 @@
lng = aMapLocation.latitude.toString()
address = aMapLocation.address
speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat()
- alarmViewModel.addAlarm(
- taskId,
- deviceId,
- "甲烷浓度超过阈值",
- lat,
- lng,
- System.currentTimeMillis().timestampToCompleteDate(),
- gasAlarmRule.toString(),
- it.data,
- "0",
- "1",
- "",
- dataModel?.methane.toString(),
- )
+
+ if (it.data.endsWith(".png")) {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ it.data,
+ "0",
+ "1",
+ "",
+ dataModel?.methane.toString(),
+ )
+ } else {
+ alarmViewModel.addAlarm(
+ taskId,
+ deviceId,
+ "甲烷浓度超过阈值",
+ lat,
+ lng,
+ System.currentTimeMillis().timestampToCompleteDate(),
+ gasAlarmRule.toString(),
+ "",
+ "0",
+ "1",
+ it.data,
+ dataModel?.methane.toString(),
+ )
+ isRecordingVideo = false
+ }
}
}, true
)
@@ -606,8 +630,8 @@
aChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byChanNum.toInt()
startAChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
- dChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum +
- deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
+ dChannelNum =
+ deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum + deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256
startDChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt()
var iAnalogStartChan = startAChannel
@@ -655,7 +679,9 @@
//打开激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.OPEN_SENSOR_COMMAND,
LocaleConstant.OPEN_SENSOR_COMMAND.size
)
@@ -748,6 +774,31 @@
}
/**
+ * 视频抓取,抓取15s的视频
+ * */
+ private fun recordVideo() {
+ if (!isRecordingVideo) {
+ isRecordingVideo = true
+ val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4"
+ Log.d(kTag, "开始抓取视频 => $videoPath")
+ hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath)
+ object : CountDownTimer(15 * 1000, 1000) {
+ override fun onTick(l: Long) {
+
+ }
+
+ override fun onFinish() {
+ //停止视频抓取
+ hkSDK.NET_DVR_StopSaveRealData(returnUserId)
+
+ //海康视频不能直接播放,需要转码。服务器转码
+ fileViewModel.uploadFile(File(videoPath), FileType.VIDEO)
+ }
+ }.start()
+ }
+ }
+
+ /**
* 画面抓取
* */
private fun captureImage(isAutoCapture: Boolean) {
@@ -770,7 +821,9 @@
private fun stopPreview() {
//关闭激光传感器
SDKGuider.sdkGuider.devPassThroughGuider.NET_DVR_SendToSerialPort_jni(
- returnUserId, 2, 1,
+ returnUserId,
+ 2,
+ 1,
LocaleConstant.CLOSE_SENSOR_COMMAND,
LocaleConstant.CLOSE_SENSOR_COMMAND.size
)
@@ -835,9 +888,9 @@
if (dataModel!!.methane >= gasAlarmRule) {
isAlarm = "1"
- captureImage(true)
+ recordVideo()
- //TODO 抓取报警时候的视频并上传
+ captureImage(true)
}
/***折线图**************************************************************************/
@@ -924,4 +977,13 @@
super.onSaveInstanceState(outState)
binding.mapView.onSaveInstanceState(outState)
}
+
+ //扩展函数
+ private fun Context.createVideoFileDir(): File {
+ val videoDir = File(this.getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ if (!videoDir.exists()) {
+ videoDir.mkdir()
+ }
+ return videoDir
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt b/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
index e90c1ee..4b03815 100644
--- a/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
+++ b/app/src/main/java/com/casic/br/ktd/view/TaskDetailActivity.kt
@@ -19,6 +19,7 @@
import com.casic.br.ktd.widgets.DateRangeActionSheet
import com.gyf.immersionbar.ImmersionBar
import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import com.pengxh.kt.lite.utils.Constant
import com.pengxh.kt.lite.utils.WeakReferenceHandler
@@ -175,8 +176,7 @@
taskDetailAdapter.setOnClickedListener(object :
TaskDetailAdapter.OnClickedListener {
override fun onShowTextClicked(item: TaskDetailModel.DataModel.RowsModel) {
- //TODO 播放视频
- item.taskId.show(this@TaskDetailActivity)
+ navigatePageTo(item.taskId)
}
})
}
diff --git a/app/src/main/java/com/casic/br/ktd/view/VideoPlayerActivity.kt b/app/src/main/java/com/casic/br/ktd/view/VideoPlayerActivity.kt
new file mode 100644
index 0000000..9b04bb6
--- /dev/null
+++ b/app/src/main/java/com/casic/br/ktd/view/VideoPlayerActivity.kt
@@ -0,0 +1,89 @@
+package com.casic.br.ktd.view
+
+import android.content.res.Configuration
+import android.os.Bundle
+import com.casic.br.ktd.databinding.ActivityVideoPlayerBinding
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.extensions.getScreenHeight
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.utils.Constant
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
+
+class VideoPlayerActivity : KotlinBaseActivity() {
+
+ private lateinit var orientationUtils: OrientationUtils
+ private var isPlay = false
+ private var isPause = false
+
+ override fun initEvent() {
+
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val params = window.attributes
+ params.width = (getScreenWidth() * 0.8).toInt()
+ params.height = (getScreenHeight() * 0.8).toInt()
+ window.attributes = params
+
+ orientationUtils = OrientationUtils(this, binding.videoPlayerView)
+ //初始化不打开外部的旋转
+ orientationUtils.isEnable = false
+
+ val taskId = intent.getStringExtra(Constant.INTENT_PARAM)
+ }
+
+ override fun initViewBinding(): ActivityVideoPlayerBinding {
+ return ActivityVideoPlayerBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+
+ }
+
+ override fun onBackPressed() {
+ orientationUtils.backToProtVideo()
+ if (GSYVideoManager.backFromWindowFull(this)) {
+ return
+ }
+ super.onBackPressed()
+ }
+
+ override fun onPause() {
+ binding.videoPlayerView.currentPlayer.onVideoPause()
+ super.onPause()
+ isPause = true
+ }
+
+ override fun onResume() {
+ binding.videoPlayerView.currentPlayer.onVideoResume(false)
+ super.onResume()
+ isPause = false
+ }
+
+ override fun onDestroy() {
+ if (isPlay) {
+ binding.videoPlayerView.currentPlayer.release()
+ }
+ orientationUtils.releaseListener()
+ super.onDestroy()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ //如果旋转了就全屏
+ if (isPlay && !isPause) {
+ binding.videoPlayerView.onConfigurationChanged(
+ this,
+ newConfig,
+ orientationUtils,
+ true,
+ true
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_video_player.xml b/app/src/main/res/layout/activity_video_player.xml
new file mode 100644
index 0000000..c33aa1c
--- /dev/null
+++ b/app/src/main/res/layout/activity_video_player.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file