39

I would like to detect when a user refused the microphone permission on my iOS application. I only get this value when I try to record the microphone: -120.000000 db

But before to get this I have to set up an AVAudioSession. Is there another function?

And I got this message in the output: Microphone input permission refused - will record only silence

Thanks.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
Benoît Freslon
  • 2,021
  • 4
  • 26
  • 35
  • Possible duplicate of [iOS check if application has access to microphone](https://stackoverflow.com/questions/24981333/ios-check-if-application-has-access-to-microphone) – pkamb Oct 28 '21 at 16:20

4 Answers4

51

If you are still compiling with iOS SDK 6.0 (as I am) you have to be a bit more indirect than @Luis E. Prado, as the requestRecordPermission method doesn't exist.

Here's how I did it. Remove the autorelease bit if you're using ARC. On iOS6 nothing happens, and on iOS7 either the 'microphone is enabled' message is logged or the alert is popped up.

AVAudioSession *session = [AVAudioSession sharedInstance];
if ([session respondsToSelector:@selector(requestRecordPermission:)]) {
    [session performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
        if (granted) {
            // Microphone enabled code
            NSLog(@"Microphone is enabled..");
        }
        else {
            // Microphone disabled code
            NSLog(@"Microphone is disabled..");

            // We're in a background thread here, so jump to main thread to do UI work.
            dispatch_async(dispatch_get_main_queue(), ^{
                [[[[UIAlertView alloc] initWithTitle:@"Microphone Access Denied"
                                        message:@"This app requires access to your device's Microphone.\n\nPlease enable Microphone access for this app in Settings / Privacy / Microphone"
                                       delegate:nil
                              cancelButtonTitle:@"Dismiss"
                              otherButtonTitles:nil] autorelease] show];
            });
        }
    }];
}

EDIT: It turns out that the withObject block is executed in a background thread, so DO NOT do any UI work in there, or your app may hang. I've adjusted the code above. A client pointed this out on what was thankfully a beta release. Apologies for the mistake.

Paresh Navadiya
  • 38,095
  • 11
  • 81
  • 132
Ben Clayton
  • 80,996
  • 26
  • 120
  • 129
  • I got a problem with this solution on iPad Air (only). Do you know if exists some additional configuration with this kind of device? – Beto Feb 19 '14 at 20:24
  • @BetoBens I haven't heard of anything specific to that model. What's the problem? – Ben Clayton Feb 19 '14 at 21:23
  • When I record to a file using built-in microphone in the iPad Air, the file is created but when I playback no sound is heard and the playback never stops and only happens with this device. It's so weird. – Beto Feb 19 '14 at 23:22
  • 1
    I fix it. When RecordSound in iPadAir i must remove AVEncoderBitRateKey from settings session. I suppose is must be related about several microphones because I can't selected a different mic to save my sound file. – Beto Feb 19 '14 at 23:38
  • Your edit about the block being performed in a background thread must have changed? I put a breakpoint in the block and it is pretty clearly being performed in the main thread. I moved my UI related code in the block to the main thread just in case – Kyle Jurick Mar 03 '14 at 18:58
  • @KyleJurick That's odd, it was clearly in a non-ui thread when I tried it, and caused a nasty hang as a result. Perhaps either the thread used varies, or it behaves differently in a newer iOS version. – Ben Clayton Mar 04 '14 at 10:02
  • 1
    @BenClayton We all know that Apple likes to change things like this without release notes :) – Kyle Jurick Mar 04 '14 at 16:32
42

Please note that this will only work if built with Xcode 5, and not with 4.6

Add the AVFoundation Framework to your project

Then import the AVAudioSession header file, from the AVFoundation framework, where you intend to check if the microphone setting is enabled

#import <AVFoundation/AVAudioSession.h>

Then simply call this method

[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
            if (granted) {
                // Microphone enabled code
            }
            else {
                // Microphone disabled code
            }
        }];

The first time this method runs, it will show the prompt to allow microphone access and based on the users response it will execute the completion block. From the second time onwards it will just act based on the stored setting on the device.

Luis E. Prado
  • 2,131
  • 2
  • 16
  • 12
  • 1
    Note that this method is only available on iOS7 and above. https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/occ/instm/AVAudioSession/requestRecordPermission: – Ben Clayton Sep 30 '13 at 08:26
3

Swift answer:

if AVAudioSession.sharedInstance().recordPermission() == .Denied {
    print("Microphone permission refused");
}

Or you can use framework like PermissionScope which permit to easily check permissions. https://github.com/nickoneill/PermissionScope

Edit: Swift 3 answer:

import AVFoundation
...
if AVAudioSession.sharedInstance().recordPermission() == .denied {
    print("Microphone permission refused");
}
Floris M
  • 1,764
  • 19
  • 18
0

I'm not 100% certain if we're allowed to talk about iOS 7 outside of Apple's devforums, but I found the answer you're looking for there.

In short, you'll find your solution in the AVAudioSession.h header file in the SDK. And if you want to make use of it while still supporting iOS 6, make certain to use "respondsToSelector:" to check for the API availability.

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215