iOS 监听声音按键
有时在项目中需要监听用户是否按下了物理声音键,然后来做某些操作,如:你自定义了一个照相功能,希望用户按下声音按键时也能进行拍照,苹果自带的照相机就有这种功能.
监听物理声音键是否按下的方法有很多中,我在这里只讲两种,也是我比较熟悉的
一、通过 NSNotificationCenter 观察一个叫做 @“AVSystemController_SystemVolumeDidChangeNotification” 的通知,
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil]; - (void)volumeChanged:(NSNotification *)notification
{ float volume =
[[[notification userInfo]
objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"]
floatValue]; NSLog(@"current volume = %f", volume); }
二、通过为AudioSession添加一个监听者来实现,
-(BOOL)addHardKeyListener{
OSStatus s = AudioSessionAddPropertyListener(kAudioSessionProperty_CurrentHardwareOutputVolume, hardKeyListener, "kAudioSessionProperty_CurrentHardwareOutputVolume");
return s==kAudioSessionNoError;
}
void hardKeyListener(
void *inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void *inData
){
if (inID != kAudioSessionProperty_CurrentHardwareOutputVolume) {
return;
}
NSLog(@"%s",inClientData);
}
对于上面这种方式,如果你直接这样,那当你按下物理音量键时不会有任何的反应,你必须在调用它之前,手动初始化audioSession
你可以
AudioSessionInitialize(NULL, kCFRunLoopDefaultMode, interruptionListenerCallback, "AudioSessionInitialize");
或者直接
AudioSessionInitialize(NULL, NULL, NULL, NULL);
当你完成了上面的任何一种方式后,你就可以很好的捕捉到音量键是否按下了,但此时你会发现,当你按下音量键时,系统自带的,反映音量设置的view会
出现,试想下,当你的用户通过物理音量键操作你的程序,比如拍照,你还给人家显示个系统的音量设置键,那用户体验可想而知了,
那怎么解决呢?
那个系统自带的音量设置view 其实就是个苹果自定义的MPVolumeView,没当音量键按下时,它都会出现,但如果当前显示的正好有一个这样的东西,那这个系统的音量设置view 就不会反客为主,自己显示出来了,而是显示你自己定义的
呵呵,我就是不需要这个,那好办,自定义一个,然后加到看不到的地方不就得了,
如下:
MPVolumeView *volumeView = [[MPVolumeView alloc]initWithFrame:CGRectMake(-, -, , )];
[self.view addSubview:volumeView];
但此时,你必须激活audioSession,不然得话它还是会自己显示得
加上代码:
AudioSessionSetActive(true);
三、完成上面得东西后,你基本上可以正常捕捉到音量键得按下,但有一点要注意:audioSession在你得程序进入后台后会变为不激活状态,当你再次回到前台后,你得程序得audioSession其实是没有激活得,此时,你按下音量键,那系统得那个音量设置view 就又出来了,所以你应该添加两个系统通知,当程序进入后台时
AudioSessionSetActive(false); 当程序进入前台时 AudioSessionSetActive(true);
而且,如果捕捉音量键得按下只在某个画面有效,那当该画面不再示但前显示得画面示应该移除捕捉动作
下面是一些测试用得代码,没有什么逻辑关联性
//
// ViewController.m
// AudioSessionDemo
//
// Created by PSH_Chen_Tao on 7/18/13.
// Copyright (c) 2013 wolfman. All rights reserved.
// #import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h> @interface ViewController () @end @implementation ViewController @synthesize imagePickerController; - (void)viewDidLoad
{
[super viewDidLoad];
// 获得当前的音量,因为按物理音量键,声音会发生改变,我们可以在他每次按下音量键时都通过下面的初始音量值来还原它.
float initVolume = [MPMusicPlayerController applicationMusicPlayer].volume;
NSLog(@"%f ",initVolume);
// Do any additional setup after loading the view, typically from a nib. AudioSessionInitialize(NULL, kCFRunLoopDefaultMode, interruptionListenerCallback, "AudioSessionInitialize"); //通过捕捉物理音量键按下时产生的通知来对其进行监听
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(enterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(enterForground:) name:UIApplicationDidBecomeActiveNotification object:nil]; //避免按下音量键时,其系统自带的音量设置画面会出现
MPVolumeView *volumeView = [[MPVolumeView alloc]initWithFrame:CGRectMake(-, -, , )];
[self.view addSubview:volumeView]; } //进入后台,释放AudioSession
-(void)enterBackground:(NSNotification *)n{
AudioSessionSetActive(false);
}
//进入前台,激活AudioSession
-(void)enterForground:(NSNotification *)n{
AudioSessionSetActive(true);
} - (void)volumeChanged:(NSNotification *)notification
{ float volume =
[[[notification userInfo]
objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"]
floatValue]; NSLog(@"current volume = %f", volume); } - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} void interruptionListenerCallback(
void *inClientData,
UInt32 inInterruptionState
){ if (inInterruptionState == kAudioSessionBeginInterruption) {
NSLog(@"begin interruption"); } if (inInterruptionState == kAudioSessionEndInterruption) {
NSLog(@"end interruption");
} NSLog(@"%s",inClientData); } -(BOOL)isMuted{
CFStringRef route;
UInt32 routeSize = sizeof(route);
OSStatus s = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &routeSize, &route);
if (s==kAudioSessionNoError) {
if (route==NULL || CFStringGetLength(route)==) {
return YES;
}
} return NO;
} -(BOOL)addMutedListener{
OSStatus s = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, mutedListener, "kAudioSessionProperty_AudioRouteChange"); return s==kAudioSessionNoError;
} void mutedListener(
void *inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void *inData
){ if (inID != kAudioSessionProperty_AudioRouteChange) {
NSLog(@"inID != kAudioSessionProperty_AudioRouteChange %s",inClientData);
return;
} NSLog(@"%s",inClientData);
} -(BOOL)addHardKeyListener{
OSStatus s = AudioSessionAddPropertyListener(kAudioSessionProperty_CurrentHardwareOutputVolume, hardKeyListener, "kAudioSessionProperty_CurrentHardwareOutputVolume");
return s==kAudioSessionNoError;
} void hardKeyListener(
void *inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void *inData
){ if (inID != kAudioSessionProperty_CurrentHardwareOutputVolume) {
return;
}
NSLog(@"%s",inClientData);
} - (IBAction)addListener:(id)sender { [self addMutedListener];
[self addHardKeyListener];
} - (IBAction)removeListener:(id)sender { AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume, hardKeyListener, "kAudioSessionProperty_CurrentHardwareOutputVolume");
} -(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
} -(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
AudioSessionSetActive(false);
}
@end
iOS 监听声音按键的更多相关文章
- JS监听组合按键
有些时候,我们需要在网页上,增加一些快捷按键,方便用户使用一些常用的操作,比如:保存,撤销,复制.粘贴等等. 下面简单梳理一下思路: 我们所熟悉的按键有这么集中类型: 单独的按键操作,如:delete ...
- Dom监听组合按键
JS监听组合按键 有些时候,我们需要在网页上,增加一些快捷按键,方便用户使用一些常用的操作,比如:保存,撤销,复制.粘贴等等. 下面简单梳理一下思路: 我们所熟悉的按键有这么集中类型: 单独的按键 ...
- 【转】keyCode对照表及JS监听组合按键
原文: http://blog.csdn.net/qq_21386275/article/details/67640576 有一些需求,html 页面上的input 框只允许输入数字, 只允许输入小 ...
- 92. extjs specialkey监听回车按键
转自:http://blog.sina.com.cn/s/blog_647a022e0101401n.html 1 监听表单字段事件: Ext使得对用户某个动作的监听特别简单,诸如单击某个元素或者按下 ...
- android监听虚拟按键的显示与隐藏【转】
本文转载自:http://blog.csdn.net/u014583590/article/details/55263141 虚拟按键在华为手机中大量存在,而虚拟按键的存在无疑增加了屏幕适配的难度,往 ...
- Android通过Intent.ACTION_CLOSE_SYSTEM_DIALOGS监听Home按键消息
Android对屏幕下方经常使用的四个按键消息处理是不一致的: 1.搜索按键的消息在onKeyDown或者onKeyUp中接收: 2.菜单按键的消息在onCreateOptionsMenu.onKey ...
- android 监听声音变化
新的项目需要监听android声音的变化,再做出对应的操作,从网上找了个demo验证.记录于此. 参考链接 https://my.oschina.net/yuanxulong/blog/372268 ...
- iOS监听模式系列之通知中心
补充--通知中心 对于很多初学者往往会把iOS中的本地通知.推送通知和iOS通知中心的概念弄混.其实二者之间并没有任何关系,事实上它们都不属于一个框架,前者属于UIKit框架,后者属于Foundati ...
- iOS监听模式系列之键值编码KVC、键值监听KVO的简单介绍和应用
键值编码KVC 我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的 ...
随机推荐
- SOA一些资料
SOA相关资料整理分享 2015-03-26 16:16 by 蘑菇先生, 693 阅读, 9 评论, 收藏, 编辑 昨@幸福框架同学问能否推荐SOA一些资料.想想之前看过不少资料文档,就整理分享下. ...
- JS读写Cookie(设置、读取、删除)
JS读写Cookie(设置.读取.删除) Cookie是客户端存放数据的一种方式,可用来做状态保持. 1.设置Cookie: a.无过期时间:(若不设置过期时间,默认为会话级Cookie,浏览器关闭就 ...
- Ionic项目中使用极光推送-android
对于Ionic项目中使用消息推送服务,Ionic官方提供了ngCordova项目,这个里面的提供了用angularjs封装好的消息推送服务(官方文档),使用的是GitHub上的 PushPlugin ...
- 通过扩展改善ASP.NET MVC的验证机制[使用篇]
原文:通过扩展改善ASP.NET MVC的验证机制[使用篇] ASP.NET MVC提供一种基于元数据的验证方式是我们可以将相应的验证特性应用到作为Model实体的类型或者属性/字段上,但是这依然具有 ...
- 转载JQuery绑定鼠标粘贴事件工具类
// 粘贴事件监控 $.fn.pasteEvents = function( delay ) { if (delay == undefined) delay = 10; return $(this). ...
- 模板专业化和模板偏特样片(template specialization and partial template specialization)
测试环境: win7 64 g++ 4.8.1 /*************************************************************************** ...
- SQL点滴19—T-SQL中的透视和逆透视
原文:SQL点滴19-T-SQL中的透视和逆透视 透视 今天抽一点时间来看看透视和逆透视语句,简单的说就是行列转换.假设一个销售表中存放着产品号,产品折扣,产品价格三个列,每一种产品号可能有多种折扣, ...
- POJ 1655 Balancing Act 焦点树
标题效果:鉴于一棵树.除去一个点之后,这棵树将成为一些中国联通的块.之后该点通过寻求取消最低形成块的最大数目. 思维:树DP思维.通过为每个子树尺寸的根节点深搜索确定.之后该节点然后除去,,还有剩下的 ...
- poj3744高速功率矩阵+可能性DP
Scout YYF I Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4410 Accepted: 1151 Descr ...
- cocos2d的-X- luaproject的LUA脚本加密
2014/1/26 更新 近期又发现了一个非常easy的方法,事实上coco2dx已经给我们提供设置loader的方法. 注意:有个局限性,在非android平台下调用pEngine->exec ...