Los permisos son cruciales al construir aplicaciones móviles que requieren acceso a funciones del dispositivo, como ubicación, cámara, contactos, y más. En Flutter, manejar estos permisos de manera efectiva garantiza que la aplicación ofrezca una experiencia de usuario fluida mientras se adhiere a los requisitos de privacidad y seguridad. Un paquete popular para gestionar permisos en Flutter es permission_handler
.
Este artículo te guiará a través de cómo solicitar, verificar y manejar diferentes permisos en Flutter utilizando permission_handler
, con ejemplos prácticos basados en permission_handler
.
Instalando permission_handler
y fluttertoast
Primero, agrega el paquete permission_handler
y fluttertoast
a tu archivo pubspec.yaml
:
dependencies:
permission_handler: ^11.3.1
fluttertoast: ^8.2.4
Luego, ejecuta:
flutter pub get
Manejo de Permisos en Flutter
El paquete permission_handler
proporciona una forma sencilla de solicitar permisos y verificar sus estados. A continuación se presenta un desglose completo sobre cómo manejar diferentes permisos como llamadas telefónicas, contactos, ubicación, SMS y cámara/micrófono.
El Controlador de Permisos puede manejar todos estos tipos de permisos: Calendario, Cámara, Contactos, Ubicación, Biblioteca de Medios, Micrófono, Teléfono, Fotos, Recordatorios, Sensores, SMS, Reconocimiento de Voz, Almacenamiento, Ignorar Optimizaciones de Batería, Notificaciones, Acceso a la Ubicación de Medios, Reconocimiento de Actividad, Permisos de Bluetooth, Administrar Almacenamiento Externo, Ventana de Alerta del Sistema, Solicitar Instalación de Paquetes, Transparencia de Seguimiento de Aplicaciones, Alertas Críticas, Acceso a la Política de Notificaciones, Dispositivos Wi-Fi Cercanos, Audio, Programar Alarma Exacta, Sensores Siempre, Solo Lectura de Calendario y Acceso Completo al Calendario pero vamos a cubrir algunos en este artículo.
A continuación se muestra una guía detallada sobre cómo solicitar cada tipo de permiso, manejar escenarios como el rechazo o el rechazo permanente, y a qué otorga acceso cada permiso.
1. Permisos de Calendario
-
Permisos:
calendar
,calendarReadOnly
,calendarFullAccess
-
Caso de Uso: Acceder al calendario del usuario para leer o escribir eventos.
Future<void> requestCalendarPermission() async {
var status = await Permission.calendar.request();
if (status.isGranted) {
// Permission granted, proceed with calendar access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Calendar permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Calendar permission denied',
);
}
}
2. Permisos de Cámara
-
Permiso:
cámara
-
Caso de Uso: Acceder a la cámara del dispositivo para capturar fotos o videos.
Future<void> requestCameraPermission() async {
var status = await Permission.camera.request();
if (status.isGranted) {
// Permission granted, proceed with camera access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Camera permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Camera permission denied',
);
}
}
3. Permisos de Contactos
-
Permiso:
contacts
-
Caso de Uso: Acceder a la lista de contactos del usuario para leer o modificar contactos.
Future<void> requestContactsPermission() async {
var status = await Permission.contacts.request();
if (status.isGranted) {
// Permission granted, proceed with contacts access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Contacts permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Contacts permission denied',
);
}
}
4. Permisos de Ubicación
-
Permisos:
location
,locationAlways
,locationWhenInUse
,accessMediaLocation
-
Caso de Uso: Acceder a la ubicación del usuario para navegación, geovallado o servicios cercanos.
Future<void> requestLocationPermission() async {
var status = await Permission.location.request();
if (status.isGranted) {
// Permission granted, proceed with location access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Location permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Location permission denied',
);
}
}
5. Permisos de Biblioteca Multimedia
-
Permiso:
mediaLibrary
-
Caso de Uso: Acceder a la biblioteca multimedia del usuario (solo en iOS).
Future<void> requestMediaLibraryPermission() async {
var status = await Permission.mediaLibrary.request();
if (status.isGranted) {
// Permission granted, proceed with media library access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Media Library permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Media Library permission denied',
);
}
}
6. Permisos de Micrófono
-
Permiso:
microphone
-
Caso de Uso: Acceder al micrófono del dispositivo para grabar audio.
Future<void> requestMicrophonePermission() async {
var status = await Permission.microphone.request();
if (status.isGranted) {
// Permission granted, proceed with microphone access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Microphone permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Microphone permission denied',
);
}
}
7. Permisos del Teléfono
-
Permiso:
teléfono
-
Caso de Uso: Hacer llamadas telefónicas, leer el estado del teléfono o acceder a los registros de llamadas.
Future<void> requestPhonePermission() async {
var status = await Permission.phone.request();
if (status.isGranted) {
// Permission granted, proceed with phone access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Phone permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Phone permission denied',
);
}
}
8. Permisos de Fotos
-
Permisos:
fotos
,soloAgregarFotos
-
Caso de Uso: Acceder a la biblioteca de fotos del usuario para leer o agregar fotos.
Future<void> requestPhotosPermission() async {
var status = await Permission.photos.request();
if (status.isGranted) {
// Permission granted, proceed with photos access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Photos permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Photos permission denied',
);
}
}
9. Permisos de Recordatorios
-
Permiso:
recordatorios
-
Caso de Uso: Acceder y gestionar recordatorios en el dispositivo del usuario.
Future<void> requestRemindersPermission() async {
var status = await Permission.reminders.request();
if (status.isGranted) {
// Permission granted, proceed with reminders access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Reminders permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Reminders permission denied',
);
}
}
10. Permisos de Sensores
-
Permisos:
sensores
,sensoresSiempre
-
Caso de Uso: Acceder a los sensores del dispositivo como el acelerómetro y giroscopio.
Future<void> requestSensorsPermission() async {
var status = await Permission.sensors.request();
if (status.isGranted) {
// Permission granted, proceed with sensors access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Sensors permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Sensors permission denied',
);
}
}
11. Permisos de SMS
-
Permiso:
sms
-
Caso de Uso: Acceder a funciones de SMS, incluyendo leer o enviar mensajes de texto.
Future<void> requestSmsPermission() async {
var status = await Permission.sms.request();
if (status.isGranted) {
// Permission granted, proceed with SMS access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'SMS permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'SMS permission denied',
);
}
}
12. Permisos de Reconocimiento de Voz
-
Permiso:
speech
-
Caso de Uso: Acceder a funciones de reconocimiento de voz a texto.
Future<void> requestSpeechPermission() async {
var status = await Permission.speech.request();
if (status.isGranted) {
// Permission granted, proceed with speech recognition
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Speech recognition permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Speech recognition permission denied',
);
}
}
13. Permisos de Almacenamiento
-
Permisos:
storage
,manageExternalStorage
-
Caso de Uso: Acceder al almacenamiento interno o externo del usuario para leer o escribir archivos.
Future<void> requestStoragePermission() async {
var status = await Permission.storage.request();
if (status.isGranted) {
// Permission granted, proceed with storage access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Storage permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Storage permission denied',
);
}
}
14. Ignorar Optimizaciones de Batería
-
Permiso:
ignorarOptimizacionesDeBatería
-
Caso de Uso: Solicitar al sistema que excluya la aplicación de las medidas de optimización de batería.
Future<void> requestIgnoreBatteryOptimizationsPermission() async {
var status = await Permission.ignoreBatteryOptimizations.request();
if (status.isGranted) {
// Permission granted, proceed with ignoring battery optimizations
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Battery optimization permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Battery optimization permission denied',
);
}
}
15. Permisos de Notificación
-
Permiso:
notificación
-
Caso de Uso: Permitir que tu aplicación envíe notificaciones.
Future<void> requestNotificationPermission() async {
var status = await Permission.notification.request();
if (status.isGranted) {
// Permission granted, proceed with notifications access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Notification permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Notification permission denied',
);
}
}
16. Permisos de Bluetooth
-
Permisos:
bluetooth
,bluetoothScan
,bluetoothAdvertise
,bluetoothConnect
-
Caso de Uso: Acceder a las funciones de Bluetooth para conectar o gestionar dispositivos Bluetooth.
Future<void> requestBluetoothPermission() async {
var status = await Permission.bluetooth.request();
if (status.isGranted) {
// Permission granted, proceed with Bluetooth access
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'Bluetooth permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'Bluetooth permission denied',
);
}
}
17. Transparencia de Seguimiento de Aplicaciones
-
Permiso:
transparenciaSeguimientoAplicaciones
-
Caso de uso: Solicitar permiso de seguimiento al usuario, un requisito para el seguimiento de la aplicación en iOS.
Future<void> requestAppTrackingTransparencyPermission() async {
var status = await Permission.appTrackingTransparency.request();
if (status.isGranted) {
// Permission granted, proceed with app tracking
} else if (status.isPermanentlyDenied) {
ShowToast.showErrorText(
text: 'App tracking permission permanently denied. Please enable it in the app settings.',
);
openAppSettings();
} else {
ShowToast.showErrorText(
text: 'App tracking permission denied',
);
}
}
Los permisos juegan un papel crítico en proporcionar a los usuarios una experiencia fluida respetando su privacidad. Es esencial manejar estos permisos de manera cuidadosa y educar a los usuarios sobre por qué su aplicación los requiere.
Al utilizar el paquete permission_handler
, puedes solicitar, verificar y gestionar todos los permisos necesarios para tu aplicación Flutter en plataformas Android e iOS. Siempre proporciona a los usuarios comentarios significativos y considera agregar flujos alternativos en caso de que se nieguen o se revoquen los permisos.
Configuraciones de Android e iOS
Es fundamental incluir las configuraciones necesarias de Android e iOS. Para Android, esto implica actualizar el archivo AndroidManifest.xml
con las declaraciones de permisos correctas. Para iOS, las descripciones de uso de permisos deben agregarse al archivo Info.plist
para informar a los usuarios por qué se solicitan ciertos permisos.
Configuración de AndroidManifest.xml
en Android
Para cada permiso en los 17 ejemplos, debes agregar la etiqueta correspondiente <uses-permission>
en el archivo AndroidManifest.xml
. Así es como los permisos se alinean con el paquete permission_handler
:
-
Permiso de la cámara
<uses-permission android:name="android.permission.CAMERA" />
-
Permiso de contactos
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-
Permisos de ubicación
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
-
Permiso de Biblioteca/Almacenamiento de Medios
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage"/> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
-
Permiso de Micrófono
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Permiso de teléfono
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
-
Permiso de fotos
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
Permiso de recordatorios (Sin permiso explícito de Android)
-
Permiso de sensores
<uses-permission android:name="android.permission.BODY_SENSORS" />
-
Permiso de SMS
<uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" />
-
Permiso de Reconocimiento de Voz
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Omitir Optimizaciones de Batería
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
-
Permiso de Notificaciones (Manejado nativamente en Android 13+)
-
Permiso de acceso a la ubicación de los medios
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
-
Permiso de reconocimiento de actividad
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
-
Permisos de Bluetooth
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
-
Permiso de Transparencia de Seguimiento de Aplicaciones (solo iOS)
Configuración de Info.plist
para iOS
Para iOS, debes proporcionar claves descriptivas en el archivo Info.plist
para informar a los usuarios por qué tu aplicación necesita permisos específicos. A continuación se muestran las configuraciones para cada ejemplo de permiso:
-
Permiso de Cámara
<key>NSCameraUsageDescription</key> <string>Necesitamos acceso a tu cámara para tomar fotos.</string>
-
Permiso de Contactos
<key>NSContactsUsageDescription</key> <string>Necesitamos acceso a tus contactos para una mejor comunicación.</string>
-
Permisos de Ubicación
<key>NSLocationWhenInUseUsageDescription</key> <string>Necesitamos acceso a tu ubicación para proporcionar servicios basados en la ubicación.</string> <key>NSLocationAlwaysUsageDescription</key> <string>Necesitamos acceso a tu ubicación para rastrear tu movimiento incluso cuando la aplicación no está activa.</string>
-
Permiso de Biblioteca de Medios/Almacenamiento
<key>NSPhotoLibraryUsageDescription</key> <string>Necesitamos acceso a tus fotos para compartir o subir medios.</string>
-
Permiso de micrófono
<key>NSMicrophoneUsageDescription</key> <string>Necesitamos acceso a tu micrófono para grabación de voz.</string>
-
Permiso de teléfono
<key>NSPhoneUsageDescription</key> <string>Necesitamos acceso a los servicios telefónicos para habilitar llamadas.</string>
-
Permiso de Fotos
<key>NSPhotoLibraryAddUsageDescription</key> <string>Necesitamos permiso para agregar fotos a tu biblioteca.</string>
-
Permiso de Recordatorios
<key>NSRemindersUsageDescription</key> <string>Necesitamos acceso a tus recordatorios para la gestión de tareas.</string>
-
Permiso de Sensores
<key>NSSensorsUsageDescription</key> <string>Necesitamos acceso a tus sensores para el seguimiento de actividad física.</string>
-
Permiso de SMS (Se gestiona automáticamente por iOS si se solicitan servicios de SMS)
-
Permiso de Reconocimiento de Voz
<key>NSSpeechRecognitionUsageDescription</key>
<string>We need access to speech recognition for voice commands.</string>
-
Ignorar Optimización de Batería (No aplicable en iOS)
-
Permiso de Notificaciones
<key>NSUserNotificationUsageDescription</key>
<string>We need permission to send notifications.</string>
-
Permiso de Acceso a la Ubicación de Medios (Se gestiona automáticamente en iOS)
-
Permiso de Reconocimiento de Actividad
<key>NSMotionUsageDescription</key>
<string>We need access to motion data for fitness tracking.</string>
- Permisos de Bluetooth
<key>NSBluetoothPeripheralUsageDescription</key>
<string>We need access to Bluetooth for device connectivity.</string>
- Transparencia en el seguimiento de aplicaciones
<key>NSUserTrackingUsageDescription</key>
<string>We need permission to track your activity across apps and websites for personalized ads.</string>
Para que tu aplicación sea completamente funcional y cumpla con las últimas regulaciones de privacidad, es esencial gestionar correctamente los permisos. Al actualizar tanto el archivo AndroidManifest.xml
como Info.plist
, y al implementar la lógica correcta de manejo de permisos en tu aplicación Flutter, proporcionas una experiencia fluida y transparente para los usuarios al solicitar acceso a funciones sensibles.
Siempre asegúrate de probar los permisos en ambas plataformas y proporcionar explicaciones significativas a los usuarios sobre por qué se necesitan los permisos para evitar el rechazo durante las revisiones de la tienda de aplicaciones.
Para una investigación más profunda, considera consultar la documentación oficial del manejador de permisos para explorar otros tipos de permisos. Asegúrate también de actualizar tus archivos específicos de plataforma (como AndroidManifest.xml
y Info.plist
) con las declaraciones necesarias para cada tipo de permiso.
Source:
https://atuoha.hashnode.dev/permission-handling-in-flutter