如题

线控主要就是指的用ios耳机的  中间那个键来自定义一些程序自己的事件(比如玩吃鸡的时候,作为开枪扳机)

而想要控制耳机的音量加减的事件,

有一种方法,就是监听 系统音量的变化,根据音量变化来触发不同的行为。但是这种有局限性,比如音量最大后你再按音量加,音量就不会变了。

推荐一篇博客

链接是 https://www.jianshu.com/p/950fec0cdb21

为防止作者删掉博客,内容一并显示如下:

关于监控苹果耳机,目的上主要分为监控耳机插入,拔出,和耳机线控,因为最近做了关于苹果耳机线控方面的需求,所以想针对苹果耳机线控在这唠嗑一下。

 

苹果耳机3个按键(音量加,音量减,中间功能键)的经典设计已经延续了十几年,功能上我们谈到的耳机线控是监听耳机中间功能键的动作,作出功能上的响应。

如何支持耳机线控

1.引入AVFoundation框架

具体引入方式不截图,不细说了,只有引入了AVFoundation框架,耳机线控才能生效。

2.允许传递远程控制事件

允许传递远程控制事件

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

结束传递远程控制事件

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];

因为在允许接受远程控制事件时,UI控件必须为第一响应者,所以需要在beginReceivingRemoteControlEvents方法后面增加一个becomeFirstResponder方法。
记得补上

-(BOOL)canBecomeFirstResponder{
return YES;
}

3.启用远程事件接收

启动远程事件接受的应用才能支持耳机线控,当然也可以监控其他外部控件的响应,比如自拍杆拍照之类的。
启用远程事件接收的核心就是UIResponder类中的- (void)remoteControlReceivedWithEvent:(UIEvent *)event方法。

//received remote event
-(void)remoteControlReceivedWithEvent:(UIEvent *)event{
NSLog(@"event tyipe:::%ld subtype:::%ld",(long)event.type,(long)event.subtype);
//type==2 subtype==单击暂停键:103,双击暂停键104
if (event.type == UIEventTypeRemoteControl) {
switch (event.subtype) { case UIEventSubtypeRemoteControlPlay:{
NSLog(@"play---------");
}break;
case UIEventSubtypeRemoteControlPause:{
NSLog(@"Pause---------");
}break;
case UIEventSubtypeRemoteControlStop:{
NSLog(@"Stop---------");
}break;
case UIEventSubtypeRemoteControlTogglePlayPause:{
//单击暂停键:103
NSLog(@"单击暂停键:103");
}break;
case UIEventSubtypeRemoteControlNextTrack:{
//双击暂停键:104
NSLog(@"双击暂停键:104");
}break;
case UIEventSubtypeRemoteControlPreviousTrack:{
NSLog(@"三击暂停键:105");
}break;
case UIEventSubtypeRemoteControlBeginSeekingForward:{
NSLog(@"单击,再按下不放:108");
}break;
case UIEventSubtypeRemoteControlEndSeekingForward:{
NSLog(@"单击,再按下不放,松开时:109");
}break;
default:
break;
}
}
}

为了保证应用一定能够接受到远程控制请求,包括耳机线控,beginReceivingRemoteControlEvents方法和remoteControlReceivedWithEvent方法建议写在应用的启动的入口,AppDelegate或者RootViewController中。

写到这里,理论上我们就可以疯狂的点击耳机功能键,监控耳机响应各种华丽的操作了,但在一顿猛烈的点击之后,日志板上一片风平浪静,我的预想并没有达到。。。

实现耳机线控的三个前提

整理一下思绪,实现耳机线控的按键的监控是有以下三个前提

1.启用远程事件接收(使用[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];方法)。
2.对于UI控件同样要求必须是第一响应者(对于视图控制器UIViewController或者应用程序UIApplication对象监听无此要求)。
3.应用程序必须是当前音频的控制者,也就是在系统控制中心中当前音频播放程序必须是我们自己开发程序。

第一第二点比较好理解,第三点是何解?师爷。翻译翻译。
下拉我的手机,控制中心中有一个音乐快捷播放器。

 
控制中心.jpeg

如图所示,我的控制中心的音乐播放器被 米津玄师的Lemon 霸占着。。
第三点是指只有应用霸占着控制中心的音乐播放器时,才可以实现耳机的线控。此时我的应用明显没有具备这个条件。

如何获取播放器的控制权

既然已经知道了问题的原因,那我们就需要对症下药了。
为了获取控制中心播放器的控制权,我决定在应用开启的时候使用AVAudioPlayer播放一段几秒中的空白音频,此处是我随便写的一个demo,具体播放空白音频的时机各位开发者可以视情况而定,比如如果是用耳机线控做相机功能的朋友,可以选择在打开相机的时候使用AVAudioPlayer播放空白音频,获取播放器权限。

AVAudioPlayer的使用我就不细说了,直接上代码。    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

    [self becomeFirstResponder];

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"20" ofType:@"mp3"];
NSURL *url = [NSURL fileURLWithPath:filePath];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url fileTypeHint:nil error:nil]; if ([self.player prepareToPlay]) {
NSLog(@"音频文件准备就绪");
} [self.player play]; Class playingInfoCenter = NSClassFromString(@"MPNowPlayingInfoCenter");
if (playingInfoCenter) {
NSMutableDictionary *songInfo = [NSMutableDictionary dictionary];
//歌曲名称
[songInfo setObject:@"呜啦呜啦" forKey:MPMediaItemPropertyTitle];
//演唱者
[songInfo setObject:@"JOJO" forKey:MPMediaItemPropertyArtist]; [songInfo setObject:[[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"MP.png"]] forKey:MPMediaItemPropertyArtwork]; [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
}

为了证明确实获取了控制中心音乐播放器权限,使用MPNowPlayingInfoCenter设置播放器信息。

成功获取播放器权限后,我再次对我的耳机一整狂点,remoteControlReceivedWithEvent方法执行成功,nice~

总结

本次做耳机线控踩的坑主要是第三点前提
应用程序必须是当前音频的控制者,也就是在系统控制中心中当前音频播放程序必须是我们自己开发程序。
这点不太理解,花费了一天多的时间求索。所幸最后成功了,但解决问题的方法个人感觉并不是很聪明,如果有更好办法的朋友欢迎留言指教。

参考博客:
聊聊iOS开发中耳机的那点事(监听耳机拔插、耳机线控)
关于MPNowPlayingInfoCenter和MPRemoteCommandCenter

关于ios 的耳机线线控的更多相关文章

  1. iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...

  2. 转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一 ...

  3. iOS 耳机线控

    当你使用iphone的时候听音乐的时候,播放器在后台运行的时候,你仍然可以通过耳机来进行操作,完成曲目切换,快进,快退等功能!当然你的程序不一定是播放器应用,但是我们仍然可以让它具有这个功能,让用户通 ...

  4. iOS-触摸事件、手势识别、摇晃事件、耳机线控

    概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事件(手势操作).运动事件. ...

  5. iphone 耳机 线控

    有电话呼入时: 按一次接听电话: 快速按两次将电话转到语音信箱: 通话中: 按一次挂断电话: 通话中如果有第二个电话打进来时: 按一次保留当前通话并接听第二个电话: 按住两秒钟不放忽略(拒绝接听)第二 ...

  6. Unity3d IOS中的IGUI控件

    Unity3d IOS中的IGUI控件 @灰太龙  群63438968 我讲一下IOS中用的UI,我们采用IGUI,需要使用IGUI的高版本,在Unity3d 4.2中也可以使用的! 之前IGUI有个 ...

  7. 红米1S Mokee4.4.4 本人编译版耳机线控改动调音量以及上下曲方法

    改动的文件为,用Re管理器编辑: system/usr/keylayout/msm8226-tapan-snd-card_Button_Jack.kl 默认的耳机线控的上下键是切换上下曲功能,因此此文 ...

  8. Xamarin iOS教程之页面控件

    Xamarin iOS教程之页面控件 Xamarin iOS 页面控件 在iPhone手机的主界面中,经常会看到一排小白点,那就是页面控件,如图2.44所示.它是由小白点和滚动视图组成,可以用来控制翻 ...

  9. iOS学习之UIPickerView控件的关联选择

    接上篇iOS学习之UIPickerView控件的简单使用 接着上篇的代码 http://download.csdn.net/detail/totogo2010/4391870 ,我们要实现的效果如下: ...

随机推荐

  1. Android学习拾遗

    1. java中的flush()作用:强制将输出流缓冲区的数据送出. 2. 文件存储: 存储到内部:另外使用一个class实现,最开始初始化用了this,后来放在这里不合适,改成了带参数的构造方法. ...

  2. lambda表达式学习例子

    https://www.cnblogs.com/franson-2016/p/5593080.html https://www.cnblogs.com/fx-blog/p/11745205.html ...

  3. JdbcTemplate 的oracle分页

    @Autowired private JdbcTemplate jd; int ps1=Integer.valueOf(pageSize); int cp1=Integer.valueOf(currP ...

  4. 建立一个更高级别的查询 API:正确使用Django ORM 的方式

    https://www.oschina.net/translate/higher-level-query-api-django-orm

  5. activiti7流程变量的测试(设置全局变量)

    package com.zcc.activiti03; import org.activiti.engine.*;import org.activiti.engine.repository.Deplo ...

  6. promise的基本用法

    // Promise 对象,可以保存状态 //Promise 第一步 // 异步代码 写在 Promise的函数中 第二步 const promise = new Promise((resolve, ...

  7. firefox error downloading

    转自:http://blog.csdn.net/feigeswjtu/article/details/42146285 做过互联网开发的都知道,firefox是我们互联网开发必备浏览器之一,浏览器是载 ...

  8. Linux NIO 系列(04-3) epoll

    目录 一.why epoll 1.1 select 模型的缺点 1.2 epoll 模型优点 二.epoll API 2.1 epoll_create 2.2 epoll_ctl 2.3 epoll_ ...

  9. zabbix主动模式设置

    zabbix客户端发数据给服务端分为主被动两种模式,主动模式是zabbix客户端主动向服务端发送数据,被动模式是被动等待服务端来取数据. 主动模式: 客户端每隔一段时间主动向服务端发起连接请求--&g ...

  10. 36-python基础-python3-字典与列表的区别

    (1)不像列表,字典中的表项是不排序的.名为 spam 的列表中,第一个表项是 spam[0].但字典中没有“第一个”表项. (2)确定两个列表是否相同时,表项的顺序必须相同,但在字典确定两个字典是否 ...