why does the lockscreen button get pressed twice on kitkat

77 views Asked by At

The mediasession works pretty good for androids greater than or equal to lollipop but for some reason, implementing the lockscreen buttons using the mediasession seems to cause problems, I have a handle intent method in my service:

private void handleIntentActions(Intent actionIntent) {
        if(actionIntent == null || actionIntent.getAction() == null)return;

        String actionString = actionIntent.getAction();
        if( actionString.equalsIgnoreCase( ACTION_PPLAY ) || actionString.equalsIgnoreCase(ACTION_PLAY)){
            mMediaSessionTransportControls.play();
        }else if( actionString.equalsIgnoreCase(ACTION_PAUSE) ){
            mMediaSessionTransportControls.pause();
        }else if( actionString.equalsIgnoreCase( ACTION_PREVIOUS ) ){
            mMediaSessionTransportControls.skipToPrevious();
        }else if( actionString.equalsIgnoreCase( ACTION_NEXT ) ){
            mMediaSessionTransportControls.skipToNext();
        }else if( actionString.equalsIgnoreCase( ACTION_DISMISS ) ){
            mMediaSessionTransportControls.stop();
        }else if( actionString.equalsIgnoreCase( ACTION_START_FOREGROUND ) ){
            createNotificationChannel();
            requestAudioFocus();
            Log.e("NotifBuildTest", "NotifBUilderBefore: "+notificationBuilder);
            Notification notification = notificationBuilder.build();
            Log.e("NotifBuildTest", "NotifBUilderAfter: "+notificationBuilder);
            notification.flags = NotificationCompat.FLAG_ONGOING_EVENT|NotificationCompat.FLAG_FOREGROUND_SERVICE
                                | NotificationCompat.FLAG_NO_CLEAR | NotificationCompat.FLAG_HIGH_PRIORITY;
            startForeground(APP_NOTIFICATION_ID, notification);
        }  

the onStartCommand method looks like this:

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(mService, "foreground onStartCommand executed", Toast.LENGTH_SHORT).show();
        handleIntentActions(intent);
        updateMetaData("Unknown", "Unknown");
        super.onStartCommand(intent, flags, startId);
        return START_NOT_STICKY;
    }  

The updateMetaData looks like this:

private void updateMetaData(Bitmap albumArt,String songTitle, String artistName){
        mMediaSession.setMetadata( new MediaMetadataCompat.Builder()
                .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt )
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artistName )
                .putString(MediaMetadataCompat.METADATA_KEY_TITLE, songTitle )
                .build() );


PlaybackStateCompat mnew =  PlaybackStateCompat.Builder()
            .setActions(
                    PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
                    PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
                    PlaybackStateCompat.ACTION_PLAY |
                    PlaybackStateCompat.ACTION_PAUSE |
                    PlaybackStateCompat.ACTION_STOP )
            .setState(
                      ( getCurrentPlaybackStateCompat(),
                     0,
                     1.0f )
            .build();        
}  

The initMediaSession is like this:

public void initMediaSession() throws RemoteException {
        requestAudioFocus();

        //ComponentName mRemoteControlResponder = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName());
        //final Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
        //mediaButtonIntent.setComponent(mRemoteControlResponder);

        if(mMediaSessionManager != null)return;

        mMediaSession = new MediaSessionCompat(getApplicationContext(), mMediaSessionTag);
        mMediaSessionManager = MediaSessionManager.getSessionManager(mService);
        mMediaSessionTransportControls = mMediaSession.getController().getTransportControls();
        mMediaSession.setActive(true);
        //following flags are now set by default;
        //mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS |
        //                       MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);

        updateMetaData("Unknown", "Unknown");

        //setCallbacks
        mMediaSession.setCallback(new MediaSessionCompat.Callback() {


            @Override
            public void onPlay() {
                //super.onPlay();
                mService.playEvent();
                Toast.makeText(mService.this, "transport play is clicked", Toast.LENGTH_SHORT).show();
                updateMetaDataWithCurrentStateDetails();
            }


            @Override
            public void onPause() {
                //super.onPause();
                mService.pauseEvent();
                Toast.makeText(mService.this, "transport pause is clicked", Toast.LENGTH_SHORT).show();
                updateMetaDataWithCurrentStateDetails();
            }

            @Override
            public void onSkipToNext() {
                super.onSkipToNext();
                mService.nextPreviousTrigger(true,true);
                updateMetaDataWithCurrentStateDetails();
            }


            @Override
            public void onSkipToPrevious() {
                super.onSkipToPrevious();
                mService.nextPreviousTrigger(false,true);
                updateMetaDataWithCurrentStateDetails();
            }

            @Override
            public void onStop() {
                super.onStop(); //stop the service                       //BOTH METHODS ARE DIFFERENT
                removeNotification(); //remove the notification UI
                stopSelf();
            }
        });
        mMediaSession.setActive(true);

    }  

When I click the play button in the notification, it works as expected, but when I click the lockscreen's playbutton once, it get's clicked twice,

The mediaButtonReceiver I have looks like this(very simple implementation for now):

import androidx.media.session.MediaButtonReceiver;

    public class medButtonReceiver extends MediaButtonReceiver {
        public static  int count = 0;
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent mainIntent = null;
            if(count++ % 2 ==0) {
                mainIntent = new Intent(context, mService.class);
                mainIntent.setAction(mService.ACTION_PLAY);
            }else{
                mainIntent = new Intent(context, mService.class);
                mainIntent.setAction(mService.ACTION_PAUSE);
            }
    
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(mainIntent);
            } else {
                context.startService(mainIntent);
            }
    
    
            Log.e( "xTvM::","medButtonReceiver invoked" );
    
        }
    }  

and the logcat run looks like this:

/com.app.www E/xTvM::: something to click
09-19 09:55:37.608 8422-8422/com.app.www E/PBS::: Current playback state compat: play
09-19 09:55:37.658 8422-8422/com.app.www E/PBS::: Current playback state compat: pause
09-19 09:55:37.668 8422-8422/com.app.www E/PBS::: Current playback state compat: pause
09-19 09:55:37.678 8422-8422/com.app.www E/xTvM::: something to click
09-19 09:55:37.708 8422-8422/com.app.www E/PBS::: Current playback state compat: pause
09-19 09:55:37.778 8422-8422/com.app.www E/PBS::: Current playback state compat: play
09-19 09:55:37.788 8422-8422/com.app.www E/PBS::: Current playback state compat: play
09-19 09:55:37.808 778-778/? E/KeyguardHostView: ensureTransportPresentOrRemoved = 2
09-19 09:55:37.829 778-778/? E/KeyguardHostView: ensureTransportPresentOrRemoved = 2
09-19 09:55:47.628 618-790/? E/lights: write_int failed to open -1
09-19 09:56:00.891 618-875/? E/Watchdog: !@Sync 70

which shows that it is actually running twice, but I don't know why. Anyone have any ideas why this is happening? Thanks in advance.

0

There are 0 answers