Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

ios - How to implement a volume key shutter for iPhone?

I want to implement the same behavior with the native camera of iOS5:

  • press the volume + button to take a photo

What's the ideal way to archive it? Are there any ways to capture the volume key pressed event?

After googling & searching around for hours, I found 1 solution: using NSNotificationCenter:

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

However, it has 2 issues:

  • There is an semi-transparent overlay of "current system volume" show up every time when pressing the volume key, this is not what I wanted.
  • For the native camera, when you press the volume key as shutter, the system volume won't change, however, by using the above method, the system volume will change.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've found another way to hide the "system volume overlay" and "bypass the system volume change when the volume key pressed" by myself.

The bad part: this is an super UGLY hack.

However, the good part is: this ugly hack uses NO private APIs.

Another note is: it only works for ios5+ (anyway, for my issue, since the AVSystemController_SystemVolumeDidChangeNotification only works for ios5, so this UGLY hack just fits my issue.)

The way it work: "act as a music/movie player app and let the volume key to adjust the application-volume".

Code:

// 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 hours spending on discovering this super ugly method... shit... 草尼马啊!)

Another thing: if you take the above hack, you need to run the code EVERY-TIME when your app become active. So, you might need to put some code into your app delegate.

- (void)applicationDidBecomeActive:(UIApplication *)application 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...