3

I try to get the time System.currentTimeMillis(), than the user presses the media button. But the callback is executed at the time when the media button goes up again action == KeyEvent.ACTION_UP.

I don't want to use a BroadcastReceiver for my solution.

This is my code:

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

        @Override
        public boolean onMediaButtonEvent(final Intent mediaButtonIntent) {
            String intentAction = mediaButtonIntent.getAction();

            if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction))
            {
                KeyEvent event = (KeyEvent)mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                if (event != null)
                {
                    int action = event.getAction();
                    if (action == KeyEvent.ACTION_DOWN) {
                        long stopTimeOfGame_millis = System.currentTimeMillis();
                        UtilsRG.info("time stopped: " +stopTimeOfGame_millis);

                    }
                    if (action == KeyEvent.ACTION_UP) {
                         long test = System.currentTimeMillis();
                         UtilsRG.info("time stopped up: " +test);

                    }
                }

            }
            return super.onMediaButtonEvent(mediaButtonIntent);
        }



    });

    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); 

The log output:

time stopped down: 1473420286380
time stopped up: 1473420286383

In my opinion the difference is too small between these values.

lidox
  • 1,901
  • 3
  • 21
  • 40
  • 1
    Did you try to log the time when the action is `KeyEvent.ACTION_UP`? – Balkrishna Rawool Sep 09 '16 at 11:19
  • time stopped down: 1473420286380 and time stopped up: 1473420286383 – lidox Sep 09 '16 at 11:26
  • 1
    If you do a quick tap on the button, the difference will be small. What is your question? – Balkrishna Rawool Sep 09 '16 at 12:51
  • The difference is 0.001 ms. This is never the correct value. I think the difference is caused by the if statements before the time is tracked. My question is: How to detect the press down event correctly. If I click on the media button and hold ca. 0.5 s --> the difference is again 0.001ms. – lidox Sep 09 '16 at 12:53
  • 1
    It is 3 milliseconds. Your program looks good as far as the action events are concerned. You should try a case when you keep your finer on the button for long time to see significant difference in the times logged. – Balkrishna Rawool Sep 09 '16 at 12:57
  • 1
    And check this question: http://stackoverflow.com/questions/19029669/media-button-button-event-action-down-and-action-up-received-at-the-same-time?rq=1 – Balkrishna Rawool Sep 09 '16 at 12:59
  • Thanks so much! I think I got the solution. Thanks for your time! I will post it in minutes. :) – lidox Sep 09 '16 at 13:41
  • Do you get events from phone's volume up/down buttons on Android 5/6? I can only get events from buttons on earbuds/bluetooth devices. – myforums Nov 29 '16 at 21:12
  • I do get the events from the media buttons of the headphones – lidox Nov 30 '16 at 08:12

1 Answers1

7

I fixed the issue by my self. The trick is to use event.getDownTime() Following example explains it:

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

    @Override
    public 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;
    }


    });

    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);

I got following log:

event.getDownTime(): 0.281

event.getEventTime(): 0.421

ACTION_DOWN: 0.47

ACTION_UP: 0.471

Thus now I got the moment when the user presses the key down.

Special Thanks goes to Balkrishna Rawool

lidox
  • 1,901
  • 3
  • 21
  • 40