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
@Volatile private var isAuthenticated = false
private var frontPreviewOpened = false
companion object {
private const val TAG = "MainActivity"
@ -97,7 +98,16 @@ class MainActivity : ComponentActivity() {
})
lifecycleScope.launch {
authSessionStore.token.collect { token -> isAuthenticated = !token.isNullOrBlank() }
authSessionStore.token.collect { token ->
isAuthenticated = !token.isNullOrBlank()
if (isAuthenticated && !frontPreviewOpened) {
frontPreviewOpened = true
runOnUiThread {
openFrontPreview()
}
}
}
}
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() {
startActivity(
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.content.ContentValues
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.Bundle
import android.os.SystemClock
@ -54,6 +55,7 @@ class M530CameraActivity : ComponentActivity() {
const val EXTRA_MODE = "mode"
const val MODE_PHOTO = "photo"
const val MODE_VIDEO = "video"
const val MODE_FRONT_PREVIEW = "front_preview"
}
private lateinit var previewView: PreviewView
@ -63,6 +65,7 @@ class M530CameraActivity : ComponentActivity() {
private lateinit var physicalHintText: TextView
private lateinit var captureButton: Button
private lateinit var closeButton: Button
private lateinit var switchCameraButton: Button
private lateinit var recordDot: TextView
private lateinit var chronometer: Chronometer
@ -73,10 +76,11 @@ class M530CameraActivity : ComponentActivity() {
private var cameraProvider: ProcessCameraProvider? = null
private var lastPhysicalActionMs = 0L
private var lastTouchActionMs = 0L
private var frontPreviewUsesFrontCamera = true
private val cameraPermissionLauncher =
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 =
@ -140,7 +144,11 @@ class M530CameraActivity : ComponentActivity() {
}
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())
textSize = 14f
setTypeface(typeface, Typeface.BOLD)
@ -173,10 +181,11 @@ class M530CameraActivity : ComponentActivity() {
setPadding(dp(10), dp(5), dp(10), dp(5))
setBackgroundColor(0x7A000000)
isClickable = false
visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE
}
recordDot = TextView(this).apply {
text = "●"
text = "*"
setTextColor(0xFFFF3B30.toInt())
textSize = 18f
visibility = View.GONE
@ -203,33 +212,89 @@ class M530CameraActivity : ComponentActivity() {
)
closeButton = Button(this).apply {
text = "×"
text = "X"
gravity = Gravity.CENTER
setTextColor(Color.WHITE)
textSize = 25f
textSize = 18f
setTypeface(typeface, Typeface.BOLD)
minWidth = 0
minHeight = 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
isFocusable = true
elevation = dp(12).toFloat()
elevation = dp(8).toFloat()
contentDescription = "Cerrar"
setOnClickListener {
stopRecordingIfNeeded()
finish()
}
}
root.addView(
closeButton,
FrameLayout.LayoutParams(dp(54), dp(54), Gravity.TOP or Gravity.END).apply {
topMargin = dp(62)
FrameLayout.LayoutParams(dp(44), dp(44), Gravity.TOP or Gravity.END).apply {
topMargin = dp(60)
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 {
text = if (mode == MODE_VIDEO) "REC" else "FOTO"
visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE
setTextColor(Color.WHITE)
textSize = 15f
setTypeface(typeface, Typeface.BOLD)
@ -289,14 +354,22 @@ class M530CameraActivity : ComponentActivity() {
}
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())
textSize = 15f
setTypeface(typeface, Typeface.BOLD)
}
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)
textSize = 13f
gravity = Gravity.END or Gravity.CENTER_VERTICAL
@ -335,10 +408,10 @@ class M530CameraActivity : ComponentActivity() {
if (now - lastTouchActionMs < 350) return
lastTouchActionMs = now
if (mode == MODE_VIDEO) {
toggleVideoRecording()
} else {
takePhoto()
when (mode) {
MODE_VIDEO -> toggleVideoRecording()
MODE_FRONT_PREVIEW -> Unit
else -> takePhoto()
}
}
@ -355,7 +428,25 @@ class M530CameraActivity : ComponentActivity() {
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()
.setQualitySelector(
QualitySelector.from(
@ -397,7 +488,7 @@ class M530CameraActivity : ComponentActivity() {
captureButton.isEnabled = true
}
} catch (t: Throwable) {
stateText.text = "Error de cámara"
stateText.text = "Error de camara"
captureButton.isEnabled = false
}
}, ContextCompat.getMainExecutor(this))
@ -405,7 +496,7 @@ class M530CameraActivity : ComponentActivity() {
private fun takePhoto() {
val capture = imageCapture ?: run {
stateText.text = "Cámara no lista"
stateText.text = "Camara no lista"
return
}
@ -624,7 +715,7 @@ class M530CameraActivity : ComponentActivity() {
chronometer.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"
captureButton.text = "REC"
@ -641,6 +732,7 @@ class M530CameraActivity : ComponentActivity() {
setBackgroundColor(Color.WHITE)
alpha = 0.75f
isClickable = false
visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE
}
val root = findViewById<FrameLayout>(android.R.id.content)
root.addView(
@ -712,3 +804,8 @@ class M530CameraActivity : ComponentActivity() {
private fun timestamp(): String =
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 ""