为什么在kitkat上两次按下了锁屏按钮

问题描述

mediasession对于大于或等于lollipop的Android来说效果很好,但是由于某些原因,使用mediasession实现锁屏按钮似乎会导致问题,我的服务中有一个handle intent方法

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

onStartCommand方法如下:

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

updateMetaData看起来像这样:

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(),1.0f )
            .build();        
}  

initMediaSession像这样:

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

    }  

当我单击通知中的play按钮时,它按预期方式工作,但是当我单击锁屏的播放按钮一次时,它被单击了两次,

我的mediaButtonReceiver看起来像这样(目前非常简单的实现):

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

logcat运行如下:

/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

这表明它实际上已经运行了两次,但我不知道为什么。任何人都知道为什么会这样吗?预先感谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)