Как реализовать затвор громкости для iPhone?
Я хочу реализовать то же поведение с собственной камерой iOS5
:
- нажмите кнопку громкости +, чтобы сделать снимок
Какой идеальный способ архивирования?
Есть ли способ захватить нажатие клавиши уровня громкости?
После поиска в Интернете и поиска в течение нескольких часов я нашел 1 решение: используя NSNotificationCenter
:
...
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil];
...
- (void)volumeChanged:(NSNotification *)notification{
[self takePhoto];
}
Однако у него есть 2 проблемы:
- Полупрозрачное наложение "текущего объема системы" появляется каждый раз при нажатии клавиши громкости, это не то, что я хотел.
- Для встроенной камеры, когда вы нажимаете клавишу регулировки громкости в качестве затвора, системный том не изменится, однако, используя вышеуказанный метод, системный том изменится.
Ответы
Ответ 1
Я нашел другой способ скрыть "наложение системного тома" и "обходить изменение громкости системы при нажатии клавиши громкости".
Плохая часть: это супер UGLY хак.
Однако, хорошая часть: этот уродливый хак использует NO private 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 часов тратят на обнаружение этого супер уродливого метода... shit... 草 尼马 啊!)
Другое дело:
если вы возьмете вышеупомянутый взлом, вам нужно запустить код КАЖДОЕ ВРЕМЯ, когда ваше приложение станет активным.
Таким образом, вам может потребоваться добавить код в делегат приложения.
- (void)applicationDidBecomeActive:(UIApplication *)application
Ответ 2
Основываясь на коде 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];
Ответ 3
...
[[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];
}
Ответ 4
В настоящее время нет официального способа захвата нажатого события громкости. Apple заявила, что кнопка громкости работает с UIImagePickerController
, если вы позволили ей отображать элементы управления камерой.
Другие подходы, такие как прослушивание уведомления, кажутся неподдерживаемыми хаками, которые команда Apple - анекдотически, - иногда закрывая глаза. Чтобы предотвратить появление 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
и его кнопки камеры, если вы хотите быть в рамках правил. Если вы нашли приложение, которое, похоже, работает вне правил, то оно, вероятно, использует методы выше.
Ответ 5
Я вызываю этот метод из 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];