我正在编写一个非常简单的应用程序,在按下按钮时播放声音。因为当设备被设置为静音时,这个按钮没有多大意义,所以当设备的音频音量为零时,我想禁用它。(随后,当音量再次增大时,重新启用它。)
我正在寻找一种有效的(和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视频来找到一个。
发布于 2011-06-24 18:25:05
您是否有可能对volumeChanged:方法做了错误的签名?这对我起了作用,把它扔到了我的应用程序中:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil];
}
- (void)volumeChanged:(NSNotification *)notification
{
float volume =
[[[notification userInfo]
objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"]
floatValue];
// Do stuff with volume
}我的volumeChanged:方法每次按下按钮时都会被点击,即使音量没有因此而改变(因为它已经达到最大值/分钟)。
发布于 2015-03-20 16:03:08
这里一些答案所使用的AudioSession API在iOS 7中已被废弃,取而代之的是AVAudioSession,它为系统范围的输出卷公开了一个outputVolume属性。在卷发生变化时,可以使用KVO接收通知,如文档中所指出的:
A值在0.0到1.0之间,0.0表示最小卷,1.0表示最大卷。
系统宽的输出卷只能由用户直接设置;要在应用程序中提供卷控制,请使用MPVolumeView类。
您可以通过使用键值观察来观察此属性值的更改。
您需要确保应用程序的音频会话是活动的,这样才能工作:
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setActive(true)
startObservingVolumeChanges()
} catch {
print(“Failed to activate audio session")
}因此,如果您只需要查询当前的系统卷:
let volume = audioSession.outputVolume或者,我们可以收到这样的变更通知:
private struct Observation {
static let VolumeKey = "outputVolume"
static var Context = 0
}
func startObservingVolumeChanges() {
audioSession.addObserver(self, forKeyPath: Observation.VolumeKey, options: [.Initial, .New], context: &Observation.Context)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if context == &Observation.Context {
if keyPath == Observation.VolumeKey, let volume = (change?[NSKeyValueChangeNewKey] as? NSNumber)?.floatValue {
// `volume` contains the new system output volume...
print("Volume: \(volume)")
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}不要忘记在被释放之前停止观察:
func stopObservingVolumeChanges() {
audioSession.removeObserver(self, forKeyPath: Observation.VolumeKey, context: &Observation.Context)
}发布于 2012-02-04 03:41:01
-(float) getVolumeLevel
{
MPVolumeView *slide = [MPVolumeView new];
UISlider *volumeViewSlider;
for (UIView *view in [slide subviews]){
if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) {
volumeViewSlider = (UISlider *) view;
}
}
float val = [volumeViewSlider value];
[slide release];
return val;
}这应该能让你达到当前的音量水平。1是最大音量,0是无音量。注意:不需要显示UI元素就可以工作。还请注意,当前的音量级别相对于耳机或扬声器(这意味着,这两个音量级别是不同的,这将使您无论该设备目前使用的是什么。这并不能回答您关于接收卷更改通知的问题。
https://stackoverflow.com/questions/3651252
复制相似问题