I am working on an iPad app that connects with an accessory that plays sound. When the iPad is connected to the accessory, I would like to mute all system sounds but allow other sounds (iPod).
Part of the reason for this is that the accessory is such that it is intended to be used during a live performance. Clearly it would be annoying to have e-mail, alert, or any other system sound running through and amplified (crazy loud).
I have looked at using AVAudioSession (read Audio Sessions to learn more) and tried all of the AudioSessionCategories. None of these categories will mute the system sound, instead it will only allow you to mute application sounds (iPod) - not useful for my purposes.
I also found docs on "System Sound Services", but this only allows you to play system sounds. There is no api here to disable system sounds while your app is running.
A final note, we have made it easy to adjust the iPad level (volume) by including the MPVolumeView, but we expect the user to want to play iPod music. If while playing iPod music (or music from another app) and an e-mail comes through, you'd be amazed how LOUD / ANNOYING that e-mail suddenly becomes when going through our accessory. It's even possible it could damage equipment. :D
It is possible to change the system sounds, which turns out to be the ringer btw, using the AVSystemController. However, AVSystemController exists in the private Celestial framework. Since this framework is referenced by UIKit, it is still possible to use this class without directly referencing it.
Apple prohibits using private API's, so that alone makes this a bad idea. Given my circumstance, I think they may make an exception, BUT I will likely abandon this course since after taking it I realized that it didn't fix my problem. It does indeed mute the sounds, but as soon as I plug in to my accessory, the system sounds come out at max volume even though the ringer volume is set to 0. This leads me to believe the answer to solving my problem is in the MFI documentation.
Anyhow, here is how to change the ringer using private framework / api (which will get your app rejected without some kind of special permission).
short answer:
[[AVSystemController sharedAVSystemController] setVolumeTo:0 forCategory:@"Ringtone"];
answer without having to directly reference Celestial frameork / AVSystemController.h:
- (void) setSystemVolumeLevelTo:(float)newVolumeLevel
{
Class avSystemControllerClass = NSClassFromString(@"AVSystemController");
id avSystemControllerInstance = [avSystemControllerClass performSelector:@selector(sharedAVSystemController)];
NSString *soundCategory = @"Ringtone";
NSInvocation *volumeInvocation = [NSInvocation invocationWithMethodSignature:
[avSystemControllerClass instanceMethodSignatureForSelector:
@selector(setVolumeTo:forCategory:)]];
[volumeInvocation setTarget:avSystemControllerInstance];
[volumeInvocation setSelector:@selector(setVolumeTo:forCategory:)];
[volumeInvocation setArgument:&newVolumeLevel atIndex:2];
[volumeInvocation setArgument:&soundCategory atIndex:3];
[volumeInvocation invoke];
}
Using MediaPlayer framework, we can set the level of SYSTEM sound
[[MPMusicPlayerController applicationMusicPlayer] setVolume:0];
Best you can do is encourage your users to go into airplane mode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With