Registering a headset button click with BroadcastReceiver in Android
Just wanted to answer my own question in case others come across similar issues.
The code does work, just I wasn't seeing the Toast because I had another headset button controller app installed (and running in the background), so I guess it took priority over mine. However when I put
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);//"android.intent.action.MEDIA_BUTTON"
MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
filter.setPriority(1000); //this line sets receiver priority
registerReceiver(r, filter);
It was able to work even with the other app installed. Also, you don't need both the above AND the XML, one or the other is fine as ways of registering the intent receiver.
How to detect android headset button click on 4.0 and higher
Have you registered your broadcast receiver in AndroidManifest.xml
?
<receiver android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
Android - Broadcast receiver to detect headset button click not working on API 23 (marshmallow)
Try int instead
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
int intKey = event.getKeyCode();
}
You probably get 2 different int values for 1 button.
Android - checking headset button click
If you are trying to listen for this from an activity in the foreground, use onKeyDown()
and watch for KEYCODE_MEDIA_PLAY_PAUSE
.
Use a BroadcastReceiver
for ACTION_MEDIA_BUTTON
if you are trying to listen for this event from the background (e.g., a service playing music).
Counting headset button clicks in BroadcastReceiver
If your BroadcastReceiver
is registered in the manifest, the BroadcastReceiver
will only exist for a single call to onReceive()
-- subsequent broadcasts may result in another BroadcastReceiver
instance. And a manifest-registered BroadcastReceiver
cannot fork threads, as the whole process may get shut down once onReceive()
is over.
I am skeptical that there a clean way to get your code to be reliable, as the media button simply was not designed for your intended use pattern.
Android: Handle headset buttons events and Send information to MainActivity
API 21 changed the entire media app APIs, now centering entirely around MediaSession. Instead of registering a BroadcastReceiver
(as was needed prior to API 18) or a PendingIntent
(via registerMediaButtonEventReceiver(PendingIntent)), you can receive callbacks directly in the MediaSession.Callback.
You can set up a MediaSession
via the following code:
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);
If you only want to handle media buttons while your activity is visible, you can just have your MediaSession
handled by the Activity itself (this would allow your Callback
to just be a variable in your Activity).
The Best practices in media playback talk from I/O 2016 goes through all of the details and other APIs required to build a great media app, although note that it uses MediaSessionCompat and the other Support Library classes as detailed in the Media playback and the Support Library blog post.
Related Topics
How to Solve the "Double-Checked Locking Is Broken" Declaration in Java
Java.Sql.Sqlexception: No Suitable Driver Found for Jdbc:Microsoft:Sqlserver
Creating Runnable Jar with Gradle
Dynamically Add CSS Stylesheets in Javafx
Android: Switch Camera When Button Clicked
Android Post Picture to Facebook Wall
Error Inflating When Extending a Class
Dx Bad Class File Magic (Cafebabe) or Version (0033.0000) with Adk14
Java - Declaring from Interface Type Instead of Class
How Can a Primitive Float Value Be -0.0? What Does That Mean
Math.Random, Only Generating a 0
Should I Use Java Date and Time Classes or Go with a 3Rd Party Library Like Joda Time
"Loadstylesheetunprivileged" Error When Trying to Use CSS Stylesheet with Javafx
Java.Lang.Illegalmonitorstateexception: Object Not Locked by Thread Before Wait()