2016-09-26 80 views
1

以下是我努力制作工作代码以处理耳机按钮事件的最佳方式。我读了Android developer guide,但它显然是错误的,因为他们要求开始监听注册类名。Android:处理耳机按钮事件并将信息发送至MainActivity

am.registerMediaButtonEventReceiver(RemoteControlReceiver); // Wrong 

因此,我查看其他示例以更正代码。例如,许多秘密的建议已发表在this question,我也尝试过其他的代码,如this,并与MediaSession另一种解决方案,并清洗不需要的,我写这个代码:

我实现了类RemoteControlReceiver。显然,没有必要对一个静态内部类,其实,看到this comment

public class RemoteControlReceiver extends BroadcastReceiver { 

     public RemoteControlReceiver() { 
      super(); 
     } 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      Toast.makeText(context, "EVENT!!", Toast.LENGTH_SHORT).show(); 
      if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { 
       KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 
       if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) { 
        Toast.makeText(context, "EVENT!!", Toast.LENGTH_SHORT).show(); 

       } 
      } 
     } 
    } 

然后我注册了MainActivity的onCreate(){里面的意图......

AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); 
    ComponentName mReceiverComponent = new ComponentName(this, RemoteControlReceiver.class); 
    am.registerMediaButtonEventReceiver(mReceiverComponent); 

的registerMediaButtonEventReceiver被废弃的方式...

在清单内我记录过滤器,在活动标记后:

<activity> 
... 
</activity> 

<receiver android:name=".RemoteControlReceiver" android:enabled="true"> 
    <intent-filter android:priority="2147483647"> 
     <action android:name="android.intent.action.MEDIA_BUTTON" /> 
    </intent-filter> 
</receiver> 

注意:使用静态内部类将是,例如,“.MainActivity $ RemoteControlReceiver”。

我的工作

compileSdkVersion 24 
buildToolsVersion "24.0.0" 
... 
minSdkVersion 21 
targetSdkVersion 24 

这里我的问题:

  • 为什么registerMediaButtonEventReceiver已经过时?看来现在所有这些范例都是错误的,但我没有发现如何在Android Developer Portal上处理这些类问题。
  • 我可以通过哪种方式与MainActivity交互?我的目的是在执行一些耳机操作时对MainActivity执行操作。
+0

你的清单声明'MainActivity $ MediaButtonReceiver',但你的类被称为'RemoteControlReceiver'。这是什么? – ianhanniballake

+0

谢谢@ianhanniballake硝酸那。这只是一个复制粘贴错字,但我在所有的实验中都实现了很多接收器。现在我纠正了它,我确认设置如上所述。 – donnadulcinea

回答

1

API 21更改了整个媒体应用程序API,现在整个集中在MediaSession左右。您可以直接在MediaSession.Callback中收到回调,而无需注册BroadcastReceiver(如API 18之前所需)或PendingIntent(通过registerMediaButtonEventReceiver(PendingIntent))。

您可以通过下面的代码建立一个MediaSession

MediaSession.Callback callback = new MediaSession.Callback() { 
    @Override 
    public void onPlay() { 
    // Handle the play button 
    } 
}; 
MediaSession mediaSession = new MediaSession(context, 
    TAG); // Debugging tag, any string 
mediaSession.setFlags(
    MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | 
    MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); 
mediaSession.setCallback(callback); 

// Set up what actions you support and the state of your player 
mediaSession.setState(
    new PlaybackState.Builder() 
    .setActions(PlaybackState.ACTION_PLAY | 
       PlaybackState.ACTION_PAUSE | 
       PlaybackState.ACTION_PLAY_PAUSE); 
    .setState(PlaybackState.STATE_PLAYING, 
     0, // playback position in milliseconds 
     1.0); // playback speed 

// Call this when you start playback after receiving audio focus 
mediaSession.setActive(true); 

如果你只是想处理的多媒体按键,而你的活动是可见的,你可以有你的MediaSession由活动本身处理(这将允许您的Callback只是您的活动中的一个变量)。

Best practices in media playback talk from I/O 2016遍历所有的细节,并建立一个伟大的媒体应用所需的其他API,但是注意,它使用MediaSessionCompat和作为Media playback and the Support Library blog post详述的其他支持库类。

+0

这就是@ianhanniballake,我想找到有关新的最佳实践的信息。所有附加的参考文献也是有用的。谢谢! – donnadulcinea