Add front camera preview and camera switch UI

This commit is contained in:
Miguel Angel 2026-09-07 16:45:15 -05:00
parent 5be04b0217
commit 9deeb40217
5 changed files with 594 additions and 21 deletions

120
add_camera_switch.ps1 Normal file
View file

@ -0,0 +1,120 @@
$path = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\camera\M530CameraActivity.kt'
$lines = Get-Content $path
$result = New-Object System.Collections.Generic.List[string]
$addedVariable = $false
$addedButtonDeclaration = $false
$addedButtonUi = $false
$replacedSelector = $false
$replacedState = $false
foreach ($line in $lines) {
# ---------------------------------------------------------
# 1. Variable para saber que camara usa el preview
# ---------------------------------------------------------
if (-not $addedVariable -and
$line -match 'private var lastTouchActionMs = 0L') {
$result.Add($line)
$result.Add(' private var frontPreviewUsesFrontCamera = true')
$addedVariable = $true
continue
}
# ---------------------------------------------------------
# 2. Declaracion del boton
# ---------------------------------------------------------
if (-not $addedButtonDeclaration -and
$line -match 'private lateinit var closeButton: Button') {
$result.Add($line)
$result.Add(' private lateinit var switchCameraButton: Button')
$addedButtonDeclaration = $true
continue
}
# ---------------------------------------------------------
# 3. Insertar boton antes de captureButton
# ---------------------------------------------------------
if (-not $addedButtonUi -and
$line -match '^\s*captureButton = Button\(this\)\.apply') {
$result.Add(' switchCameraButton = Button(this).apply {')
$result.Add(' text = "CAMBIAR"')
$result.Add(' setTextColor(Color.WHITE)')
$result.Add(' textSize = 12f')
$result.Add(' setTypeface(typeface, Typeface.BOLD)')
$result.Add(' gravity = Gravity.CENTER')
$result.Add(' minWidth = 0')
$result.Add(' minHeight = 0')
$result.Add(' setPadding(dp(8), 0, dp(8), 0)')
$result.Add(' background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1))')
$result.Add(' visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE')
$result.Add(' elevation = dp(12).toFloat()')
$result.Add('')
$result.Add(' setOnClickListener {')
$result.Add(' if (mode == MODE_FRONT_PREVIEW) {')
$result.Add(' frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera')
$result.Add(' startCamera()')
$result.Add(' }')
$result.Add(' }')
$result.Add(' }')
$result.Add('')
$result.Add(' root.addView(')
$result.Add(' switchCameraButton,')
$result.Add(' FrameLayout.LayoutParams(dp(110), dp(48), Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL).apply {')
$result.Add(' bottomMargin = dp(76)')
$result.Add(' }')
$result.Add(' )')
$result.Add('')
$result.Add($line)
$addedButtonUi = $true
continue
}
# ---------------------------------------------------------
# 4. Selector dinamico frontal/posterior SOLO para preview
# ---------------------------------------------------------
if (-not $replacedSelector -and
$line -match 'CameraSelector\.DEFAULT_FRONT_CAMERA') {
$result.Add(' if (frontPreviewUsesFrontCamera)')
$result.Add(' CameraSelector.DEFAULT_FRONT_CAMERA')
$result.Add(' else')
$result.Add(' CameraSelector.DEFAULT_BACK_CAMERA,')
$replacedSelector = $true
continue
}
# ---------------------------------------------------------
# 5. Cambiar mensaje segun camara
# ---------------------------------------------------------
if (-not $replacedState -and
$line -match 'stateText\.text = "Camara frontal lista"') {
$result.Add(' stateText.text = if (frontPreviewUsesFrontCamera)')
$result.Add(' "Camara frontal lista"')
$result.Add(' else')
$result.Add(' "Camara posterior lista"')
$replacedState = $true
continue
}
$result.Add($line)
}
Set-Content -Path $path -Value $result -Encoding UTF8
Write-Host ""
Write-Host "=========================================="
Write-Host "CAMBIO DE CAMARA AGREGADO"
Write-Host "=========================================="
Write-Host "Variable: $addedVariable"
Write-Host "Declaracion boton: $addedButtonDeclaration"
Write-Host "UI boton: $addedButtonUi"
Write-Host "Selector: $replacedSelector"
Write-Host "Estado: $replacedState"
Write-Host ""

View file

@ -57,6 +57,7 @@ class MainActivity : ComponentActivity() {
@Inject lateinit var authSessionStore: AuthSessionStore @Inject lateinit var authSessionStore: AuthSessionStore
@Volatile private var isAuthenticated = false @Volatile private var isAuthenticated = false
private var frontPreviewOpened = false
companion object { companion object {
private const val TAG = "MainActivity" private const val TAG = "MainActivity"
@ -97,7 +98,16 @@ class MainActivity : ComponentActivity() {
}) })
lifecycleScope.launch { lifecycleScope.launch {
authSessionStore.token.collect { token -> isAuthenticated = !token.isNullOrBlank() } authSessionStore.token.collect { token ->
isAuthenticated = !token.isNullOrBlank()
if (isAuthenticated && !frontPreviewOpened) {
frontPreviewOpened = true
runOnUiThread {
openFrontPreview()
}
}
}
} }
registerHardwareReceiver() registerHardwareReceiver()
@ -222,6 +232,20 @@ class MainActivity : ComponentActivity() {
} }
private fun openFrontPreview() {
if (!isAuthenticated) return
startActivity(
android.content.Intent(
this,
com.bodycamera.twentyfoulabs.camera.M530CameraActivity::class.java
).putExtra(
com.bodycamera.twentyfoulabs.camera.M530CameraActivity.EXTRA_MODE,
com.bodycamera.twentyfoulabs.camera.M530CameraActivity.MODE_FRONT_PREVIEW
).addFlags(android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP)
)
}
private fun handlePhotoButton() { private fun handlePhotoButton() {
startActivity( startActivity(
android.content.Intent( android.content.Intent(
@ -374,3 +398,4 @@ fun AppNavigation(viewModel: MainViewModel, onOpenPhotoCamera: () -> Unit, onOpe

View file

@ -1,10 +1,11 @@
package com.bodycamera.twentyfoulabs.camera package com.bodycamera.twentyfoulabs.camera
import android.Manifest import android.Manifest
import android.content.ContentValues import android.content.ContentValues
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Color import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.graphics.drawable.GradientDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.SystemClock import android.os.SystemClock
@ -54,6 +55,7 @@ class M530CameraActivity : ComponentActivity() {
const val EXTRA_MODE = "mode" const val EXTRA_MODE = "mode"
const val MODE_PHOTO = "photo" const val MODE_PHOTO = "photo"
const val MODE_VIDEO = "video" const val MODE_VIDEO = "video"
const val MODE_FRONT_PREVIEW = "front_preview"
} }
private lateinit var previewView: PreviewView private lateinit var previewView: PreviewView
@ -63,6 +65,7 @@ class M530CameraActivity : ComponentActivity() {
private lateinit var physicalHintText: TextView private lateinit var physicalHintText: TextView
private lateinit var captureButton: Button private lateinit var captureButton: Button
private lateinit var closeButton: Button private lateinit var closeButton: Button
private lateinit var switchCameraButton: Button
private lateinit var recordDot: TextView private lateinit var recordDot: TextView
private lateinit var chronometer: Chronometer private lateinit var chronometer: Chronometer
@ -73,10 +76,11 @@ class M530CameraActivity : ComponentActivity() {
private var cameraProvider: ProcessCameraProvider? = null private var cameraProvider: ProcessCameraProvider? = null
private var lastPhysicalActionMs = 0L private var lastPhysicalActionMs = 0L
private var lastTouchActionMs = 0L private var lastTouchActionMs = 0L
private var frontPreviewUsesFrontCamera = true
private val cameraPermissionLauncher = private val cameraPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) startCamera() else stateText.text = "Permiso de cámara requerido" if (granted) startCamera() else stateText.text = "Permiso de camara requerido"
} }
private val audioPermissionLauncher = private val audioPermissionLauncher =
@ -140,7 +144,11 @@ class M530CameraActivity : ComponentActivity() {
} }
modeText = TextView(this).apply { modeText = TextView(this).apply {
text = if (mode == MODE_VIDEO) "VIDEO" else "FOTO" text = when (mode) {
MODE_VIDEO -> "VIDEO"
MODE_FRONT_PREVIEW -> "FRONTAL"
else -> "FOTO"
}
setTextColor(if (mode == MODE_VIDEO) 0xFFFF3B30.toInt() else 0xFFFFC400.toInt()) setTextColor(if (mode == MODE_VIDEO) 0xFFFF3B30.toInt() else 0xFFFFC400.toInt())
textSize = 14f textSize = 14f
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
@ -173,10 +181,11 @@ class M530CameraActivity : ComponentActivity() {
setPadding(dp(10), dp(5), dp(10), dp(5)) setPadding(dp(10), dp(5), dp(10), dp(5))
setBackgroundColor(0x7A000000) setBackgroundColor(0x7A000000)
isClickable = false isClickable = false
visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE
} }
recordDot = TextView(this).apply { recordDot = TextView(this).apply {
text = "●" text = "*"
setTextColor(0xFFFF3B30.toInt()) setTextColor(0xFFFF3B30.toInt())
textSize = 18f textSize = 18f
visibility = View.GONE visibility = View.GONE
@ -203,33 +212,89 @@ class M530CameraActivity : ComponentActivity() {
) )
closeButton = Button(this).apply { closeButton = Button(this).apply {
text = "×" text = "X"
gravity = Gravity.CENTER gravity = Gravity.CENTER
setTextColor(Color.WHITE) setTextColor(Color.WHITE)
textSize = 25f textSize = 18f
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
minWidth = 0 minWidth = 0
minHeight = 0 minHeight = 0
setPadding(0, 0, 0, 0) setPadding(0, 0, 0, 0)
background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1))
background = GradientDrawable().apply {
shape = GradientDrawable.OVAL
setColor(0x99000000.toInt())
setStroke(dp(1), 0xCCFFFFFF.toInt())
}
isClickable = true isClickable = true
isFocusable = true isFocusable = true
elevation = dp(12).toFloat() elevation = dp(8).toFloat()
contentDescription = "Cerrar"
setOnClickListener { setOnClickListener {
stopRecordingIfNeeded() stopRecordingIfNeeded()
finish() finish()
} }
} }
root.addView( root.addView(
closeButton, closeButton,
FrameLayout.LayoutParams(dp(54), dp(54), Gravity.TOP or Gravity.END).apply { FrameLayout.LayoutParams(dp(44), dp(44), Gravity.TOP or Gravity.END).apply {
topMargin = dp(62) topMargin = dp(60)
rightMargin = dp(12) rightMargin = dp(12)
} }
) )
switchCameraButton = Button(this).apply {
text = "CAMARA POSTERIOR"
setTextColor(Color.WHITE)
textSize = 11f
setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER
minWidth = 0
minHeight = 0
setPadding(dp(16), 0, dp(16), 0)
background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = dp(24).toFloat()
setColor(0xB31A1A1A.toInt())
setStroke(dp(1), 0xCCFFFFFF.toInt())
}
visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE
elevation = dp(10).toFloat()
contentDescription = "Cambiar camara"
setOnClickListener {
if (mode == MODE_FRONT_PREVIEW) {
frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera
text = if (frontPreviewUsesFrontCamera)
"CAMARA POSTERIOR"
else
"CAMARA FRONTAL"
startCamera()
}
}
}
root.addView(
switchCameraButton,
FrameLayout.LayoutParams(
dp(170),
dp(46),
Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
).apply {
bottomMargin = dp(76)
}
)
captureButton = Button(this).apply { captureButton = Button(this).apply {
text = if (mode == MODE_VIDEO) "REC" else "FOTO" text = if (mode == MODE_VIDEO) "REC" else "FOTO"
visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE
setTextColor(Color.WHITE) setTextColor(Color.WHITE)
textSize = 15f textSize = 15f
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
@ -289,14 +354,22 @@ class M530CameraActivity : ComponentActivity() {
} }
physicalHintText = TextView(this).apply { physicalHintText = TextView(this).apply {
text = if (mode == MODE_VIDEO) "F5 VIDEO" else "F2 FOTO" text = when (mode) {
MODE_VIDEO -> "F5 VIDEO"
MODE_FRONT_PREVIEW -> "EN VIVO"
else -> "F2 FOTO"
}
setTextColor(if (mode == MODE_VIDEO) 0xFFFF3B30.toInt() else 0xFFFFC400.toInt()) setTextColor(if (mode == MODE_VIDEO) 0xFFFF3B30.toInt() else 0xFFFFC400.toInt())
textSize = 15f textSize = 15f
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
} }
stateText = TextView(this).apply { stateText = TextView(this).apply {
text = if (mode == MODE_VIDEO) "Preparando video..." else "Preparando cámara..." text = when (mode) {
MODE_VIDEO -> "Preparando video..."
MODE_FRONT_PREVIEW -> "Preparando camara frontal..."
else -> "Preparando camara..."
}
setTextColor(Color.WHITE) setTextColor(Color.WHITE)
textSize = 13f textSize = 13f
gravity = Gravity.END or Gravity.CENTER_VERTICAL gravity = Gravity.END or Gravity.CENTER_VERTICAL
@ -335,10 +408,10 @@ class M530CameraActivity : ComponentActivity() {
if (now - lastTouchActionMs < 350) return if (now - lastTouchActionMs < 350) return
lastTouchActionMs = now lastTouchActionMs = now
if (mode == MODE_VIDEO) { when (mode) {
toggleVideoRecording() MODE_VIDEO -> toggleVideoRecording()
} else { MODE_FRONT_PREVIEW -> Unit
takePhoto() else -> takePhoto()
} }
} }
@ -355,7 +428,25 @@ class M530CameraActivity : ComponentActivity() {
provider.unbindAll() provider.unbindAll()
if (mode == MODE_VIDEO) { if (mode == MODE_FRONT_PREVIEW) {
imageCapture = null
videoCapture = null
provider.bindToLifecycle(
this,
if (frontPreviewUsesFrontCamera)
CameraSelector.DEFAULT_FRONT_CAMERA
else
CameraSelector.DEFAULT_BACK_CAMERA,
preview
)
stateText.text = if (frontPreviewUsesFrontCamera)
"Camara frontal lista"
else
"Camara posterior lista"
captureButton.isEnabled = false
} else if (mode == MODE_VIDEO) {
val recorder = Recorder.Builder() val recorder = Recorder.Builder()
.setQualitySelector( .setQualitySelector(
QualitySelector.from( QualitySelector.from(
@ -397,7 +488,7 @@ class M530CameraActivity : ComponentActivity() {
captureButton.isEnabled = true captureButton.isEnabled = true
} }
} catch (t: Throwable) { } catch (t: Throwable) {
stateText.text = "Error de cámara" stateText.text = "Error de camara"
captureButton.isEnabled = false captureButton.isEnabled = false
} }
}, ContextCompat.getMainExecutor(this)) }, ContextCompat.getMainExecutor(this))
@ -405,7 +496,7 @@ class M530CameraActivity : ComponentActivity() {
private fun takePhoto() { private fun takePhoto() {
val capture = imageCapture ?: run { val capture = imageCapture ?: run {
stateText.text = "Cámara no lista" stateText.text = "Camara no lista"
return return
} }
@ -624,7 +715,7 @@ class M530CameraActivity : ComponentActivity() {
chronometer.visibility = View.GONE chronometer.visibility = View.GONE
recordDot.visibility = View.GONE recordDot.visibility = View.GONE
stateText.text = if (error) "Error de grabación" else "Video guardado" stateText.text = if (error) "Error de grabacion" else "Video guardado"
physicalHintText.text = "F5 VIDEO" physicalHintText.text = "F5 VIDEO"
captureButton.text = "REC" captureButton.text = "REC"
@ -641,6 +732,7 @@ class M530CameraActivity : ComponentActivity() {
setBackgroundColor(Color.WHITE) setBackgroundColor(Color.WHITE)
alpha = 0.75f alpha = 0.75f
isClickable = false isClickable = false
visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE
} }
val root = findViewById<FrameLayout>(android.R.id.content) val root = findViewById<FrameLayout>(android.R.id.content)
root.addView( root.addView(
@ -712,3 +804,8 @@ class M530CameraActivity : ComponentActivity() {
private fun timestamp(): String = private fun timestamp(): String =
SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(Date()) SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(Date())
} }

157
apply_front_preview_v2.ps1 Normal file
View file

@ -0,0 +1,157 @@
$cameraPath = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\camera\M530CameraActivity.kt'
$mainPath = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\MainActivity.kt'
$camera = Get-Content $cameraPath -Raw
$main = Get-Content $mainPath -Raw
# ============================================================
# M530CameraActivity.kt
# ============================================================
# 1. Agregar modo FRONT_PREVIEW
$camera = [regex]::Replace(
$camera,
'const val MODE_VIDEO = "video"',
'const val MODE_VIDEO = "video"' + [Environment]::NewLine +
' const val MODE_FRONT_PREVIEW = "front_preview"',
1
)
# 2. Texto superior
$camera = $camera.Replace(
'text = if (mode == MODE_VIDEO) "VIDEO" else "FOTO"',
'text = when (mode) {' + [Environment]::NewLine +
' MODE_VIDEO -> "VIDEO"' + [Environment]::NewLine +
' MODE_FRONT_PREVIEW -> "CAMARA FRONTAL"' + [Environment]::NewLine +
' else -> "FOTO"' + [Environment]::NewLine +
' }'
)
# 3. Ocultar botón de captura cuando sea preview frontal
$camera = $camera.Replace(
'text = if (mode == MODE_VIDEO) "REC" else "FOTO"',
'text = if (mode == MODE_VIDEO) "REC" else "FOTO"' + [Environment]::NewLine +
' visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE'
)
# 4. Texto inferior
$camera = $camera.Replace(
'text = if (mode == MODE_VIDEO) "F5 VIDEO" else "F2 FOTO"',
'text = when (mode) {' + [Environment]::NewLine +
' MODE_VIDEO -> "F5 VIDEO"' + [Environment]::NewLine +
' MODE_FRONT_PREVIEW -> "VISTA EN VIVO"' + [Environment]::NewLine +
' else -> "F2 FOTO"' + [Environment]::NewLine +
' }'
)
# 5. Estado inicial
$camera = [regex]::Replace(
$camera,
'text = if \(mode == MODE_VIDEO\) "Preparando video\.\.\." else ".*?"',
'text = when (mode) {' + [Environment]::NewLine +
' MODE_VIDEO -> "Preparando video..."' + [Environment]::NewLine +
' MODE_FRONT_PREVIEW -> "Preparando camara frontal..."' + [Environment]::NewLine +
' else -> "Preparando camara..."' + [Environment]::NewLine +
' }',
1
)
# 6. Evitar acciones de foto/video en preview frontal
$camera = [regex]::Replace(
$camera,
'if \(mode == MODE_VIDEO\) \{\s*toggleVideoRecording\(\)\s*\} else \{\s*takePhoto\(\)\s*\}',
'when (mode) {' + [Environment]::NewLine +
' MODE_VIDEO -> toggleVideoRecording()' + [Environment]::NewLine +
' MODE_FRONT_PREVIEW -> Unit' + [Environment]::NewLine +
' else -> takePhoto()' + [Environment]::NewLine +
' }',
1
)
# 7. Usar cámara frontal solo en FRONT_PREVIEW
$camera = [regex]::Replace(
$camera,
'(\s*provider\.unbindAll\(\)\s*)if \(mode == MODE_VIDEO\) \{',
'$1if (mode == MODE_FRONT_PREVIEW) {' + [Environment]::NewLine +
' imageCapture = null' + [Environment]::NewLine +
' videoCapture = null' + [Environment]::NewLine +
'' + [Environment]::NewLine +
' provider.bindToLifecycle(' + [Environment]::NewLine +
' this,' + [Environment]::NewLine +
' CameraSelector.DEFAULT_FRONT_CAMERA,' + [Environment]::NewLine +
' preview' + [Environment]::NewLine +
' )' + [Environment]::NewLine +
'' + [Environment]::NewLine +
' stateText.text = "Camara frontal lista"' + [Environment]::NewLine +
' captureButton.isEnabled = false' + [Environment]::NewLine +
' } else if (mode == MODE_VIDEO) {',
1
)
# ============================================================
# MainActivity.kt
# ============================================================
# 8. Variable para abrir la cámara frontal una sola vez por inicio
$main = $main.Replace(
'@Volatile private var isAuthenticated = false',
'@Volatile private var isAuthenticated = false' + [Environment]::NewLine +
' private var frontPreviewOpened = false'
)
# 9. Al detectar sesión válida, abrir preview frontal
$main = [regex]::Replace(
$main,
'authSessionStore\.token\.collect \{ token -> isAuthenticated = !token\.isNullOrBlank\(\) \}',
'authSessionStore.token.collect { token ->' + [Environment]::NewLine +
' isAuthenticated = !token.isNullOrBlank()' + [Environment]::NewLine +
'' + [Environment]::NewLine +
' if (isAuthenticated && !frontPreviewOpened) {' + [Environment]::NewLine +
' frontPreviewOpened = true' + [Environment]::NewLine +
' runOnUiThread {' + [Environment]::NewLine +
' openFrontPreview()' + [Environment]::NewLine +
' }' + [Environment]::NewLine +
' }' + [Environment]::NewLine +
' }',
1
)
# 10. Función para abrir la cámara frontal
$frontFunction = @'
private fun openFrontPreview() {
if (!isAuthenticated) return
startActivity(
android.content.Intent(
this,
com.bodycamera.twentyfoulabs.camera.M530CameraActivity::class.java
).putExtra(
com.bodycamera.twentyfoulabs.camera.M530CameraActivity.EXTRA_MODE,
com.bodycamera.twentyfoulabs.camera.M530CameraActivity.MODE_FRONT_PREVIEW
).addFlags(android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP)
)
}
'@
$main = $main.Replace(
' private fun handlePhotoButton() {',
$frontFunction + ' private fun handlePhotoButton() {'
)
# ============================================================
# Guardar cambios
# ============================================================
Set-Content -Path $cameraPath -Value $camera -Encoding UTF8
Set-Content -Path $mainPath -Value $main -Encoding UTF8
Write-Host ''
Write-Host '=========================================='
Write-Host 'FRONT PREVIEW V2 APLICADO'
Write-Host '=========================================='
Write-Host 'MODE_FRONT_PREVIEW agregado'
Write-Host 'Camara frontal configurada'
Write-Host 'F2 y F5 mantienen camara trasera'
Write-Host ''

View file

@ -0,0 +1,174 @@
$path = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\camera\M530CameraActivity.kt'
$c = Get-Content $path -Raw
# ---------------------------------------------------------
# Import para fondos redondeados
# ---------------------------------------------------------
if ($c -notmatch 'import android\.graphics\.drawable\.GradientDrawable') {
$c = $c.Replace(
'import android.graphics.Typeface',
"import android.graphics.Typeface`r`nimport android.graphics.drawable.GradientDrawable"
)
}
# ---------------------------------------------------------
# Boton CERRAR
# ---------------------------------------------------------
$oldClose = @'
closeButton = Button(this).apply {
text = "X"
gravity = Gravity.CENTER
setTextColor(Color.WHITE)
textSize = 25f
setTypeface(typeface, Typeface.BOLD)
minWidth = 0
minHeight = 0
setPadding(0, 0, 0, 0)
background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1))
isClickable = true
isFocusable = true
elevation = dp(12).toFloat()
setOnClickListener {
stopRecordingIfNeeded()
finish()
}
}
root.addView(
closeButton,
FrameLayout.LayoutParams(dp(54), dp(54), Gravity.TOP or Gravity.END).apply {
topMargin = dp(62)
rightMargin = dp(12)
}
)
'@
$newClose = @'
closeButton = Button(this).apply {
text = "X"
gravity = Gravity.CENTER
setTextColor(Color.WHITE)
textSize = 18f
setTypeface(typeface, Typeface.BOLD)
minWidth = 0
minHeight = 0
setPadding(0, 0, 0, 0)
background = GradientDrawable().apply {
shape = GradientDrawable.OVAL
setColor(0x99000000.toInt())
setStroke(dp(1), 0xCCFFFFFF.toInt())
}
isClickable = true
isFocusable = true
elevation = dp(8).toFloat()
contentDescription = "Cerrar"
setOnClickListener {
stopRecordingIfNeeded()
finish()
}
}
root.addView(
closeButton,
FrameLayout.LayoutParams(dp(44), dp(44), Gravity.TOP or Gravity.END).apply {
topMargin = dp(60)
rightMargin = dp(12)
}
)
'@
$c = $c.Replace($oldClose, $newClose)
# ---------------------------------------------------------
# Boton CAMBIAR CAMARA
# ---------------------------------------------------------
$oldSwitch = @'
switchCameraButton = Button(this).apply {
text = "CAMBIAR"
setTextColor(Color.WHITE)
textSize = 12f
setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER
minWidth = 0
minHeight = 0
setPadding(dp(8), 0, dp(8), 0)
background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1))
visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE
elevation = dp(12).toFloat()
setOnClickListener {
if (mode == MODE_FRONT_PREVIEW) {
frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera
startCamera()
}
}
}
root.addView(
switchCameraButton,
FrameLayout.LayoutParams(dp(110), dp(48), Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL).apply {
bottomMargin = dp(76)
}
)
'@
$newSwitch = @'
switchCameraButton = Button(this).apply {
text = "CAMARA POSTERIOR"
setTextColor(Color.WHITE)
textSize = 11f
setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER
minWidth = 0
minHeight = 0
setPadding(dp(16), 0, dp(16), 0)
background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = dp(24).toFloat()
setColor(0xB31A1A1A.toInt())
setStroke(dp(1), 0xCCFFFFFF.toInt())
}
visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE
elevation = dp(10).toFloat()
contentDescription = "Cambiar camara"
setOnClickListener {
if (mode == MODE_FRONT_PREVIEW) {
frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera
text = if (frontPreviewUsesFrontCamera)
"CAMARA POSTERIOR"
else
"CAMARA FRONTAL"
startCamera()
}
}
}
root.addView(
switchCameraButton,
FrameLayout.LayoutParams(
dp(170),
dp(46),
Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
).apply {
bottomMargin = dp(76)
}
)
'@
$c = $c.Replace($oldSwitch, $newSwitch)
Set-Content -Path $path -Value $c -Encoding UTF8
Write-Host ""
Write-Host "=========================================="
Write-Host "UI DE CAMARA ACTUALIZADA"
Write-Host "=========================================="
Write-Host ""