ANDROID_BUILD_INSTRUCTIONS
Solución: Bloqueo de Permisos READ_MEDIA_*
Problema
Google Play rechaza READ_MEDIA_IMAGES y READ_MEDIA_VIDEO para apps con uso ocasional de fotos.
Solución Implementada
AndroidManifest.xml - Bloqueo Explícito
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" tools:node="remove" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
Esto bloquea los permisos que las dependencias de androidx.camera intentan agregar.
Funcionalidad
- Cámara: Funciona normalmente (abre directamente por defecto)
- Galería: Disponible con
getPhoto({ source: 'PHOTOS' })- Android 13+: Photo Picker (sin permisos)
- Android 12-: READ_EXTERNAL_STORAGE limitado
Build
# Limpiar
cd android && ./gradlew clean && cd ..
# Build completo
npm run build:www
npx cap sync android
cd android && ./gradlew bundleRelease
# Verificar permisos
npm run verify:android-permissions
Verificación Manual
# Ver permisos en el AAB/APK
aapt dump permissions android/app/build/outputs/bundle/release/app-release.aab | grep READ_MEDIA
Resultado esperado: No debe aparecer READ_MEDIA_IMAGES ni READ_MEDIA_VIDEO
Si Google Play Sigue Rechazando
- Verifica el manifest merged:
cat android/app/build/intermediates/merged_manifests/release/AndroidManifest.xml | grep -E "READ_MEDIA|READ_EXTERNAL"
-
Incrementa versionCode en
android/app/build.gradle -
Build limpio completo:
cd android
rm -rf .gradle app/build
./gradlew clean
cd ..
npm run build:www
npx cap sync android
cd android && ./gradlew bundleRelease
Declaración para Google Play
Si detecta READ_EXTERNAL_STORAGE:
Permiso: READ_EXTERNAL_STORAGE (maxSdkVersion 32)
Justificación:
"Compatibilidad con Android 12 y anteriores para selección de fotos. Android 13+ usa Photo Picker sin permisos."
Uso
// Cámara directa (default)
await getPhoto()
// Selector cámara/galería
await getPhoto({ source: 'PROMPT' })
// Solo galería
await getPhoto({ source: 'PHOTOS' })