Search code examples
iosflutterxcodemobileios-permissions

Permissions not working even though they are in info.plist for Camera & Microphone


I have a video meeting feature in my Flutter App, before users start a meeting they have to check that their Microphone and Camera permissions are enabled or they can't join the meeting.

      builder: (context) {
        return AlertDialog(
          title: const Text("Permissions Required"),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const Text(
                  "The following permissions are needed for video calls:"),
              if (!micEnabled)
                Text(
                    "• Microphone: ${!micEnabled ? 'Not granted' : 'Granted'}"),
              if (!cameraEnabled)
                Text("• Camera: ${!cameraEnabled ? 'Not granted' : 'Granted'}"),
              const SizedBox(height: 8),
              const Text(
                "Please grant these permissions in your device settings to continue.",
                style: TextStyle(fontSize: 12),
              ),
            ],
          ),
          actions: <Widget>[
            TextButton(
              child: const Text("Try Again"),
              onPressed: () {
                Navigator.of(context).pop();
                _getPermissions();
              },
            ),
            TextButton(
              child: const Text("Open Settings"),
              onPressed: () async {
                Navigator.of(context).pop();
                await openAppSettings();
              },
            ),
          ],
        );
      },
  Future<bool> _getPermissions() async {
    print('Starting permission checks...');

    try {
      // Check current status first
      final micStatus = await Permission.microphone.status;
      final cameraStatus = await Permission.camera.status;
      print(
          'Initial permission status - Mic: $micStatus, Camera: $cameraStatus');

      // Update state based on current status
      setState(() {
        _isMicEnabled = micStatus.isGranted;
        _isCameraEnabled = cameraStatus.isGranted;
      });

      print('after setState - Mic: $_isMicEnabled, Camera: $_isCameraEnabled');

      // Request permissions if not already granted
      print('Requesting permissions if needed...');
      print('going to get mic permissions');
      if (!_isMicEnabled) {
        await _getMicPermissions();
      }
      print('going to get camera permissions');
      if (!_isCameraEnabled) {
        await _getCameraPermissions();
      }

      // If we still don't have permissions after requesting, show settings dialog
      if (!_isMicEnabled || !_isCameraEnabled) {
        if (context.mounted) {
          _showPermissionDeniedDialog(context, _isMicEnabled, _isCameraEnabled);
        }
        return false;
      }

      return true;
    } catch (e) {
      print('Error getting permissions: $e');
      return false;
    }
  }

I have the necessary permissions in my info.plist:

    <key>NSCameraUsageDescription</key>
    <string>We need access to your camera for video calls and capturing photos</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>We need access to your microphone for voice calls and voice messages</string>

But it always tells me that I don't have the permissions enabled and I need to open my device settings, and then when i open the settings those permissions are not there.

flutter: Starting permission checks... flutter: Initial permission status - Mic: PermissionStatus.denied, Camera: PermissionStatus.denied flutter: after setState - Mic: false, Camera: false flutter: Requesting permissions if needed... flutter: going to get mic permissions flutter: Getting mic permissions flutter: Current mic status: PermissionStatus.denied flutter: after setState for mic - Mic: false, Camera: false flutter: Mic permission request result: PermissionStatus.permanentlyDenied flutter: going to get camera permissions flutter: Getting camera permissions flutter: Current camera status: PermissionStatus.denied flutter: after setState for camera - Mic: false, Camera: false flutter: Camera permission request result: PermissionStatus.permanentlyDenied

I can see it says that my permissions are permanently denied but how do i fix this?

For the record I have the app deployed on iOS and Android with the same code and it works fine on Android with this code.

I don't think there's anything wrong with my code but I'm not sure what I'm missing that I need to check.

I hate iOS development and I hate XCode.


Solution

  • Since it works on Android and not iOS, then we can assume the permission handler was set correctly

    For iOS, you can add this code snippet to ios/Podfile

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        flutter_additional_ios_build_settings(target)
        target.build_configurations.each do |config|
          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
            '$(inherited)',
            'PERMISSION_CAMERA=1',
            'PERMISSION_MICROPHONE=1'
          ]
        end
      end
    end
    

    In your terminal run

    cd ios
    pod install --repo-update
    cd ..
    

    Also update your code to call .request()

     Future<bool> _getPermissions() async {
        print('Starting permission checks...');
    
        try {
          // Check current status first
          PermissionStatus cameraStatus = await Permission.camera.request();
          PermissionStatus micStatus = await Permission.microphone.request();
          print(
              'Initial permission status - Mic: $micStatus, Camera: $cameraStatus');
    
          // Update state based on current status
          setState(() {
            _isMicEnabled = micStatus.isGranted;
            _isCameraEnabled = cameraStatus.isGranted;
          });
    
          print('after setState - Mic: $_isMicEnabled, Camera: $_isCameraEnabled');
    
          // Request permissions if not already granted
          print('Requesting permissions if needed...');
          print('going to get mic permissions');
          if (!_isMicEnabled) {
            await _getMicPermissions();
          }
          print('going to get camera permissions');
          if (!_isCameraEnabled) {
            await _getCameraPermissions();
          }
    
          // If we still don't have permissions after requesting, show settings dialog
          if (!_isMicEnabled || !_isCameraEnabled) {
            if (context.mounted) {
              _showPermissionDeniedDialog(context, _isMicEnabled, _isCameraEnabled);
            }
            return false;
          }
    
          return true;
        } catch (e) {
          print('Error getting permissions: $e');
          return false;
        }
      }