视频播放
This commit is contained in:
7
.idea/deploymentTargetSelector.xml
generated
7
.idea/deploymentTargetSelector.xml
generated
@@ -4,6 +4,13 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
<DropdownSelection timestamp="2026-05-06T08:15:17.445018500Z">
|
||||||
|
<Target type="DEFAULT_BOOT">
|
||||||
|
<handle>
|
||||||
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=80bece4" />
|
||||||
|
</handle>
|
||||||
|
</Target>
|
||||||
|
</DropdownSelection>
|
||||||
<DialogSelection />
|
<DialogSelection />
|
||||||
</SelectionState>
|
</SelectionState>
|
||||||
</selectionStates>
|
</selectionStates>
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ dependencies {
|
|||||||
implementation(libs.androidx.constraintlayout)
|
implementation(libs.androidx.constraintlayout)
|
||||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||||
implementation(libs.firebase.crashlytics.buildtools)
|
implementation(libs.firebase.crashlytics.buildtools)
|
||||||
|
implementation(libs.androidx.ui.test)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
@@ -76,4 +77,10 @@ dependencies {
|
|||||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
// ZXing 二维码扫描库
|
// ZXing 二维码扫描库
|
||||||
implementation("com.google.zxing:core:3.5.2")
|
implementation("com.google.zxing:core:3.5.2")
|
||||||
|
// ExoPlayer 核心库
|
||||||
|
implementation("androidx.media3:media3-exoplayer:1.9.0")
|
||||||
|
// ExoPlayer UI组件库,提供PlayerView等
|
||||||
|
implementation("androidx.media3:media3-ui:1.9.0")
|
||||||
|
// ExoPlayer 通用库
|
||||||
|
implementation("androidx.media3:media3-common:1.9.0")
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,13 @@
|
|||||||
android:theme="@style/Theme.DefenseApplication">
|
android:theme="@style/Theme.DefenseApplication">
|
||||||
<activity
|
<activity
|
||||||
android:name=".liveVideo.LiveVideoActivity"
|
android:name=".liveVideo.LiveVideoActivity"
|
||||||
android:exported="false" />
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".home.ScanActivity"
|
android:name=".home.ScanActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
@@ -46,13 +52,7 @@
|
|||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".home.HomeActivity"
|
android:name=".home.HomeActivity"
|
||||||
android:exported="true">
|
android:exported="false"/>
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".login.RegisterSuccessActivity"
|
android:name=".login.RegisterSuccessActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@@ -1,80 +1,251 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.example.defenseapplication.liveVideo
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.media.AudioManager
|
||||||
|
import android.media.MediaPlayer
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.view.SurfaceHolder
|
||||||
import android.os.Looper
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.activity.OnBackPressedDispatcher
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.ui.test.isEnabled
|
||||||
import com.example.defenseapplication.databinding.LiveVideoActivityBinding
|
import com.example.defenseapplication.databinding.LiveVideoActivityBinding
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
class LiveVideoActivity : AppCompatActivity() {
|
class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||||
private lateinit var binding: LiveVideoActivityBinding
|
private lateinit var binding: LiveVideoActivityBinding
|
||||||
|
|
||||||
|
private var mediaPlayer: MediaPlayer? = null
|
||||||
|
private var isFullscreen = false
|
||||||
|
private var isPlaying = false
|
||||||
private var isVoiceEnabled = false
|
private var isVoiceEnabled = false
|
||||||
private var isLightOn = false
|
private var isLightOn = false
|
||||||
private var isRecording = false
|
private var isRecording = false
|
||||||
private var recordTime = 0
|
|
||||||
private var recordHandler: Handler? = null
|
private var videoWidth = 0
|
||||||
private var recordRunnable: Runnable? = null
|
private var videoHeight = 0
|
||||||
|
|
||||||
|
private val testVideoUrl = "https://vjs.zencdn.net/v/oceans.mp4"
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = LiveVideoActivityBinding.inflate(layoutInflater)
|
binding = LiveVideoActivityBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
|
||||||
|
initSurfaceView()
|
||||||
initListener()
|
initListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initSurfaceView() {
|
||||||
|
binding.surfaceView.holder.addCallback(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun surfaceCreated(holder: SurfaceHolder) {
|
||||||
|
initMediaPlayer(holder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
|
||||||
|
adjustSurfaceViewSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
||||||
|
releaseMediaPlayer()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initMediaPlayer(holder: SurfaceHolder) {
|
||||||
|
mediaPlayer = MediaPlayer().apply {
|
||||||
|
setDisplay(holder)
|
||||||
|
setAudioStreamType(AudioManager.STREAM_MUSIC)
|
||||||
|
|
||||||
|
try {
|
||||||
|
setDataSource(this@LiveVideoActivity, Uri.parse(testVideoUrl))
|
||||||
|
prepareAsync()
|
||||||
|
|
||||||
|
setOnPreparedListener { mp ->
|
||||||
|
this@LiveVideoActivity.videoWidth = mp.videoWidth
|
||||||
|
this@LiveVideoActivity.videoHeight = mp.videoHeight
|
||||||
|
adjustSurfaceViewSize()
|
||||||
|
mp.isLooping = true
|
||||||
|
mp.start()
|
||||||
|
this@LiveVideoActivity.isPlaying = true
|
||||||
|
Toast.makeText(this@LiveVideoActivity, "视频准备完成", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnCompletionListener {
|
||||||
|
this@LiveVideoActivity.isPlaying = false
|
||||||
|
Toast.makeText(this@LiveVideoActivity, "播放完成", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnErrorListener { _, what, extra ->
|
||||||
|
Toast.makeText(this@LiveVideoActivity, "播放错误: $what, $extra", Toast.LENGTH_SHORT).show()
|
||||||
|
releaseMediaPlayer()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnBufferingUpdateListener { _, percent ->
|
||||||
|
if (percent < 100) {
|
||||||
|
Toast.makeText(this@LiveVideoActivity, "缓冲中: $percent%", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Toast.makeText(this@LiveVideoActivity, "无法加载视频", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun adjustSurfaceViewSize() {
|
||||||
|
if (videoWidth == 0 || videoHeight == 0) return
|
||||||
|
|
||||||
|
val screenWidth = resources.displayMetrics.widthPixels
|
||||||
|
val screenHeight = resources.displayMetrics.heightPixels
|
||||||
|
val aspectRatio = videoWidth.toFloat() / videoHeight.toFloat()
|
||||||
|
|
||||||
|
val params = binding.surfaceView.layoutParams
|
||||||
|
|
||||||
|
if (isFullscreen) {
|
||||||
|
if (screenWidth.toFloat() / screenHeight.toFloat() > aspectRatio) {
|
||||||
|
params.width = (screenHeight * aspectRatio).toInt()
|
||||||
|
params.height = screenHeight
|
||||||
|
} else {
|
||||||
|
params.width = screenWidth
|
||||||
|
params.height = (screenWidth / aspectRatio).toInt()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val containerHeight = binding.videoContainer.height
|
||||||
|
params.width = (containerHeight * aspectRatio).toInt()
|
||||||
|
params.height = containerHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.surfaceView.layoutParams = params
|
||||||
|
}
|
||||||
|
|
||||||
private fun initListener() {
|
private fun initListener() {
|
||||||
// 返回按钮
|
|
||||||
binding.btnBack.setOnClickListener {
|
binding.btnBack.setOnClickListener {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 菜单按钮
|
|
||||||
binding.ivMenu.setOnClickListener {
|
binding.ivMenu.setOnClickListener {
|
||||||
Toast.makeText(this, "菜单", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "菜单", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全屏按钮
|
|
||||||
binding.ivFullscreen.setOnClickListener {
|
binding.ivFullscreen.setOnClickListener {
|
||||||
Toast.makeText(this, "全屏", Toast.LENGTH_SHORT).show()
|
toggleFullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.surfaceView.setOnClickListener {
|
||||||
|
togglePlayPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 语音按钮
|
|
||||||
binding.llVoice.setOnClickListener {
|
binding.llVoice.setOnClickListener {
|
||||||
toggleVoice()
|
toggleVoice()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 灯光按钮
|
|
||||||
binding.llLight.setOnClickListener {
|
binding.llLight.setOnClickListener {
|
||||||
toggleLight()
|
toggleLight()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 录像按钮
|
|
||||||
binding.llRecord.setOnClickListener {
|
binding.llRecord.setOnClickListener {
|
||||||
toggleRecording()
|
toggleRecording()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 告警日志区域
|
|
||||||
binding.llAlarmLog.setOnClickListener {
|
binding.llAlarmLog.setOnClickListener {
|
||||||
Toast.makeText(this, "查看告警日志", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "查看告警日志", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun togglePlayPause() {
|
||||||
|
mediaPlayer?.let { mp ->
|
||||||
|
if (mp.isPlaying) {
|
||||||
|
mp.pause()
|
||||||
|
isPlaying = false
|
||||||
|
Toast.makeText(this, "已暂停", Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
mp.start()
|
||||||
|
isPlaying = true
|
||||||
|
Toast.makeText(this, "继续播放", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleFullscreen() {
|
||||||
|
isFullscreen = !isFullscreen
|
||||||
|
|
||||||
|
if (isFullscreen) {
|
||||||
|
enterFullscreen()
|
||||||
|
} else {
|
||||||
|
exitFullscreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enterFullscreen() {
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
||||||
|
|
||||||
|
binding.topBar.visibility = View.GONE
|
||||||
|
binding.bitRateBar.visibility = View.GONE
|
||||||
|
binding.functionBar.visibility = View.GONE
|
||||||
|
|
||||||
|
val alarmLogParent = binding.llAlarmLog.parent.parent as View
|
||||||
|
alarmLogParent.visibility = View.GONE
|
||||||
|
|
||||||
|
val containerParams = binding.videoContainer.layoutParams
|
||||||
|
containerParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
containerParams.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
binding.videoContainer.layoutParams = containerParams
|
||||||
|
|
||||||
|
val surfaceParams = binding.surfaceView.layoutParams
|
||||||
|
surfaceParams.width = resources.displayMetrics.widthPixels
|
||||||
|
surfaceParams.height = resources.displayMetrics.heightPixels
|
||||||
|
binding.surfaceView.layoutParams = surfaceParams
|
||||||
|
|
||||||
|
binding.ivFullscreen.setImageResource(com.example.defenseapplication.R.drawable.back)
|
||||||
|
|
||||||
|
Toast.makeText(this, "已进入全屏", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun exitFullscreen() {
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||||
|
window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
||||||
|
|
||||||
|
binding.topBar.visibility = View.VISIBLE
|
||||||
|
binding.bitRateBar.visibility = View.VISIBLE
|
||||||
|
binding.functionBar.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
val alarmLogParent = binding.llAlarmLog.parent.parent as View
|
||||||
|
alarmLogParent.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
val containerParams = binding.videoContainer.layoutParams
|
||||||
|
containerParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
containerParams.height = (220 * resources.displayMetrics.density).toInt()
|
||||||
|
binding.videoContainer.layoutParams = containerParams
|
||||||
|
|
||||||
|
adjustSurfaceViewSize()
|
||||||
|
|
||||||
|
binding.ivFullscreen.setImageResource(com.example.defenseapplication.R.drawable.full_screen)
|
||||||
|
|
||||||
|
Toast.makeText(this, "已退出全屏", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun toggleVoice() {
|
private fun toggleVoice() {
|
||||||
isVoiceEnabled = !isVoiceEnabled
|
isVoiceEnabled = !isVoiceEnabled
|
||||||
|
|
||||||
if (isVoiceEnabled) {
|
if (isVoiceEnabled) {
|
||||||
binding.vVoiceActive.visibility = View.VISIBLE
|
mediaPlayer?.setVolume(1.0f, 1.0f)
|
||||||
binding.ivVoice.setColorFilter(resources.getColor(com.example.defenseapplication.R.color.green))
|
binding.ivVoice.setImageResource(com.example.defenseapplication.R.drawable.voice_open)
|
||||||
Toast.makeText(this, "语音已开启", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "声音已开启", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
binding.vVoiceActive.visibility = View.INVISIBLE
|
mediaPlayer?.setVolume(0.0f, 0.0f)
|
||||||
binding.ivVoice.clearColorFilter()
|
binding.ivVoice.setImageResource(com.example.defenseapplication.R.drawable.voice)
|
||||||
Toast.makeText(this, "语音已关闭", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "声音已关闭", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +253,10 @@ class LiveVideoActivity : AppCompatActivity() {
|
|||||||
isLightOn = !isLightOn
|
isLightOn = !isLightOn
|
||||||
|
|
||||||
if (isLightOn) {
|
if (isLightOn) {
|
||||||
binding.ivLight.setImageResource(com.example.defenseapplication.R.drawable.light_on)
|
binding.ivLight.setImageResource(com.example.defenseapplication.R.drawable.light_on_open)
|
||||||
binding.ivLight.setColorFilter(resources.getColor(com.example.defenseapplication.R.color.green))
|
|
||||||
Toast.makeText(this, "灯光已开启", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "灯光已开启", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
binding.ivLight.setImageResource(com.example.defenseapplication.R.drawable.low_light)
|
binding.ivLight.setImageResource(com.example.defenseapplication.R.drawable.light_on)
|
||||||
binding.ivLight.clearColorFilter()
|
|
||||||
Toast.makeText(this, "灯光已关闭", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "灯光已关闭", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,38 +265,37 @@ class LiveVideoActivity : AppCompatActivity() {
|
|||||||
isRecording = !isRecording
|
isRecording = !isRecording
|
||||||
|
|
||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
recordTime = 0
|
binding.ivRecord.setImageResource(com.example.defenseapplication.R.drawable.copy_open)
|
||||||
binding.tvRecordTime.text = "00"
|
|
||||||
startRecordTimer()
|
|
||||||
binding.ivRecord.setColorFilter(resources.getColor(com.example.defenseapplication.R.color.red))
|
|
||||||
Toast.makeText(this, "开始录像", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "开始录像", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
stopRecordTimer()
|
binding.ivRecord.setImageResource(com.example.defenseapplication.R.drawable.copy)
|
||||||
binding.ivRecord.clearColorFilter()
|
Toast.makeText(this, "停止录像", Toast.LENGTH_SHORT).show()
|
||||||
Toast.makeText(this, "停止录像,共录制 ${recordTime} 秒", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startRecordTimer() {
|
private fun releaseMediaPlayer() {
|
||||||
recordHandler = Handler(Looper.getMainLooper())
|
mediaPlayer?.let {
|
||||||
recordRunnable = object : Runnable {
|
if (it.isPlaying) {
|
||||||
override fun run() {
|
it.stop()
|
||||||
recordTime++
|
|
||||||
binding.tvRecordTime.text = String.format("%02d", recordTime)
|
|
||||||
recordHandler?.postDelayed(this, 1000)
|
|
||||||
}
|
}
|
||||||
|
it.release()
|
||||||
|
mediaPlayer = null
|
||||||
}
|
}
|
||||||
recordHandler?.post(recordRunnable!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopRecordTimer() {
|
override fun onPause() {
|
||||||
recordRunnable?.let { recordHandler?.removeCallbacks(it) }
|
super.onPause()
|
||||||
recordHandler = null
|
mediaPlayer?.pause()
|
||||||
recordRunnable = null
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
mediaPlayer?.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
releaseMediaPlayer()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
stopRecordTimer()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
app/src/main/res/drawable/copy_open.png
Normal file
BIN
app/src/main/res/drawable/copy_open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable/full_screen.png
Normal file
BIN
app/src/main/res/drawable/full_screen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
app/src/main/res/drawable/light_on_open.png
Normal file
BIN
app/src/main/res/drawable/light_on_open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 669 B |
BIN
app/src/main/res/drawable/voice_open.png
Normal file
BIN
app/src/main/res/drawable/voice_open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 796 B |
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 顶部导航栏 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/topBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
android:background="#FFFFFF"
|
android:background="#FFFFFF"
|
||||||
@@ -16,12 +17,11 @@
|
|||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:paddingRight="16dp">
|
android:paddingRight="16dp">
|
||||||
|
|
||||||
<Button
|
<ImageView
|
||||||
android:id="@+id/btnBack"
|
android:id="@+id/btnBack"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:background="@drawable/back"
|
android:background="@drawable/back"/>
|
||||||
android:contentDescription="返回" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvTitle"
|
android:id="@+id/tvTitle"
|
||||||
@@ -30,8 +30,9 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="智能防御机A1"
|
android:text="智能防御机A1"
|
||||||
android:textColor="#000000"
|
android:textColor="@color/black"
|
||||||
android:textSize="18sp" />
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivMenu"
|
android:id="@+id/ivMenu"
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
|
|
||||||
<!-- 视频流信息 -->
|
<!-- 视频流信息 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/bitRateBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
android:background="#FFFFFF"
|
android:background="#FFFFFF"
|
||||||
@@ -57,38 +59,55 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="120 B/S"
|
android:text="120 B/S"
|
||||||
android:textColor="#999999"
|
android:textColor="@color/black"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 视频显示区域 -->
|
<!-- 视频播放区域 -->
|
||||||
<RelativeLayout
|
<FrameLayout
|
||||||
|
android:id="@+id/videoContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="280dp"
|
android:layout_height="220dp"
|
||||||
android:background="#000000">
|
android:background="#000000">
|
||||||
|
|
||||||
<ImageView
|
<SurfaceView
|
||||||
android:id="@+id/ivVideo"
|
android:id="@+id/surface_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scaleType="centerCrop"
|
android:layout_gravity="center" />
|
||||||
android:src="@drawable/img" />
|
|
||||||
|
|
||||||
<!-- 全屏按钮 -->
|
<!-- 全屏按钮 -->
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivFullscreen"
|
android:id="@+id/ivFullscreen"
|
||||||
android:layout_width="32dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="24dp"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:src="@drawable/go_up" />
|
android:src="@drawable/full_screen"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
<!-- 播放控制按钮 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/playControl"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivPlay"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:src="@drawable/full_screen" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<!-- 功能按钮区域 -->
|
<!-- 功能按钮区域 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/functionBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="120dp"
|
android:layout_height="120dp"
|
||||||
android:background="#FFFFFF"
|
android:background="#FFFFFF"
|
||||||
@@ -101,49 +120,69 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="horizontal">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivVoice"
|
android:id="@+id/ivVoice"
|
||||||
android:layout_width="24dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="42dp"
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:src="@drawable/voice" />
|
android:src="@drawable/voice" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="语音"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/ic_normal"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/llLight"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivLight"
|
android:id="@+id/ivLight"
|
||||||
android:layout_width="24dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="42dp"
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:src="@drawable/light_on" />
|
android:src="@drawable/light_on" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="灯光"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/ic_normal"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/llRecord"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivRecord"
|
android:id="@+id/ivRecord"
|
||||||
android:layout_width="24dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="42dp"
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:src="@drawable/copy"/>
|
android:src="@drawable/copy"/>
|
||||||
</LinearLayout>
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="控制"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/ic_normal"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -153,10 +192,7 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:background="#FFFFFF">
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -169,23 +205,18 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:orientation="horizontal"
|
||||||
android:orientation="horizontal">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="告警日志"
|
android:text="告警日志"
|
||||||
android:textColor="#000000"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16dp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="16dp"
|
|
||||||
android:src="@drawable/go_up" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 告警图片列表 -->
|
<!-- 告警图片列表 -->
|
||||||
@@ -230,15 +261,16 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="入侵告警"
|
android:text="入侵告警"
|
||||||
android:textColor="#666666"
|
android:textColor="@color/black"
|
||||||
android:textSize="12sp" />
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="03-11"
|
android:text="03-11"
|
||||||
android:textColor="#999999"
|
android:textColor="@color/ic_normal"
|
||||||
android:textSize="10sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -265,7 +297,7 @@
|
|||||||
android:layout_height="20dp"
|
android:layout_height="20dp"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:src="@drawable/copy" />
|
android:src="@drawable/album" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
@@ -274,15 +306,16 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="入侵告警"
|
android:text="入侵告警"
|
||||||
android:textColor="#666666"
|
android:textColor="@color/black"
|
||||||
android:textSize="12sp" />
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="03-11"
|
android:text="03-11"
|
||||||
android:textColor="#999999"
|
android:textColor="@color/ic_normal"
|
||||||
android:textSize="10sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -321,15 +354,16 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="入侵告警"
|
android:text="入侵告警"
|
||||||
android:textColor="#666666"
|
android:textColor="@color/black"
|
||||||
android:textSize="12sp" />
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="03-11"
|
android:text="03-11"
|
||||||
android:textColor="#999999"
|
android:textColor="@color/ic_normal"
|
||||||
android:textSize="10sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ material = "1.10.0"
|
|||||||
activity = "1.8.0"
|
activity = "1.8.0"
|
||||||
constraintlayout = "2.1.4"
|
constraintlayout = "2.1.4"
|
||||||
firebaseCrashlyticsBuildtools = "3.0.7"
|
firebaseCrashlyticsBuildtools = "3.0.7"
|
||||||
|
uiTest = "1.11.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
@@ -20,6 +21,7 @@ material = { group = "com.google.android.material", name = "material", version.r
|
|||||||
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||||
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
|
firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
|
||||||
|
androidx-ui-test = { group = "androidx.compose.ui", name = "ui-test", version.ref = "uiTest" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user