1

I am developing a sort of an easy app in Android Studio and I want to have a code that detects when a button of the headphones is pressed, (so that then elicits and action).

I have been looking up on Internet and searching everywhere, and all scripts that I have found, have not worked.

Either due to problems with the versions of Android or because the code just "gets red" and for reasons I don't know, it just doesn't work. I am really desperate and needy of that code. So I'd be so thankful if someone is able to share one.

For instance, here is a code I was using:

 public static class MediaButtonIntentReceiver extends BroadcastReceiver {
    // int E=0;

    public MediaButtonIntentReceiver() {
        super();
    }


    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) { //Si la acción capturada en intentaction no equivale a una puñsación de boton entonces sale de el método debido al return
            MainActivity.E= 7;
            return;
        }
        KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); //extra key se refiere a el de los auriculares
        if (event == null) {         //Si event es null, return. Event equivale a extrakeyevent. osea que si no hay extrakey event, return
            MainActivity.E= 7;    return;
        }
        int action = event.getAction();
        if (action == KeyEvent.ACTION_DOWN) { //Lo que hará cuando sea pulsado

            MainActivity.E= MainActivity.E+1;


            // do something




        }
        abortBroadcast();
    }


}

With the following in the manifest:

<receiver android:name="OuterClass$MediaButtonIntentReceiver">
            <intent-filter   android:priority="2147483647">
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
        </receiver>

The thing is that, when I run the app, and I press the media button of the headphones, nothing happens with the MediaPlayer of Android (As it should normally happen), and that indicates that, in point of fact, the app is having the priority for these buttons over the mediaPlayer of Android. However, nothing happens in the app either with the presses (when it is supposed to happen something). I have to add too, that when the press is long, the a kind of app of Google is opened. I am not interested in long presses though.

Also I have to mention that from where I extracted this, there was more code apart from the already seen, for instance there were things like:

  //AudioManager mAudioManager =  (AudioManager) getSystemService(Context.AUDIO_SERVICE);
       //ComponentName mReceiverComponent = new ComponentName(this, MediaButtonIntentReceiver.class);

    //mAudioManager.registerMediaButtonEventReceiver(mReceiverComponent);

  //  mAudioManager.unregisterMediaButtonEventReceiver(mReceiverComponent);

(these lines were discarded by me) Anyway this code did not work because Android studio says that they are obsolete.

I also found:

// BroadcastReceiver MediaButtonIntentReceiver = new MediaButtonIntentReceiver(); // MediaButtonIntentReceiver mMediaButtonReceiver = new MediaButtonIntentReceiver(); // IntentFilter mediaFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); //mediaFilter.setPriority(1000000000); // registerReceiver(mMediaButtonReceiver, mediaFilter);

I put it within the onCreate of the MainActivity. And did not work either.

I found a last code in another question of this forum. Which don't work as some parts of the code appear in red (the callback, the return true(and appears "return outside method")...):

MediaSession audioSession = new MediaSession(getApplicationContext(), "TAG"); audioSession.setCallback(new MediaSession.Callback){

    //@Override
    public static boolean onMediaButtonEvent(final Intent mediaButtonIntent) {
        String intentAction = mediaButtonIntent.getAction();
        if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
            KeyEvent event = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

            if (event != null) {

                stopTimeOfGame_millis = event.getDownTime();
                double usersReactionTime = (event.getDownTime() - startTimeOfGame_millis) / 1000.0;
                UtilsRG.info("event.getDownTime(): " + usersReactionTime);


                double getEventTime = (event.getEventTime() - startTimeOfGame_millis) / 1000.0;
                UtilsRG.info("event.getEventTime(): " + getEventTime);

                int action = event.getAction();
                if (action == KeyEvent.ACTION_DOWN) {
                    long action_down = android.os.SystemClock.uptimeMillis();
                    double actionDown = (action_down - startTimeOfGame_millis) / 1000.0;
                    UtilsRG.info("ACTION_DOWN: " + actionDown);
                }

                if (action == KeyEvent.ACTION_UP) {
                    long action_up = android.os.SystemClock.uptimeMillis();
                    double actionUp = (action_up - startTimeOfGame_millis) / 1000.0;
                    UtilsRG.info("ACTION_UP: " + actionUp);
                }
            }
        }
        return true;
    }


};

In this, I also had o add:

  PlaybackState state = new PlaybackState.Builder()
        .setActions(PlaybackState.ACTION_PLAY_PAUSE)
        .setState(PlaybackState.STATE_PLAYING, 0, 0, 0)
        .build();
audioSession.setPlaybackState(state);

audioSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);

audioSession.setActive(true);

To be more specific: enter image description here

I am getting crazy with this. Please help. haha. Thank you all in advance!

BlueMath
  • 11
  • 4
  • 1
    What have you tried so far? Are you only trying to listen for button presses when your activity is in the foreground or when your app is in the background as well? – ianhanniballake Feb 23 '17 at 03:17
  • Check : http://stackoverflow.com/questions/9056814/how-do-i-intercept-button-presses-on-the-headset-in-android – Komal12 Feb 23 '17 at 03:22
  • Thanks for replying. I've already tried with the codes shown there. The thing is that they do not work, either because I am still so newcomer and I don't know how to handle some problems that appear when I copy that codes or due to problems with the versions of Android. So basically what I think that I have to do is, to declare a new class that extends from Broadcastreceiver, then set its priority to the maximum in the manifest, and then call it from the mainActivity.. isn't it? How do I call it from the mainActivity? (yes excuse my ignorance) and what are the MediaSession, AudioManager..? – BlueMath Feb 23 '17 at 12:19
  • The idea is to listen the presses when the App is working in the foreground. But yes I would also prefer if it can be also carried out when it is in the background. – BlueMath Feb 23 '17 at 12:23

2 Answers2

0

Try

the ACTION_MEDIA_BUTTON intent.

or simply override Activity onKeyDown method:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_HEADSETHOOK){
        //handle click
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Doc
  • 10,831
  • 3
  • 39
  • 63
  • Thanks a lot. I am still so new here. So where am I supposed to put that code? inside of the mainActivity, or in the main class, or do I create a new class?. What should I write in the Manifest to give to it priority over the music playlist of android (and other actions that android automatically carries out when these buttons are pressed). How should I call that method from the mainActivity?. Excuse my ignorance, and thank you so much!!!! – BlueMath Feb 23 '17 at 12:10
  • whatever Activity handles your action event will use this method. – Doc Feb 23 '17 at 12:48
0

You should use a MediaSession (MediaSessionCompat to support API levels < 21). The onKeyDown method is called only if your activity is shown and the device is unlocked.

In short, you need to create a new MediaSession

mediaSession = new MediaSession(getApplicationContext(), SESSION_TAG);

set a callback on it

mediaSession.setCallback(new Callback() {
    // override just the methods you need
});

Set flags on the session:

mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);

Set the interceptable events and set the playback state. Set all the states you need to intercept, only for these ones you will receive events on your callback:

PlaybackState state = new PlaybackState.Builder()
    .setActions(PlaybackState.ACTION_PLAY|...)
    .setState(PlaybackState.STATE_STOPPED, PlaybackState.PLAYBACK_POSITION_UNKNOWN, SystemClock.elapsedRealtime())
.build();
mediaSession.setPlaybackState(state);

Activate the session:

mediaSession.setActive(true);
Massimo
  • 3,436
  • 4
  • 40
  • 68
  • Thanks a lot for replying! This is what I get now: http://i63.tinypic.com/scf4va.png I do not understand why the callback, the "set..!, and the session tag (which I do not know what is nor what it is for) appear in read. – BlueMath Feb 23 '17 at 13:56
  • Very strange. What is your minimum SDK level? – Massimo Feb 23 '17 at 14:35
  • It is set in 21 minSdkVersion 21 targetSdkVersion 25 versionCode 1 – BlueMath Feb 23 '17 at 14:42
  • I just performed one, but the problem persists... :( I really wanna cry haha – BlueMath Feb 23 '17 at 14:47
  • `SESSION_TAG` is a `String`, pass any value rather than `SESSION_TAG` – Massimo Feb 23 '17 at 14:49
  • what do you mean? which values? – BlueMath Feb 23 '17 at 14:59
  • the one passed in `new MediaSession(getApplicationContext(), SESSION_TAG)` – Massimo Feb 23 '17 at 15:00
  • MediaSession mediaSession = new MediaSession(getApplicationContext(), "SESSION_TAG"); do you mean doing this? excuse my ignorance – BlueMath Feb 23 '17 at 15:04
  • Yes, or pass any other value, but pass a valid value. From the image you posted SESSION_TAG does not exist (in my example it is meant to be a constant, but you have to define it). – Massimo Feb 23 '17 at 15:06
  • I keep having the same errors.. some of them I don't even understand where they come from, for instance: http://i65.tinypic.com/1ioewx.png thanks a lot for your help – BlueMath Feb 23 '17 at 15:13
  • Did you import `Callback`? If not import it or write `new MediaSession.Callback` rather than `new Callback` – Massimo Feb 23 '17 at 15:18
  • http://i65.tinypic.com/2dbv7zd.png it worked for that mistake in particular. But I keep having errors that are inexplicable. – BlueMath Feb 23 '17 at 15:29
  • ...you are calling `setCallback` on the class... call it on the object – Massimo Feb 23 '17 at 15:30
  • http://i68.tinypic.com/2u5gw9c.png true!. still having some problems thank you so much – BlueMath Feb 23 '17 at 15:42
  • I think you should really learn something about programming and java before starting to program for Android. *Programming* is not *asking continuously on StackOverflow*, there are *problems* which cannot be asked, because they are just the basics. I'm sorry my friend, but, for your own good, study and learn before and then start. You are starting with a too much complex problem for your skills. – Massimo Feb 23 '17 at 15:49
  • I know. But I need the app to do that... I know that a nonstatic method cannot be referenced from a static context, but the thing is that I need the method or class that performs the action of listening to the media buttons to be static(at least this is what I read). I have taken out the setcallback from that method,and still have the same error (as it all is within the main class). (the method also throws the same error)That's the only error left, and I don't know how to solve it, I swear that this is the last question haha. Thanks so much for your help. http://i68.tinypic.com/16iz5tk.png – BlueMath Feb 24 '17 at 18:13
  • (Taking out everything from the main class and puting it within anotherone does not work, doing so generates some errors in all the "set.." ) pls help! it looks like that way if I do so: http://i67.tinypic.com/2jb8ylv.png – BlueMath Feb 24 '17 at 18:19
  • You don't need any help. First of all you have to read about static methods and overriding. It is *impossible* to help you if you don't have any knowledge about these fundamental arguments... please use the attached code and look to the IDE warnings, they are sufficient to understand why your code is not working. – Massimo Feb 27 '17 at 10:12