Android耳机线控具体解释,蓝牙耳机button监听(仿酷狗线控效果)
转载请注明出处:http://blog.csdn.net/fengyuzhengfan/article/details/46461253
当耳机的媒体按键被单击后。Android系统会发出一个广播。该广播的携带者一个Action名为MEDIA_BUTTON的Intent。监听该广播便能够获取手机的耳机媒体按键的单击事件。
在Android中有个AudioManager类,该类会维护MEDIA_BUTTON广播的分发。所以要实现耳机按键监听须要向AudioManager注冊一个用于接收耳机按键单击事件的接收器:
- AudioManager audioManager = (AudioManager)context
- .getSystemService(Context.AUDIO_SERVICE);
- ComponentName name = newComponentName(context.getPackageName(),
- MediaButtonReceiver.class.getName());
- audioManager.registerMediaButtonEventReceiver(name);
该方法的原型为:
publicvoid registerMediaButtonEventReceiver (PendingIntent eventReceiver)
Added in API level 18
Registera component to be the sole receiver of MEDIA_BUTTON intents. This is like registerMediaButtonEventReceiver(android.content.ComponentName),
but allows the buttons to go to any PendingIntent. Note that you shouldonly use this form if you know you will continue running for the full timeuntil unregistering the PendingIntent.
Parameters
eventReceiver |
target that will receive media button intents. The PendingIntent will be sent an ACTION_MEDIA_BUTTON event |
从API凝视中可知:
1、 在AudioManager对象注冊一个MediaoButtonRecevie,使它成为MEDIA_BUTTON的唯一接收器,也就是说仅仅有我能收到,其它的都收不到这个广播了,否则的话大家都收到会照成一定的混乱;
2、该广播必须在AndroidManifest.xml文件里进行声明。否则就监听不到该MEDIA_BUTTON广播了。
注,由于当我们注冊了AudioManager媒体按键的接收器。而且该接收器是媒体按键的唯一接收器。所以要在不使用按键监听的时候取消该注冊:
- AudioManager audioManager = (AudioManager)context .getSystemService(Context.AUDIO_SERVICE);
- ComponentName name = newComponentName(context.getPackageName(), MediaButtonReceiver.class.getName());
- audioManager.unregisterMediaButtonEventReceiver(name);
当耳机媒体键发生单击事件的时候Android系统会发出两次广播,第一次是按键按下去的时候,第二次是松开按键的时候,为了可以准确的获知用户单击了几次媒体键,我们仅仅须要在按键松开的时候处理单击事件就可以:
- KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); //获得KeyEvent对象
- if(keyEvent.getAction()== KeyEvent.ACTION_UP){
- //在这里处理单击事件
- }
以下就分别解说一下为了实现线控效果所用到的几个类:
1. 耳机线控管理工具类HeadSetUtil:
- package com.jph.lc;
- import android.content.ComponentName;
- import android.content.Context;
- import android.media.AudioManager;
- import android.util.Log;
- /**
- * 耳机线控管理工具类 单例
- * @author JPH
- * @date 2015-6-9 下午4:03:45
- */
- public class HeadSetUtil {
- private static HeadSetUtil headSetUtil;
- private OnHeadSetListener headSetListener = null;
- public static HeadSetUtil getInstance() {
- if (headSetUtil == null) {
- headSetUtil = new HeadSetUtil();
- }
- return headSetUtil;
- }
- /**
- * 设置耳机单击双击监听接口 必须在open前设置此接口,否则设置无效
- * @param headSetListener
- */
- public void setOnHeadSetListener(OnHeadSetListener headSetListener) {
- this.headSetListener = headSetListener;
- }
- /**
- * 为MEDIA_BUTTON 意图注冊接收器(注冊开启耳机线控监听, 请务必在设置接口监听之后再调用此方法,否则接口无效)
- * @param context
- */
- public void open(Context context) {
- if(headSetListener==null){
- throw new IllegalStateException("please set headSetListener");
- }
- AudioManager audioManager = (AudioManager) context
- .getSystemService(Context.AUDIO_SERVICE);
- ComponentName name = new ComponentName(context.getPackageName(),
- MediaButtonReceiver.class.getName());
- audioManager.registerMediaButtonEventReceiver(name);
- Log.i("ksdinf", "open");
- }
- /**
- * 关闭耳机线控监听
- * @param context
- */
- public void close(Context context) {
- AudioManager audioManager = (AudioManager) context
- .getSystemService(Context.AUDIO_SERVICE);
- ComponentName name = new ComponentName(context.getPackageName(),
- MediaButtonReceiver.class.getName());
- audioManager.unregisterMediaButtonEventReceiver(name);
- }
- /**
- * 删除耳机单机双击监听接口
- */
- public void delHeadSetListener() {
- this.headSetListener = null;
- }
- /**
- * 获取耳机单击双击接口
- *
- * @return
- */
- protected OnHeadSetListener getOnHeadSetListener() {
- return headSetListener;
- }
- /**
- * 耳机button单双击监听
- */
- public interface OnHeadSetListener {
- /**
- * 单击触发,主线程。
- 此接口真正触发是在单击操作1秒后 由于须要推断1秒内是否仍监听到点击,有的话那就是双击了
- */
- public void onClick();
- /**
- * 双击触发,此接口在主线程。能够放心使用
- */
- public void onDoubleClick();
- /**
- * 三连击
- */
- public void onThreeClick();
- }
- }
该类主要负责媒体按键接收器的注冊和自己定义媒体按键回调监听器的设置。
该类中包括一个OnHeadSetListener接口,该接口中的onClick(),onDoubleClick()。onThreeClick()三个方法分别会在单击事件。双击事件,以及三连击事件发生时被回调。
须要指出的是。单击和双击事件会有1秒的延迟,这是由于在这1秒内须要监听是否还有单击发生的原因,当然这1s也不是绝对的,你也能够依据实际的业务须要自己定义事件。
在以下解说的这个类中将会解开酷狗线控的原理。
2.耳机媒体按键广播接收器MediaButtonReceiver:
- package com.jph.lc;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.KeyEvent;
- import com.jph.lc.HeadSetUtil.OnHeadSetListener;
- /**
- * MEDIA_BUTTON耳机媒体按键广播接收器
- * @author JPH
- * @Date2015-6-9 下午8:35:40
- */
- public class MediaButtonReceiver extends BroadcastReceiver{
- private Timer timer = null;
- private OnHeadSetListener headSetListener = null;
- private static MTask myTimer = null;
- /**单击次数**/
- private static int clickCount;
- public MediaButtonReceiver(){
- timer = new Timer(true);
- this.headSetListener = HeadSetUtil.getInstance().getOnHeadSetListener();
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.i("ksdinf", "onReceive");
- String intentAction = intent.getAction() ;
- if(Intent.ACTION_MEDIA_BUTTON.equals(intentAction)){
- KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); //获得KeyEvent对象
- if(headSetListener != null){
- try {
- if(keyEvent.getAction() == KeyEvent.ACTION_UP){
- if (clickCount==0) {//单击
- clickCount++;
- myTimer = new MTask();
- timer.schedule(myTimer,1000);
- }else if (clickCount==1) {//双击
- clickCount++;
- }else if (clickCount==2) {//三连击
- clickCount=0;
- myTimer.cancel();
- headSetListener.onThreeClick();
- }
- }
- } catch (Exception e) {
- }
- }
- }
- abortBroadcast();//终止广播(不让别的程序收到此广播,免受干扰)
- }
- /**
- * 定时器,用于延迟1秒,推断是否会发生双击和三连击
- */
- class MTask extends TimerTask{
- @Override
- public void run() {
- try {
- if (clickCount==1) {
- mhHandler.sendEmptyMessage(1);
- }else if (clickCount==2) {
- mhHandler.sendEmptyMessage(2);
- }
- clickCount=0;
- } catch (Exception e) {
- // TODO: handle exception
- }
- }
- };
- /**
- * 此handle的目的主要是为了将接口在主线程中触发
- * ,为了安全起见把接口放到主线程触发
- */
- Handler mhHandler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if(msg.what==1){//单击
- headSetListener.onClick();
- }else if (msg.what==2) {//双击
- headSetListener.onDoubleClick();
- }else if (msg.what==3) {//三连击
- headSetListener.onThreeClick();
- }
- }
- };
- }
该类主要负责接收系统发出的媒体案件的单击事件。并对单击事件做对应的处理以达到单击。双击。三连击的效果。须要指出的是该类在实例化的时候会获取OnHeadSetListener监听器,所以要在调用HeadSetUtil类的open方法用之前设置OnHeadSetListener。否则将不会对媒体按键事件做处理。
该类中有个名为Mtask的内部类,该内部类是一个定时任务,该任务会在指定的时间里分析是否会发生双击和三连击。
另外,该类中另一个myHandler对象,该对象是为了将回调监听发生在UI线程中,以方便UI的更新。
3.监听器的使用类MainActivity:
- package com.jph.lc;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.TextView;
- import com.jph.lc.HeadSetUtil.OnHeadSetListener;
- /**
- * 耳机线控实例。蓝牙耳机button监听(仿酷狗线控效果)
- * @author JPH
- * @Date2015-6-10 上午9:49:02
- */
- public class MainActivity extends Activity {
- TextView txt = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- txt = (TextView) findViewById(R.id.text);
- HeadSetUtil.getInstance().setOnHeadSetListener(headSetListener);
- HeadSetUtil.getInstance().open(this);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- HeadSetUtil.getInstance().close(this);
- }
- OnHeadSetListener headSetListener = new OnHeadSetListener() {
- @Override
- public void onDoubleClick() {
- txt.setText("双击");
- Log.i("ksdinf", "双击");
- }
- @Override
- public void onClick() {
- txt.setText("单击");
- Log.i("ksdinf", "单击");
- }
- @Override
- public void onThreeClick() {
- txt.setText("三连击");
- Log.i("ksdinf", "三连击");
- }
- };
- }
该类中举要介绍了媒体按键监听的使用。
源代码下载:http://download.csdn.net/detail/fengyuzhengfan/8797357
Android耳机线控具体解释,蓝牙耳机button监听(仿酷狗线控效果)的更多相关文章
- Second Day: 关于Button监听事件的三种方法(匿名类、外部类、继承接口)
第一种:通过匿名类实现对Button事件的监听 首先在XML文件中拖入一个Button按钮,并设好ID,其次在主文件.java中进行控件初始化(Private声明),随后通过SetOnClickLis ...
- 仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)
转载请说明原出处,谢谢~~ 整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果 ...
- Android开发之手势滑动(滑动手势监听)详解
Android开发之手势滑动(滑动手势监听)详解 在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListen ...
- Android软键盘的隐藏显示、事件监听的代码
把开发过程中重要的一些内容片段做个珍藏,如下资料是关于Android软键盘的隐藏显示.事件监听的内容,应该是对小伙伴们有所用途. public class ResizeLayout extends L ...
- 背水一战 Windows 10 (66) - 控件(WebView): 监听和处理 WebView 的事件
[源码下载] 背水一战 Windows 10 (66) - 控件(WebView): 监听和处理 WebView 的事件 作者:webabcd 介绍背水一战 Windows 10 之 控件(WebVi ...
- Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听
原文:Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听 简单记录下android 盒子开发遥控器的监听 ,希望能帮到新入门的朋友们 不多说,直接贴代码 public cla ...
- Android修行之路------List view无法获取监听方法
注意: 1.在list view自定义布局中如果添加滚动布局,会导致自定义布局无法获取监听. 2.如果ListView的每项布局里有像Button,ImageButton之类View的控键时,这些Vi ...
- Android的事件处理机制详解(二)-----基于监听的事件处理机制
基于监听的事件处理机制 前言: 我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应 这就涉及到了android的事件处理机制; android给我们提供了两套功能强大的处理机制 ...
- UGUI研究院之控件以及按钮的监听事件系统
继续学习,我相信大家在做NGUI开发的时候处理事件都会用到UIEventListener,那么UGUI中怎么办呢?先看UGUI的事件有那些吧 Supported Events The Eventsys ...
随机推荐
- luogu P2078 朋友
题目背景 小明在A公司工作,小红在B公司工作. 题目描述 这两个公司的员工有一个特点:一个公司的员工都是同性. A公司有N名员工,其中有P对朋友关系.B公司有M名员工,其中有Q对朋友关系.朋友的朋友一 ...
- luogu P3353 在你窗外闪耀的星星
问题:天空可以理解为一条数轴,在这条数轴上分布着许多颗星星,对于每颗星星都有它的位置Xi和自身的亮度Bi.而窗户所能看到的范围是一个给出的参数W,我们看到的星星也包括窗户边缘的星星.现在,要你求出调整 ...
- 三、C++ const分析
1.C语言中的const: const修饰的变量是只读的,本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在只读存储区分配空间 const只在编译期有用,在运行期无效 c ...
- java 图片合成文字或者awt包下的对话框引入自定义字体库
成就卡图片字体问题:1.下载 xxx.ttf 文件2.mkdir /usr/local/jdk1.6.0_11/jre/lib/fonts/fallback. 在jre/lib/fonts 下 ...
- python基础(一)—— 核心数据类型
Hello World程序 [root@mysql ~]# python3 Python 3.6.5 (default, Jul 8 2018, 11:41:23) [GCC 4.4.7 20120 ...
- 队列的JS实现及广度优先搜索(BFS)的实现
队列是先进先出(FIFO)的数据结构,插入操作叫做入队,只能添加在队列的末尾:删除操作叫做出队,只能移除第一个元素.在JS中,用数组可以很简单的实现队列.JavaScript实现排序算法 functi ...
- python基础002
1.pycharm安装与添加解释器 专业版.英文界面,不要汉化—一定要尊重知识产权 算术运算符:+ - * / // % ** ^ 布尔运算符:== > < >= <= 逻辑运 ...
- python基础——6(字符编码,文件操作)
今日内容: 1.字符编码: 人识别的语言与机器识别的语言转化的媒介 ***** 2.字符与字节: 字符占多少字节,字符串转化 *** 3.文件操作: 操作硬盘中的一块区域:读写操作 ...
- SSRS ( .rdl文件)如何动态的设置导出Excel文件中的工作表标签名
要实现以上效果,则在Tablix属性里设置 参考:https://dotblogs.com.tw/ricochen/archive/2012/06/14/72798.aspx
- Leetcode 309.最佳买卖股票时机含冷冻期
最佳买卖股票时机含冷冻期 给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格. 设计一个算法计算出最大利润.在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票): 你不 ...