日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线控耳机监听

發(fā)布時間:2023/11/30 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线控耳机监听 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

當耳機的媒體按鍵被單擊后,Android系統(tǒng)會發(fā)出一個廣播,該廣播的攜帶者一個Action名為MEDIA_BUTTON的Intent。監(jiān)聽該廣播便可以獲取手機的耳機媒體按鍵的單擊事件。

在Android中有個AudioManager類,該類會維護MEDIA_BUTTON廣播的分發(fā),所以要實現(xiàn)耳機按鍵監(jiān)聽需要向AudioManager注冊一個用于接收耳機按鍵單擊事件的接收器:

?

?
1 2 3 4 5 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 when a media button action occurs, with EXTRA_KEY_EVENT added and holding the key code of the media button that was pressed.

從API注釋中可知:

1、 在AudioManager對象注冊一個MediaoButtonRecevie,使它成為MEDIA_BUTTON的唯一接收器,也就是說只有我能收到,其他的都收不到這個廣播了,否則的話大家都收到會照成一定的混亂;

2、該廣播必須在AndroidManifest.xml文件中進行聲明,否則就監(jiān)聽不到該MEDIA_BUTTON廣播了。

注,因為當我們注冊了AudioManager媒體按鍵的接收器,并且該接收器是媒體按鍵的唯一接收器,所以要在不使用按鍵監(jiān)聽的時候取消該注冊:

?

?
1 2 3 AudioManager audioManager = (AudioManager)context??? .getSystemService(Context.AUDIO_SERVICE); ComponentName name = newComponentName(context.getPackageName(),??? MediaButtonReceiver.class.getName()); audioManager.unregisterMediaButtonEventReceiver(name);

?

當耳機媒體鍵發(fā)生單擊事件的時候Android系統(tǒng)會發(fā)出兩次廣播,第一次是按鍵按下去的時候,第二次是松開按鍵的時候,為了能夠準確的獲知用戶單擊了幾次媒體鍵,我們只需要在按鍵松開的時候處理單擊事件即可:

?

?
1 2 3 4 KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); //獲得KeyEvent對象 if(keyEvent.getAction()== KeyEvent.ACTION_UP){ //在這里處理單擊事件 }

?

下面就分別講解一下為了實現(xiàn)線控效果所用到的幾個類:

1. 耳機線控管理工具類HeadSetUtil:

?

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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; ????} ????/** ?????* 設(shè)置耳機單擊雙擊監(jiān)聽接口 必須在open前設(shè)置此接口,否則設(shè)置無效 ?????* @param headSetListener ?????*/ ????public void setOnHeadSetListener(OnHeadSetListener headSetListener) { ????????this.headSetListener = headSetListener; ????} ????/** ?????* 為MEDIA_BUTTON 意圖注冊接收器(注冊開啟耳機線控監(jiān)聽, 請務(wù)必在設(shè)置接口監(jiān)聽之后再調(diào)用此方法,否則接口無效) ?????* @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); ????} ????/** ?????* 關(guān)閉耳機線控監(jiān)聽 ?????* @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); ????} ????/** ?????* 刪除耳機單機雙擊監(jiān)聽接口 ?????*/ ????public void delHeadSetListener() { ????????this.headSetListener = null; ????} ????/** ?????* 獲取耳機單擊雙擊接口 ?????* ?????* @return ?????*/ ????protected OnHeadSetListener getOnHeadSetListener() { ????????return headSetListener; ????} ????/** ?????* 耳機按鈕單雙擊監(jiān)聽 ?????*/ ????public interface OnHeadSetListener { ????????/** ?????????* 單擊觸發(fā),主線程。 此接口真正觸發(fā)是在單擊操作1秒后 因為需要判斷1秒內(nèi)是否仍監(jiān)聽到點擊,有的話那就是雙擊了 ?????????*/ ????????public void onClick(); ????????/** ?????????* 雙擊觸發(fā),此接口在主線程,可以放心使用 ?????????*/ ????????public void onDoubleClick(); ????????/** ?????????* 三連擊 ?????????*/ ????????public void onThreeClick(); ????} }
該類主要負責媒體按鍵接收器的注冊和自定義媒體按鍵回調(diào)監(jiān)聽器的設(shè)置。該類中包含一個OnHeadSetListener接口,該接口中的onClick(),onDoubleClick(),onThreeClick()三個方法分別會在單擊事件,雙擊事件,以及三連擊事件發(fā)生時被回調(diào)。需要指出的是,單擊和雙擊事件會有1秒的延遲,這是因為在這1秒內(nèi)需要監(jiān)聽是否還有單擊發(fā)生的原因,當然這1s也不是絕對的,你也可以根據(jù)實際的業(yè)務(wù)需要自定義事件。在下面講解的這個類中將會解開酷狗線控的原理。

?

2.耳機媒體按鍵廣播接收器MediaButtonReceiver:

?

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 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; ????/**單擊次數(shù)**/ ????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秒,判斷是否會發(fā)生雙擊和三連擊 ?????*/ ????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的目的主要是為了將接口在主線程中觸發(fā) ?????* ,為了安全起見把接口放到主線程觸發(fā) ?????*/ ????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(); ????????????} ????????} ????}; ????????? }
該類主要負責接收系統(tǒng)發(fā)出的媒體案件的單擊事件,并對單擊事件做相應(yīng)的處理以達到單擊,雙擊,三連擊的效果。需要指出的是該類在實例化的時候會獲取OnHeadSetListener監(jiān)聽器,所以要在調(diào)用HeadSetUtil類的open方法用之前設(shè)置OnHeadSetListener,否則將不會對媒體按鍵事件做處理。

?

該類中有個名為Mtask的內(nèi)部類,該內(nèi)部類是一個定時任務(wù),該任務(wù)會在指定的時間里分析是否會發(fā)生雙擊和三連擊。

另外,該類中還有一個myHandler對象,該對象是為了將回調(diào)監(jiān)聽發(fā)生在UI線程中,以方便UI的更新。

3.監(jiān)聽器的使用類MainActivity:

?

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 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; /** ?* 耳機線控實例,藍牙耳機按鈕監(jiān)聽(仿酷狗線控效果) ?* @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, 三連擊); ????????} ????}; }

?

該類中舉要介紹了媒體按鍵監(jiān)聽的使用。

總結(jié)

以上是生活随笔為你收集整理的线控耳机监听的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。