如何实现iPhone的音量快门键?

我想实现与iOS5的本机相同的行为:

  • 按音量+button拍照

什么是归档它的理想方式? 有没有什么方法来捕捉音量按键事件?

谷歌search几个小时后,我发现1解决scheme:使用NSNotificationCenter

 ... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; ... - (void)volumeChanged:(NSNotification *)notification{ [self takePhoto]; } 

但是,它有两个问题:

  • 每次按音量键时都会出现一个“当前系统音量”的半透明叠加,这不是我想要的。
  • 对于本地摄像机,当您按音量键作为快门时,系统音量不会改变,但通过使用上述方法,系统音量将会改变。

build立在huxia的代码上,这个工作在ios5 +上,每次启动时不需要运行代码,只需要运行一次。

 // these 4 lines of code tell the system that "this app needs to play sound/music" AVAudioPlayer* p = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"photoshutter.wav"]] error:NULL]; [p prepareToPlay]; [p stop]; //make MPVolumeView Offscreen CGRect frame = CGRectMake(-1000, -1000, 100, 100); MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:frame]; [volumeView sizeToFit]; [self.view addSubview:volumeView]; 

我发现了另外一种方法来隐藏“系统音量叠加”和“按下音量键时绕过系统音量变化”。

不好的部分:这是一个超级UGLY黑客。

但是,最好的部分是:这个丑陋的黑客使用没有私人API。

另外值得注意的是:它只适用于ios5 +(无论如何,对于我的问题,因为AVSystemController_SystemVolumeDidChangeNotification只适用于ios5,所以这个UGLY黑客只适合我的问题。)

它的工作方式:“充当音乐/电影播放器​​应用程序,让音量键调整应用程序音量”。

码:

 // these 4 lines of code tell the system that "this app needs to play sound/music" AVAudioPlayer* p = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"photo-shutter.wav"]] error:NULL]; [p prepareToPlay]; [p stop]; [p release]; // these 5 lines of code tell the system that "this window has an volume view inside it, so there is no need to show a system overlay" [[self.view viewWithTag:54870149] removeFromSuperview]; MPVolumeView* vv = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, -100, 100, 100)]; [self.view addSubview:vv]; vv.tag = 54870149; [vv release]; 

(花5个小时去发现这个超级丑陋的方法……草尼马啊!)

另一件事:如果你采取了上面的黑客攻击,你需要运行代码每当你的应用程序变得活跃。 所以,您可能需要将一些代码放入您的应用程序委托中。

 - (void)applicationDidBecomeActive:(UIApplication *)application 

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; 

 - (void)volumeChanged:(NSNotification *)notification{ CGRect frame = CGRectMake(-1000, -1000, 100, 100); MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:frame]; [volumeView sizeToFit]; [self.view addSubview:volumeView]; [volumeView release]; [self takePhoto]; } 

目前没有官方的方法来捕捉音量按键事件。 苹果公司指出的是,如果你允许它显示相机控制,音量button与UIImagePickerController一起工作。

其他方法,比如倾听通知,似乎是苹果团队没有支持的诡计 – 有趣的是 – 有时视而不见。 为了防止出现卷HUD,可以使用无证UIApplication方法:

 - (void)setSystemVolumeHUDEnabled:(BOOL)enabled; - (void)setSystemVolumeHUDEnabled:(BOOL)enabled forAudioCategory:(NSString *)category; 

他们使用我唯一看到的声明是:

 UIApplication *app = [UIApplication sharedApplication]; [app setSystemVolumeHUDEnabled:NO forAudioCategory:@"Ringtone"]; [app setSystemVolumeHUDEnabled:NO]; 

我不确定是否或为什么你似乎需要停用某个特定类别的HUD,然后一般情况下,但没有适当的文档,很难弄清楚。

所以:如果你想在规则中使用UIImagePickerController和它的相机button。 如果你发现一个似乎在规则之外工作的应用程序,那么它可能使用上面的方法。

我从viewDidAppear调用这个方法

 -(void) startTrackingVolume { [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil]; if (!self.volumeView) { // put it somewhere outside the bounds of parent view self.volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, -100, 10, 0)]; [self.volumeView sizeToFit]; } if (!self.volumeView.superview) { [self.view addSubview:self.volumeView]; } } 

viewWillDisappear中将显示在调用中

 [[AVAudioSession sharedInstance] setActive:NO error:nil];