программный доступ к кнопкам громкости iPhone

Есть ли способ подписаться на кнопки громкости нажимайте события?

После недавних отказов от Apple

Не используйте это. Apple теперь использует какой-то патч, который сразу отверг бы ваше приложение, если он использует какой-либо из частных API-интерфейсов – хотя следует отметить, что некоторые приложения в App Store уже используют это и все еще там!

Единственный способ сделать это сейчас – заставить AVAudioPlayer подготовиться к игре, но не играть ([player prepareToPlay]). Это, похоже, позаботится об изменении объема приложения в соответствии с кнопками рокера.

В настоящее время нет другого опубликованного способа справиться с этим.

ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ ВЫШЕУПРАВЛЕНИЕ

Да, используйте MPVolumeView

MPVolumeView *volume = [[[MPVolumeView alloc] initWithFrame:CGRectMake(18.0, 340.0, 284.0, 23.0)] autorelease]; [[self view] addSubview:volume]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; for (UIView *view in [volume subviews]){ if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) { volumeViewSlider = view; //volumeViewSlider is a UIView * object } } [volumeViewSlider _updateVolumeFromAVSystemController]; -(IBAction)volumeChanged:(id)sender{ [volumeViewSlider _updateVolumeFromAVSystemController]; } 

Это даст вам слайдер (тот же, что используется в ipod), значение которого изменится в соответствии с объемом телефона

Вы получите предупреждение о компиляции, которое может не соответствовать запросу _updateVolumeFromAVSystemControl, но просто игнорируйте его.

Если вы просто хотите получать уведомления, я думаю, что это так:

Пожалуйста, поправьте меня, если я ошибаюсь, но я не считаю, что это использует какой-либо внутренний API.

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

Подробная информация об этом событии находится здесь: http://www.cocoadev.com/index.pl?AVSystemController

Другие ответы здесь, похоже, основаны на этом взломе: http://blog.stormyprods.com/2008/09/proper-usage-of-mpvolumeview-class.html, который был обходным решением для исправленной ошибки.

Но я уверен, что все, что вы хотите сделать, это ПОЛУЧИТЬ уведомление, а не установить системный том, вы можете просто использовать центр уведомлений, как с любым другим событием!

Обратите внимание: поскольку Apple добавила в камеру действие увеличения громкости, это уведомление не отправляется, пока UIImagePickerController .

Если вы готовы погрузиться в частный API, у меня есть патч для Wolf3d, который добавляет именно ту функциональность, которую вы ищете. Он использует частный class AVSystemController и некоторые скрытые методы в UIApplication

Хорошо,

Поэтому я увидел ваши решения и не знаю, собирается ли Apple отклонить или принять использование AVSystemController_SystemVolumeDidChangeNotification . Но у меня есть работа.

Используйте UISlider из MPVolumeView для регистрации для любых изменений громкости на оборудовании iPhone, как это

 MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectZero]; for (UIView *view in [volumeView subviews]) { if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ self.volume_slider = (UISlider*)view; break; } } [volumeView sizeToFit]; #THIS IS THE MAIN LINE. ADD YOUR CALLBACK TARGET HERE [self.volume_slider addTarget:self action:@selector(volumeListener:) forControlEvents:UIControlEventValueChanged]; [self addSubview:volumeView]; [volumeView setAlpha:0.0f]; -(void)volumeListener:(NSNotification*)notification { #UPDATE YOUR UI ACCORDING OR DO WHATEVER YOU WANNA DO. #YOU CAN ALSO GET THE SOUND STEP VALUE HERE FROM NOTIFICATION. } 

Дайте мне знать, если это поможет кому угодно.

Самый простой и наиболее функциональный способ сделать это, который я нашел при изучении всех источников, упомянутых выше и в других streamах, – это: JPSVolumeButtonHandler (я не участвую, кроме пользователя, но очень благодарен ответственным людям!)

EDIT: версия 1.0.2 появилась с некоторыми существенными изменениями / улучшениями. Я оставлю свой предыдущий ответ за 1.0.1 ниже фола.

Я помещаю class обертки образца, который можно либо развернуть как есть, либо использовать для надежного использования JPSVolumeButtonHandler в отдельном репозитории Github .

Вот как предполагается использовать оболочку (я добавлю это в repository, как только я получу):

  1. Класс singleton имеет два флага: isInUse и isOn . isInUse предназначен для установки в каких-то общих настройках приложения и в любой момент, когда кнопка включения кнопок включена и выключается. Таким образом, независимо от каких-либо других значений в classе, если это false ничего не произойдет, когда пользователь нажимает кнопку громкости, и реализация гарантирует как можно больше, чтобы вещи были чистыми и не влияли на уровень громкости системы без необходимости. (Прочитайте вопрос, упомянутый в README, для того, что может произойти, когда поддержка кнопок включена в первый раз.) isOn должно быть true точно в течение всего времени, которое требуется кнопке. Вы можете включать и выключать его независимо от текущего значения isInUse .

  2. В любом представлении вы инициализируете действие, которое должно произойти при нажатии кнопки тома, установите действие следующим образом:

    PhysicalButton.shared.action = {/ * сделать что-то * /}

Действие имеет тип () -> Void . Пока вы не инициализируете действие, ничего не сломается. Просто ничего не произойдет. Эта защитная функциональность была важна для меня, поскольку представление, использующее поддержку кнопки тома, будет создано только после того, как будет установлена ​​поддержка кнопки.

Для просмотра вещей в действии вы можете загрузить приложение, которое я использую это в реальном времени бесплатно. Установки управляют «поддержкой физических кнопок» в целом. Основной вид Секундомера – это тот, который фактически переключает управление кнопками при входе в представление и выключает его. Если вы найдете время, вы также найдете важную заметку в разделе «Настройки»> «Руководство пользователя»> «Опция: поддержка физической кнопки»:

В исключительных обстоятельствах приложение не может получить возможность правильно переключить кнопку регулировки громкости вне представления «Секундомер» …

Я добавлю полную заметку в Github README.md. Не стесняйтесь адаптировать и повторно использовать его, если это имеет значение в вашем случае.

Обстоятельства на самом деле не являются исключительными, и я не совсем понял, что случилось. Когда пользователь убивает приложение (или вы просто останавливаете приложение из Xcode), когда кнопки регулировки громкости включены, физическая поддержка кнопок может быть неправильно удалена из ОС. Таким образом, вы можете получить два внутренних экземпляра обработчика, только один из которых вы контролируете. Таким образом, каждый нажатие кнопки приводит к двум или даже более вызовам программы действий. Моя обложка имеет некоторый код опекуна, чтобы предотвратить слишком быстрое обращение к кнопке. Но это лишь частичное решение. Фиксировать нужно, чтобы войти в базовый обработчик, который, к сожалению, я все еще слишком мало понимаю, чтобы попытаться исправить ситуацию сам.


OLD, FOR 1.0.1:

В частности, мой интерес был в решении Swift. Код находится в Objective-C. Чтобы спасти кого-то от некоторых исследований, это все, что я использовал с помощью Cocoapods (для таких манекенов, как я):

  1. Добавить pod 'JPSVolumeButtonHandler' в podfile
  2. Выполнить pod install в командной строке
  3. Добавьте #import в заголовочный файл моста
  4. Настройте обратные вызовы для кнопок увеличения и уменьшения громкости:

     let volumeButtonHandler = JPSVolumeButtonHandler( upBlock: { log.debug("Volume up button pressed...") // Do something when the volume up button is pressed... }, downBlock: { log.debug("Volume down button pressed...") // Do something else for volume down... }) 

Вот и все. Остальное необязательно.


В моем случае я хотел включить наложение физических нажатий кнопок с виртуальными экранными кнопками только для избранных представлений, при этом, чтобы как можно меньше блокировать обычные функции кнопок (чтобы пользователь мог запускать музыку в фоновом режиме и настраивать его объем в остальной части приложения просто прекрасен). В итоге я получил class Singleton:

 class OptionalButtonHandler { static var sharedInstance: OptionalButtonHandler? private var volumeButtonHandler: JPSVolumeButtonHandler? = nil private let action: () -> () var enabled: Bool { set { if !enabled && newValue { // Switching from disabled to enabled... assert(volumeButtonHandler == nil, "No leftover volume button handlers") volumeButtonHandler = JPSVolumeButtonHandler(upBlock: { log.debug("Volume up button pressed...") self.action() }, downBlock: { log.debug("Volume down button pressed...") self.action() }) } else if enabled && !newValue { log.debug("Disabling physical button...") // The other way around: Switching from enabled to disabled... volumeButtonHandler = nil } } get { return (volumeButtonHandler != nil) } } /// For one-time initialization of this otherwise singleton class. static func initSharedInstance(action: () -> ()) { sharedInstance = OptionalButtonHandler(action: action) } private init(action: () -> ()) { self.action = action } } 

Существует только одно общее действие для кнопок увеличения и уменьшения громкости. initSharedInstance() был необходим, потому что мое действие включало ссылки на элемент пользовательского интерфейса (представление), который был бы настроен только в некоторой зависящей от пользователя точке после запуска приложения.

Одноразовая настройка:

 OptionalButtonHandler.initSharedInstance({ // ...some UI action }) 

Включить / отключить выборочно просто так:

 OptionalButtonHandler.sharedInstance!.enabled = true // (false) 

(Обратите внимание, что моя логика кода гарантирует, что .enabled никогда не initSharedInstance() до initSharedInstance() .)

Я запускаю Xcode 7.3 и iOS 9.3.2 на тестовом устройстве (обязательно!).

С нетерпением ждем, как Apple почувствует перегрузку своих драгоценных кнопок. По крайней мере, мое приложение обязательно будет минимально инвазивным, и использование кнопки действительно имеет смысл. Это не приложение для камеры, но в сопоставимых приложениях ранее использовались кнопки физического уровня (менее хорошо).

  • Нарисуйте часть круга
  • Могу ли я отключить прокрутку звука UIPickerView?
  • Одновременные распознаватели жестов в Iphone SDK
  • Получить процентное использование процессора
  • drawRect не вызывается в моем подclassе UIImageView
  • UITableView, прокрутите вниз до перезагрузки?
  • QLPreviewController удаляет или добавляет UIBarButtonItems
  • UISlider вместе с ProgressView
  • запись NSDictionary для plist в моем приложении
  • Как работает новый механизм автоматического подсчета ссылок?
  • Сколько стоит разработка приложения для iPhone?
  • Давайте будем гением компьютера.