在工作中,我們有時候會處理到耳機按鍵的邏輯,主要分為兩類,一種是短按,一種是長按。
監聽耳機的按鍵事件的方法有兩種:
方法一:註冊監聽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 {
//長按
}
}
}
--------------------------------分隔線-------------------------------------------------------------------
BroadcastReceiver基本使用方法:
BroadcastReceiver用於監聽被廣播的事件(Intent)
為了達到這個目的,BroadcastReceiver必須進行註冊,註冊方法有以下2種:
1. 在AndroidManifest.xml當中進行註冊
2. 在應用程式的代碼當中進行註冊
第一種方法:
activity_test.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.testbroadcastreceiver.TestActivity" >
<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sendBroadcaster" />
</RelativeLayout>
TestActivity.java :
public class TestActivity extends Activity {
private Button sendButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
sendButton = (Button) findViewById(R.id.sendButton);
sendButton.setOnClickListener(new BroadcastListener());
}
class BroadcastListener implements OnClickListener {
@Override
public void onClick(View v) {
System.out.println("發送intent");
//宣告一個intent,把需要用到的廣播裝入intent再送出給Receive
//,讓Receiver根據收到的廣播來處理自訂要做的事
Intent intent = new Intent();
intent.setAction(Intent.ACTION_EDIT);
TestActivity.this.sendBroadcast(intent);
}
}
}
TestReceiver.java:
public class TestReceiver extends BroadcastReceiver{
public TestReceiver(){
System.out.println("啟動TestReceiver");
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("執行OnReceiver");
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testbroadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".TestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在這裡寫入TestReceiver,並把廣播動作都寫進去。
<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
</intent-filter>
</receiver>
</application>
</manifest>
執行結果:
發送intent
啟動TestReceiver
執行OnReceiver
第二種方法:
1 註冊BroadcastReceiver:
registerReceiver(receiver,filter);
2 取消註冊BroadcastReceiver(receiver);
如果一個BroadcastReceiver用於更新UI,那麼通常會使用這種方法進行註冊
在Activity啟動的時候註冊BroadcastReceiver,在Activity被摧毀以後取消註冊
activity_test.xml:
BroadcastReceiver基本使用方法:
BroadcastReceiver用於監聽被廣播的事件(Intent)
為了達到這個目的,BroadcastReceiver必須進行註冊,註冊方法有以下2種:
1. 在AndroidManifest.xml當中進行註冊
2. 在應用程式的代碼當中進行註冊
第一種方法:
activity_test.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.testbroadcastreceiver.TestActivity" >
<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sendBroadcaster" />
</RelativeLayout>
TestActivity.java :
public class TestActivity extends Activity {
private Button sendButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
sendButton = (Button) findViewById(R.id.sendButton);
sendButton.setOnClickListener(new BroadcastListener());
}
class BroadcastListener implements OnClickListener {
@Override
public void onClick(View v) {
System.out.println("發送intent");
//宣告一個intent,把需要用到的廣播裝入intent再送出給Receive
//,讓Receiver根據收到的廣播來處理自訂要做的事
Intent intent = new Intent();
intent.setAction(Intent.ACTION_EDIT);
TestActivity.this.sendBroadcast(intent);
}
}
}
TestReceiver.java:
public class TestReceiver extends BroadcastReceiver{
public TestReceiver(){
System.out.println("啟動TestReceiver");
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("執行OnReceiver");
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testbroadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".TestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在這裡寫入TestReceiver,並把廣播動作都寫進去。
<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
</intent-filter>
</receiver>
</application>
</manifest>
執行結果:
發送intent
啟動TestReceiver
執行OnReceiver
第二種方法:
1 註冊BroadcastReceiver:
registerReceiver(receiver,filter);
2 取消註冊BroadcastReceiver(receiver);
如果一個BroadcastReceiver用於更新UI,那麼通常會使用這種方法進行註冊
在Activity啟動的時候註冊BroadcastReceiver,在Activity被摧毀以後取消註冊
activity_test.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.testbroadcastreceiver.TestActivity" >
<Button
android:id="@+id/registerButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="regBroadcaster" />
<Button
android:id="@+id/unregisterButton"
android:layout_width="wrap_content"
android:layout_below="@+id/registerButton"
android:layout_height="wrap_content"
android:text="UnBroadcaster" />
</RelativeLayout>
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.testbroadcastreceiver.TestActivity" >
<Button
android:id="@+id/registerButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="regBroadcaster" />
<Button
android:id="@+id/unregisterButton"
android:layout_width="wrap_content"
android:layout_below="@+id/registerButton"
android:layout_height="wrap_content"
android:text="UnBroadcaster" />
</RelativeLayout>
TestActivity.java:
public class TestActivity extends Activity {
private Button registerButton;
private Button unregisterButton;
private SMSReceiver smsReceiver = null ;
private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
registerButton = (Button) findViewById(R.id.registerButton);
unregisterButton = (Button) findViewById(R.id.unregisterButton);
registerButton.setOnClickListener(new RegisterButtonListener());
unregisterButton.setOnClickListener(new UnRegisterButtonListener());
}
class RegisterButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
smsReceiver = new SMSReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(SMS_ACTION);
TestActivity.this.registerReceiver(smsReceiver, filter);
System.out.println("註冊廣播");
}
}
class UnRegisterButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
System.out.println("取消註冊");
}
}
}
private Button registerButton;
private Button unregisterButton;
private SMSReceiver smsReceiver = null ;
private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
registerButton = (Button) findViewById(R.id.registerButton);
unregisterButton = (Button) findViewById(R.id.unregisterButton);
registerButton.setOnClickListener(new RegisterButtonListener());
unregisterButton.setOnClickListener(new UnRegisterButtonListener());
}
class RegisterButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
smsReceiver = new SMSReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(SMS_ACTION);
TestActivity.this.registerReceiver(smsReceiver, filter);
System.out.println("註冊廣播");
}
}
class UnRegisterButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
System.out.println("取消註冊");
}
}
}
BroadcastReceiver.java
public class SMSReceiver extends BroadcastReceiver{
public SMSReceiver(){
System.out.println("啟動TestReceiver");
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("執行OnReceiver");
}
}
public SMSReceiver(){
System.out.println("啟動TestReceiver");
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("執行OnReceiver");
}
}
當到DDMS的Emulator Control去記一封訊息,模擬器會收到訊息