我正在编写一个非常简单的应用程序,在按下按钮时播放声音。因为当设备被设置为静音时,这个按钮没有多大意义,所以当设备的音频音量为零时,我想禁用它。(随后,当音量再次增大时,重新启用它。)
我正在寻找一种有效的(和AppStore安全的)方法来检测当前的卷设置,并在卷级别改变时获得通知/回调。我不想改变音量设置。
所有这些都是在使用said按钮的我的ViewController中实现的。我已经用运行iPhone 4.0.1和4.0.2的iOS 4以及运行4.0.1的iPhone 3G进行了测试。使用iOS SDK4.0.2和llvm1.5构建。(使用gcc或llvm并不能改善任何情况。)在构建实现过程中没有任何问题,也没有错误或警告。静态分析仪也很高兴。
以下是我迄今所尝试过的,但都没有成功。
根据苹果的音频服务文档,我应该为kAudioSessionProperty_CurrentHardwareOutputVolume注册一个kAudioSessionProperty_CurrentHardwareOutputVolume,它的工作方式如下:
// Registering for Volume Change notifications
AudioSessionInitialize(NULL, NULL, NULL, NULL);
returnvalue = AudioSessionAddPropertyListener (
kAudioSessionProperty_CurrentHardwareOutputVolume ,
audioVolumeChangeListenerCallback,
self
);returnvalue是0,这意味着注册回调是有效的。
可悲的是,当我按下设备上的音量按钮、耳机的按键或按响器静音开关时,我的函数audioVolumeChangeListenerCallback就永远回不来了。
当使用完全相同的代码来注册kAudioSessionProperty_AudioRouteChange (在WWDC视频、开发人员文档和许多站点上作为类似的示例项目使用)时,我实际上在更改音频路由时得到了回调(通过插入/拔出耳机或对接设备)。
一个名为Doug的用户打开了一个名为iPhone volume changed event for volume already max的线程,在该线程中,他声称他成功地使用了这种方式(除非卷实际上不会改变,因为它已经设置为最大值)。不过,这对我不管用。
我尝试过的另一种方式是像这样在NSNotificationCenter注册。
// sharedAVSystemController
AudioSessionInitialize(NULL, NULL, NULL, NULL);
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil];这应该会将任何volumeChanged更改通知我的方法SystemVolume,但实际上它并没有这样做。
因为共同的信念告诉我,如果一个人太努力地用可可来实现某件事情,那就是做了一些根本错误的事情,我希望在这里错过一些东西。很难相信有什么简单的方法可以达到目前的音量水平,但我还没能通过使用苹果的文档、示例代码、谷歌( Google )、苹果开发者论坛( Apple Developer Forum)或通过观看WWDC 2010视频来找到一个。
发布于 2018-01-19 14:11:02
Swift 4
func startObservingVolumeChanges() {
avAudioSession.addObserver(self, forKeyPath: Observation.VolumeKey, options: [.initial, .new], context: &Observation.Context)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &Observation.Context {
if keyPath == Observation.VolumeKey, let volume = (change?[NSKeyValueChangeKey.newKey] as? NSNumber)?.floatValue {
print("\(logClassName): Volume: \(volume)")
}
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
func stopObservingVolumeChanges() {
avAudioSession.removeObserver(self, forKeyPath: Observation.VolumeKey, context: &Observation.Context)
}然后你打电话
var avAudioSession = AVAudioSession.sharedInstance()
try? avAudioSession.setActive(true)
startObservingVolumeChanges()https://stackoverflow.com/questions/3651252
复制相似问题