2017-01-02 129 views
1

我正在使用MediaButton操作篩選器來接收藍牙耳機媒體按鈕事件。動作過濾器是工作android棒棒糖和低於版本,但不適用於Android M和以上。無法從藍牙耳機(PTT)設備獲取KeyEvent停止

在那些提到的設備中只有KeyEvent.KEYCODE_MEDIA_PLAY:正在工作。

已執行操作的列表。 1.單擊PTT(一鍵通)按鈕 - 得到了回調onReceive(Context context, Intent intent)與事件KeyEvent.KEYCODE_MEDIA_PLAY: 2.釋放PTT按鈕 - 應該得到回調onReceive(Context context, Intent intent)與事件KeyEvent.KEYCODE_MEDIA_STOP: - 但只有在上述設備沒有收到此事件。

我已經提到了我在下面使用的代碼。

艙單

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.pttsample"> 

<uses-permission android:name="android.permission.BLUETOOTH" /> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 
<uses-permission android:name="android.permission.INTERNET" /> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <receiver android:name=".MediaButtonReceiver"> 
     <intent-filter android:priority="1000000"> 
      <action android:name="android.intent.action.MEDIA_BUTTON" /> 

     </intent-filter> 
    </receiver> 
</application> 

接收機

public class MediaButtonReceiver extends BroadcastReceiver{ 

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

    String action = intent.getAction(); 

    if (action.equalsIgnoreCase(Intent.ACTION_MEDIA_BUTTON)) 
    { 

     KeyEvent event = (KeyEvent) intent 
       .getParcelableExtra(Intent.EXTRA_KEY_EVENT); 
     if (event == null) 
      return; 

     if (event.getKeyCode() != KeyEvent.KEYCODE_HEADSETHOOK 
       && event.getKeyCode() != KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE 
       && event.getAction() != KeyEvent.ACTION_DOWN) { 
      return; 
     } 

     Intent i = null; 

       Log.e("MEDIA CONTROLLER","Power Button Play app destroy"); 
     switch (event.getKeyCode()) 
     { 
      case KeyEvent.KEYCODE_HEADSETHOOK: 
       Log.e("MEDIA CONTROLLER","Power Button Play KEYCODE_HEADSETHOOK"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 
       Log.e("MEDIA CONTROLLER","Power Button Play MEDIA_PLAY_PAUSE"); 
       switch (event.getAction()) 
       { 
        case KeyEvent.ACTION_DOWN: 
         if (event.getRepeatCount() > 0) 
          break; 

         break; 
        case KeyEvent.ACTION_UP: 
         // long click 
         Log.e("MEDIA CONTROLLER","Power Button Play Action Up"); 
         break; 
        case KeyEvent.ACTION_MULTIPLE: 
         Log.e("MEDIA", "Action Multiple"); 
         break; 
       } 
       break; 
      //The following is the received from PTT device button 
      case KeyEvent.KEYCODE_MEDIA_PLAY: 
       Log.e("MEDIA CONTROLLER>>>","Button Play"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_PAUSE: 
       Log.e("MEDIA CONTROLLER","Power Button Pause"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: 
       Log.e("MEDIA CONTROLLER","audio track"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_CLOSE: 
       Log.e("MEDIA CONTROLLER","close"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_EJECT: 
       Log.e("MEDIA CONTROLLER","eject"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 
       Log.e("MEDIA CONTROLLER","fast forward"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_NEXT: 
       Log.e("MEDIA CONTROLLER","next"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 
       Log.e("MEDIA CONTROLLER","previous"); 
       break; 
      case KeyEvent.KEYCODE_MEDIA_RECORD: 
       Log.e("MEDIA CONTROLLER","record"); 
       break; 

      case KeyEvent.KEYCODE_MEDIA_REWIND: 
       Log.e("MEDIA CONTROLLER","rewind"); 
       break; 

      case KeyEvent.KEYCODE_MEDIA_STOP: 
       Log.e("MEDIA CONTROLLER","stop"); 
       break; 
     } 

     if (isOrderedBroadcast()) 
      abortBroadcast(); 
     if (i != null) 
      context.sendBroadcast(i); 
    } 


} 

MainActivity

已經嘗試添加以下內容。

mMediaControlClientReceiverComponent = new ComponentName(
      getPackageName(), MediaButtonReceiver.class.getName()); 
    mMediaStopReceiverComponent = new ComponentName(
      getPackageName(), MediaButtonReceiver.class.getName()); 

    audioManager = (AudioManager) this.getSystemService(AUDIO_SERVICE); 
    audioManagerStopOption = (AudioManager) this.getSystemService(AUDIO_SERVICE); 

    audioManager.registerMediaButtonEventReceiver(mMediaControlClientReceiverComponent); 
    audioManagerStopOption.registerMediaButtonEventReceiver(mMediaStopReceiverComponent); 
+0

您是否找到解決方案了。張貼在這裏。 – ADM

回答

0

我一直在努力解決同樣的問題。 我不知道這是Android的廣泛,但正在發生在我用來開發的Samsung S6上。

首先,即使沒有MediaSession,當您的UI是活動窗口(在屏幕上可見)時,也會發生這種情況。當UI處於活動狀態時,媒體密鑰將發送到活動。

下面是我如何解決這個問題。

您需要設置Audiomanager到MODE_NORMAL

audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);  
audioManager.setMode(AudioManager.MODE_NORMAL); 

在這一點上,甚至設置內部消除音頻焦點時,您將收到通過按麥克風PTT觸發MEDIA_PLAY。 您可以捕捉到這些與該keydown您的活動引發

@Override 
public boolean(int keyCode KeyEvent event){ 
    if (keyCode == 126) startPlay(); 
    return true; 
} 

然後你就可以例如開始播放與MediaPlayer的類的東西。 只有在實際播放MEDIA_STOP和其他密鑰將發送到您的應用程序的東西。

但是我認爲你正在創建某種Walky Talky應用程序。你會流RTP。我自己用AudioTrack類來做到這一點。使用play()啓動audiotrack時,還可以使用其他媒體鍵。

由於您可能想使用PTT MIC中的麥克風,因此必須使用藍牙sco進行連接。這也是通過AudioManager完成的。像這樣的東西

audio.setBluetoothScoOn(true); 
    audio.stopBluetoothSco(); 

但是,這打破了上述所有,只收到MEDIA_PLAY。 到目前爲止,我只找到了一種解決方案,那就是使用藍牙套接字。以下是我使用的課程。它是專爲Dellking PTT麥克風

package on4akh.be.remotehamming; 

import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothSocket; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Set; 
import java.util.UUID; 

public class BluetoothPtt { 
    private byte[] mmBuffer = new byte[1024]; 
    private InputStream in; 
    private BluetoothSocket socket; 
    private boolean isRunning = true; 
    private OnMessageReceived pttState = null; 

    public BluetoothPtt(OnMessageReceived listener){ 
     pttState = listener; 
     Set<BluetoothDevice> bs = BluetoothAdapter.getDefaultAdapter().getBondedDevices(); 
     for (BluetoothDevice device : bs){ 
      if (device.getName().equalsIgnoreCase("DellKing PTT Mic")){ 
       try{ 
        socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); 
        start(); 
       } 
       catch (IOException e){ 
        return; 
       } 
      } 
      return; 
     } 
    } 

    private void start(){ 
     new Thread(){ 
      @Override 
      public void run(){ 
       try { 
        socket.connect(); 
        in = socket.getInputStream(); 
       } 
       catch (IOException e){ 
        socket = null; 
        return; 
       } 

       while (isRunning){ 
        try { 
         if (socket.isConnected()){ 
          in.read(mmBuffer); 
          if (mmBuffer[5] == 80){ 
           pttState.isPressed(true); 
          } 
          else 
           { 
            pttState.isPressed(false); 
           } 
         } 
        } catch (IOException e) { 

        } 
       } 
      } 
     }.start(); 
    } 

    public void release(){ 
     isRunning = false; 
     try { 
      socket.close(); 
     } 
     catch (IOException e){ 

     } 
     socket = null; 
    } 

    public interface OnMessageReceived { 
     public void isPressed(boolean state); 
    } 
} 

你按下並釋放PTT按鈕時,都會有6字節碼是發送,其中第六個字節是80新聞82發佈。 類有,我用它來切換PTT在我的應用

BluetoothPtt ptt = new BluetoothPtt(new BluetoothPtt.OnMessageReceived(){ 
      @Override 
      public void isPressed(boolean state){ 
       togglePtt(); 
      } 
     }); 

希望你可以使用我的回答的onMessagedReceived聽衆。