代码之家  ›  专栏  ›  技术社区  ›  Rektirino

应用程序在耳机上崩溃按钮单击

  •  2
  • Rektirino  · 技术社区  · 7 年前

    我已经建立了一个音频播放器,部署在android谷歌游戏商店。我正在使用crashlytics来监视崩溃和anr。最近我收到了很多媒体按钮接收器的崩溃。在许多设备中,耳机的咔哒声都能正常工作。但一些设备也带来了这个问题。

    事故报告-

    Fatal Exception: java.lang.RuntimeException: Unable to start receiver android.support.v4.media.session.MediaButtonReceiver: java.lang.IllegalStateException: Could not find any Service that handles android.intent.action.MEDIA_BUTTON or implements a media browser service.
           at android.app.ActivityThread.handleReceiver(ActivityThread.java:2866)
           at android.app.ActivityThread.access$1700(ActivityThread.java:182)
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1551)
           at android.os.Handler.dispatchMessage(Handler.java:111)
           at android.os.Looper.loop(Looper.java:194)
           at android.app.ActivityThread.main(ActivityThread.java:5706)
           at java.lang.reflect.Method.invoke(Method.java)
           at java.lang.reflect.Method.invoke(Method.java:372)
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1033)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
    

    媒体会话代码-

    private void initMediaSession() throws RemoteException {
            if (mediaSessionManager != null) return; //mediaSessionManager exists
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
            }
            // Create a new MediaSession
            mediaSession = new MediaSessionCompat(this, "AudioPlayer");
            //Get MediaSessions transport controls
            transportControls = mediaSession.getController().getTransportControls();
            //set MediaSession -> ready to receive media commands
            mediaSession.setActive(true);
            //indicate that the MediaSession handles transport control commands
            // through its MediaSessionCompat.Callback.
            mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS|MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
    
    
            //Set mediaSession's MetaData
            updateMetaData();
    
    
            mediaSession.setCallback(new MediaSessionCompat.Callback() {
                @Override
                public void onPlay() {
                    super.onPlay();
    
                    resumeMedia();
                }
    
                @Override
                public void onPause() {
                    super.onPause();
    
                    pauseMedia();
                }
    
                @Override
                public void onSkipToNext() {
                    super.onSkipToNext();
    
                }
    
                @Override
                public void onSkipToPrevious() {
                    super.onSkipToPrevious();
    
                }
    
                @Override
                public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
    
                    if (su.getHeadsetEnableSwitch()) {
    
                        String intentAction = mediaButtonIntent.getAction();
                        if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
                            KeyEvent event = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
    
                            if (event != null) {
    
    
                                int action = event.getAction();
                                Log.e("Headset key: ", String.valueOf(action));
                                if (action == KeyEvent.ACTION_DOWN) {
    
                                    Log.e("Headset: ", "Action down");
    
                                    headsetClickCount++;
    
                                    new Handler().postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
    
                                            if (headsetClickCount == 1) {
    
                                                if (isPng()) pauseMedia();
                                                else resumeMedia();
    
                                                headsetClickCount = 0;
    
                                            } else if (headsetClickCount == 2) {
    
                                                if (su.getDoubleClickAction() == 0) {
                                                } else if (su.getDoubleClickAction() == 1)
                                                    skipToPrevious();
                                                else if (su.getDoubleClickAction() == 2) skipToNext();
                                                headsetClickCount = 0;
                                            } else if (headsetClickCount == 3) {
    
                                                if (su.getTripleClickAction() == 0) {
                                                } else if (su.getTripleClickAction() == 1)
                                                    skipToPrevious();
                                                else if (su.getTripleClickAction() == 2) skipToNext();
                                                headsetClickCount = 0;
                                            }
                                        }
                                    }, 750);
                                }
    
                                if (action == KeyEvent.FLAG_LONG_PRESS) {
    
                                    if (su.getLongClickAction() == 0) {
                                    } else if (su.getLongClickAction() == 1) skipToPrevious();
                                    else if (su.getLongClickAction() == 2) skipToNext();
    
                                }
    
    
                                if (action == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
    
                                    Log.e("Headset: ", "headset sethook");
                                    if (isPng()) pauseMedia();
                                    else resumeMedia();
                                }
    
                                if (action == KeyEvent.KEYCODE_MEDIA_NEXT) {
    
                                    skipToNext();
                                }
    
                                if (action == KeyEvent.KEYCODE_MEDIA_PREVIOUS) {
    
                                    skipToPrevious();
                                }
    
                                if (action == KeyEvent.KEYCODE_MEDIA_PAUSE) {
    
                                    pauseMedia();
                                }
    
                                if (action == KeyEvent.KEYCODE_MEDIA_PLAY) {
    
                                    resumeMedia();
                                }
    
    
                            }
                        }
    
                        return true;
    
                    }
    
                return true;
                }
            });
    
    
    
        }
    

    有什么问题,怎么解决?

    我的想法-可能是因为用户在我的应用程序仍在播放时打开了其他具有此功能的音乐应用程序。

    1 回复  |  直到 7 年前
        1
  •  -1
  •   Tom11    6 年前

    你必须创建自己的媒体按钮接收器类,比如 MyMediaButtonReceiver.java ,延伸 MediaButtonReceiver ,它将是空的,除了 onReceive 必须重写的方法,调用 super.onReceive(...) 在捕获 IllegalStateException 以下内容:

    public class MyMediaButtonReceiver extends MediaButtonReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                super.onReceive(context, intent);
            } catch (IllegalStateException e) {
                Log.d(this.getClass().getName(), e.getMessage());
            }
        }
    }
    

    那么您必须在清单中声明该接收方类(或者替换以前的 媒体按钮接收器 类声明(如果有),例如:

    <receiver android:name=".MyMediaButtonReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </receiver>