程序访问iPhone音量button
有什么办法可以订阅音量button新闻事件?
在苹果最近被拒绝之后
不要使用这个。 苹果现在使用一些补丁程序,如果它使用任何私有API,就会直接拒绝你的应用程序 – 虽然在这里应该注意到,App Store上的一些应用程序已经使用了这个补丁程序,并且仍然存在!
现在唯一的方法就是让AVAudioPlayer准备播放但不播放([player prepareToPlay])。 这似乎照顾到根据摇杆button调整应用程序的音量。
目前没有其他公布的方式来处理这个问题。
请阅读上述说明
是的,使用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这是一个解决现在修复的错误。
但我敢肯定,如果你想要做的只是获取通知,而不是设置系统音量,那么你可以像任何其他事件一样使用通知中心!
build议:由于苹果在相机中增加了音量提升操作,当UIImagePickerController
可见时, 不会发送此通知。
如果你愿意进入私人API,我有一个补丁Wolf3d ,增加了你正在寻找的function。 它使用私有AVSystemController
类和UIApplication
上的一些隐藏方法
好的,
所以我看到了你的解决scheme,并不知道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. }
让我知道这是否有助于任何人。
我在研究上面提到的所有源代码和其他线程中发现的最简单,最function完整的方法是: JPSVolumeButtonHandler (除了作为用户,我不参与其中)但非常感谢责任人!
编辑:版本1.0.2来了一些重大的变化/增强。 我将把我以前的答案放在低于1.0.1的位置。
我把一个示例包装类,您可以按原样部署,或者用来学习JPSVolumeButtonHandler希望在这里真正快速地在一个单独的Github存储库中正确使用。
以下是包装的使用方法(我将尽快将其添加到存储库中):
-
单例类有两个标志:
isInUse
和isOn
。isInUse
是为了在某种常规的应用程序设置中设置的,并且一般地打开和closuresbutton支持。 所以,无论课堂上有没有其他的值,如果这是false
的,用户按下音量button时就不会有任何事情发生,并且实现尽可能地保持干净,不会不必要地影响系统音量。 (请阅读自述文件中提到的问题,以了解第一次启用button支持时可能发生的情况。)isOn
的意思是在需要button的持续时间内准确无误。 您可以打开和closures,而不考虑isInUse
的当前值。 -
在任何一个视图中,当按下音量button时,初始化应该发生的动作,设置如下的动作:
PhysicalButton.shared.action = {/ *做某事* /}
该操作具有type () -> Void
。 在你初始化动作之前,什么都不会中断。 什么都不会发生。 这个防御function对我来说很重要,因为只有在设置button支持后才能创build使用音量button支持的视图。
为了看到行动中的事情,你可以免费下载我正在使用的应用程序 。 一般来说,这些设置操作“物理button支持”。 主秒表视图是在进入视图时实际切换button处理的视图,在离开视图时closures。 如果您find时间,您还可以在“设置”>“用户指南”>“选项:物理button支持”中find重要说明:
在特殊情况下,应用程序可能没有机会正确切换“秒表”视图外的音量button处理。
我将把完整的注释添加到Github的README.md中。 随意调整和重用它,如果它在你的情况是相关的。
事实并非如此,我还没有完全弄清楚什么是错的。 当音量button打开时,用户杀死应用程序(或者只是在Xcode中停止您的应用程序),物理button支持可能无法正确从操作系统中删除。 因此,最终可能会有两个内部处理程序实例,只有其中一个可以控制。 那么,每个button点击都会导致两个甚至更多的调用操作例程。 我的包装有一些监护人的代码,以防止button的调用太快。 但这只是一个部分的解决scheme。 修复需要进入底层的处理程序,我很遗憾自己试图解决这些问题的时候,仍然有太多的理解。
OLD,FOR 1.0.1:
我特别感兴趣的是Swift解决scheme。 代码在Objective-C中。 为了节省一些人的研究,这是我所做的所有使用Cocoapods(像我这样的傻瓜):
- 将
pod 'JPSVolumeButtonHandler'
添加到pod 'JPSVolumeButtonHandler'
文件中 - 在命令行上运行
pod install
- 将
#import <JPSVolumeButtonHandler.h>
添加到桥接头文件中 -
设置音量上下button的callback,如下所示:
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... })
而已。 剩下的是可选的。
在我的情况下,我想用虚拟屏幕上的button为select的视图启用叠加物理buttonbutton,同时确保尽可能地阻挡正常的buttonfunction(以便用户可以在后台运行音乐并调整其在应用程序的其余部分的体积就好了)。 我结束了大部分单身课程,如下所示:
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 } }
这里只有一个常用的上下音量button的操作。 initSharedInstance()
是必须的,因为我的操作包含了一个UI元素(视图)的引用,它只会在应用程序启动后的某个依赖于用户的位置设置。
一次性设置如下:
OptionalButtonHandler.initSharedInstance({ // ...some UI action })
有select地启用/禁用就像这样:
OptionalButtonHandler.sharedInstance!.enabled = true // (false)
(请注意,我的代码逻辑确保在initSharedInstance()
之前永远不会访问initSharedInstance()
。)
我在(required!)testing设备上运行Xcode 7.3和iOS 9.3.2。
期待学习苹果如何感觉超载他们珍贵的音量button。 至less我的应用程序确保微创,button使用真的很有意义。 这不是一个相机的应用程序,但可比的应用程序已经使用物理音量button(甚至不太好)。