Android监听耳机按键事件

在工作中,我们有时候会处理到耳机按键的逻辑,主要分为两类,一种是短按,一种是长按。

监听耳机的按键事件的方法有两种:

方法一:注册监听Media Button的按键事件

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;

public class MainActivity extends Activity {

	private AudioManager mAudioManager;
	private ComponentName mComponentName;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        // AudioManager注册一个MediaButton对象
		mComponentName = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName());
	}

	@Override
	protected void onResume() {
		 mAudioManager.registerMediaButtonEventReceiver(mComponentName);
	     registerReceiver(headSetReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
		super.onResume();
	}

	@Override
	protected void onPause() {
		// 取消注册
		mAudioManager.unregisterMediaButtonEventReceiver(mComponentName);
		unregisterReceiver(headSetReceiver);
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		mAudioManager = null;
		mComponentName = null;
		super.onDestroy();
	}

	private final BroadcastReceiver headSetReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
				// phone headset plugged
				if (intent.getIntExtra("state", 0) == 1) {
					// do something
//					Log.d(TAG, "耳机检测:插入");
//					Toast.makeText(context, "耳机检测:插入", Toast.LENGTH_SHORT) .show();
					mAudioManager.registerMediaButtonEventReceiver(mComponentName);
					// phone head unplugged
				} else {
					// do something
//					Log.d(TAG, "耳机检测:没有插入");
//					Toast.makeText(context, "耳机检测:没有插入", Toast.LENGTH_SHORT).show();
					mAudioManager.unregisterMediaButtonEventReceiver(mComponentName);
				}
			}
		}
	};

MediaButtonReceiver.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;

public class MediaButtonReceiver extends BroadcastReceiver {

	private static String TAG = "MediaButtonReceiver";

	@Override
	public void onReceive(Context context, Intent intent) {

		// 获得Action
		String intentAction = intent.getAction();
		// 获得KeyEvent对象
		KeyEvent keyEvent = (KeyEvent) intent
				.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

		Log.i(TAG, "Action ---->" + intentAction + "  KeyEvent----->"
				+ keyEvent.toString());
		// 按下 / 松开 按钮
		int keyAction = keyEvent.getAction();

		if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)
				&& (KeyEvent.ACTION_DOWN == keyAction)) {
			// 获得按键字节码
			int keyCode = keyEvent.getKeyCode();

			// 获得事件的时间
			// long downtime = keyEvent.getEventTime();

			// 获取按键码 keyCode
//			StringBuilder sb = new StringBuilder();
//			// 这些都是可能的按键码 , 打印出来用户按下的键
//			if (KeyEvent.KEYCODE_MEDIA_NEXT == keyCode) {
//				sb.append("KEYCODE_MEDIA_NEXT");
//			}
			// 说明:当我们按下MEDIA_BUTTON中间按钮时,实际出发的是 KEYCODE_HEADSETHOOK 而不是
			// KEYCODE_MEDIA_PLAY_PAUSE
			if (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE == keyCode) {
//				sb.append("KEYCODE_MEDIA_PLAY_PAUSE");

			}
			if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) {
//				sb.append("KEYCODE_HEADSETHOOK");
			}
			if (KeyEvent.KEYCODE_MEDIA_PREVIOUS == keyCode) {
//				sb.append("KEYCODE_MEDIA_PREVIOUS");
			}
			if (KeyEvent.KEYCODE_MEDIA_STOP == keyCode) {
//				sb.append("KEYCODE_MEDIA_STOP");
			}
			// 输出点击的按键码
//			Log.i(TAG, sb.toString());
//			Toast.makeText(context, sb.toString(), Toast.LENGTH_SHORT).show();
		} else if (KeyEvent.ACTION_UP == keyAction) {
			Log.i("chengjie", "aaa");
		}
	}
}

注意,在AndroidManifest.xml中定义

 <receiver android:name="com.lenovo.longexposure.MediaButtonReceiver" >
            <intent-filter android:priority="2147483647" >
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
 </receiver>

注意这种方法只能监听耳机的短按事件,如果想监听长按事件,请用方法二。

方法二:直接监听onKeyDown方法

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) { //按下了耳机键
			if (event.getRepeatCount() == 0) {  //如果长按的话,getRepeatCount值会一直变大
				//短按
			} else {
				//长按
			}
		}
}

时间: 2024-08-25 17:31:03

Android监听耳机按键事件的相关文章

Android学习按键事件监听与Command模式

Android学习按键事件监听与Command模式 - Dufresne - 博客园 ? 一 Command模式 意图: 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化: 对请求排队或记录请求日志,以及支持可撤销的操作. 将请求被封装成一个对象,当向某对象提交请求时,使我们可以不用去知道被具体的请求的操作或者请求的接收者, 实现了动作的请求者对象和动作的执行者对象之间的解耦合. 适用性: 使用Command模式代替callback形式的回调应用: 在不同的时刻指定.排列和执行请

Android View 按键事件分发流程 onTouch onTouchEvent onClick onLongClick 和 onKey onKeyDown onClick

1.为了测试,我们同时将View 设置 onTouch  onTouchEvent  onClick onLongClick 四个事件,经过加打印测试发现,按键分发流程是这样的 如果是短按:onTouch-->>onTouchEvent--->>onClick .长按:onTouch-->>onTouchEvent--->>onLongClick-->>onClick.为什么会是这样? 我们看View 源码 public boolean disp

Android怎样监听蓝牙耳机的按键事件

写在前面: 直接想要代码非常easy,你直接把滚动栏拉到最底端就能够看到.假设想要十分地了解为什么,那就依照我规划的一步一步来理解.下面測试环境以手头上有的「Bluedio + 红米手机」. 1.蓝牙耳机的使用 蓝牙耳机的使用说明书中都会有相关的具体使用说明,这里拣重点说明一下.除了电源开关,耳机上一般有三个键.例如以下所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2FuZ2Vhcg==/font/5a6L5L2T/fontsize/40

Android按键事件发布流程

总结一下,Android按键事件发布流程 //InputReader.cpp void InputReader::loopOnce() { ... size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);      if (count) { processEventsLocked(mEventBuffer, count); } ...  } InputReader线程启动后,循环调用l

android 应用监听输入法按键事件【比如搜索和回车键等】的整个流程分析

继承于InputMethodService类的服务代码如下: int keyCode = sKey.getKeyCode(); KeyEvent eDown = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, keyCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD); KeyEvent eUp = new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode, 0, 0, 0, 0, Ke

Android如何监听蓝牙耳机的按键事件(转)

源: Android如何监听蓝牙耳机的按键事件 写在前面: 直接想要代码很简单,你直接把滚动条拉到最底端就可以看到.如果想要十分地了解为什么,那就按照我规划的一步一步来理解.以下测试环境以手头上有的「Bluedio + 红米手机」. 1.蓝牙耳机的使用 蓝牙耳机的使用说明书中都会有相关的详细使用说明,这里拣重点说明一下.除了电源开关,耳机上一般有三个键.如下所示: 它们每个都是多功能键,在不同的情况下有不同的功能.1号键的功能包括:开始播放音乐/停止插入音乐/接听电话/挂断电话:2号键的功能有:

Android锁屏状态获取音量按键事件

Android系统没有提供音量按键的广播,而Activity的onKeyDown方法只有在界面显示时才能捕获音量变化, 要在锁屏状态或后台获得音量按键事件,可以通过判断音量值的改变来判断是否按下了音量键.实现的具体思路是: 开一个子线程,持续判断当前音量值和之前音量值是否一致,如果不同说明按下了音量键,并且重置音量值,使音量不在最大值或最小值上. package com.hy2014.phonesafer.activity; import android.app.Activity; import

quick-cocos2d-x游戏开发【12】——硬件按键事件

在quick中,对于按键事件也进行了重新封装,和node的触摸事件一样,也是通过addNodeEventListener来实现.所谓按键事件,主要是针对于android设备中的返回键"back"和菜单键"menu"的响应,在前面的一篇博文中我也简单提过一次,不过咱们还是系统性的来学习一下. 首先清楚预定义的层事件有两个, cc.ACCELERATE_EVENT     - 重力感应事件 cc.KEYPAD_EVENT                - 硬件按键事件

android 虚拟按键是通过哪种机制上报的?

1.在normal mode下,tp button也是和其他触摸事件一样,以坐标形式的input_event进行上报.在初始化时会通过tpd_button_setting()函数依据定义在tpd_custom_XXX.h文件里的配置信息将虚拟按键的坐标信息写在/sys/board_properties/virtualkeys.mtk-tpd中. 工作时.tp driver将按下的点的坐标进行上报.Android上层会读取sys中的按键配置信息.再推断上报的坐标是否属于某个按键的坐标范围,以此将坐