Подтвердить что ты не робот

Как реализовать затвор громкости для iPhone?

Я хочу реализовать то же поведение с собственной камерой iOS5:

  • нажмите кнопку громкости +, чтобы сделать снимок

Какой идеальный способ архивирования? Есть ли способ захватить нажатие клавиши уровня громкости?

После поиска в Интернете и поиска в течение нескольких часов я нашел 1 решение: используя NSNotificationCenter:

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

Однако у него есть 2 проблемы:

  • Полупрозрачное наложение "текущего объема системы" появляется каждый раз при нажатии клавиши громкости, это не то, что я хотел.
  • Для встроенной камеры, когда вы нажимаете клавишу регулировки громкости в качестве затвора, системный том не изменится, однако, используя вышеуказанный метод, системный том изменится.
4b9b3361

Ответ 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];