BroadcastReceiver для ACTION_MEDIA_BUTTON не работает

Я пишу приложение для Android для версии 4.0.3 (ICS) ОС Android. Проблема в том, что я не получаю вывод из моего Log.d() в методе onReceive() BroadcastReceiver, что означает, что мое приложение неправильно обрабатывает трансляцию.

Я прочитал бесчисленные вопросы о том, как запустить код при нажатии ACTION_MEDIA_BUTTON. Я даже скопировал + вставил код, когда мой не работал, просто чтобы посмотреть, будет ли он работать.

ACTION_MEDIA_BUTTON, которую я хочу обработать, - это единственная кнопка на наушниках, которая позволяет пользователю принимать / завершать вызовы, воспроизводить / приостанавливать музыку. Вместо того, чтобы мое приложение обрабатывало эту кнопку, когда я нажимаю на нее, стандартный музыкальный проигрыватель на моем Nexus S Android начинает воспроизводить песню.

Я не поместил свой код в другой класс, может, поэтому он не работает?

Вот код, найденный в методе onCreate() (этот код, который я скопировал с веб-сайта после того, как код, который я написал, не работал):

IntentFilter mediaButtonFilter = new IntentFilter(
            Intent.ACTION_MEDIA_BUTTON);
    mediaButtonFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    BroadcastReceiver brMediaButton = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            Log.d("Event", "Media button!");
            this.abortBroadcast();

            KeyEvent key = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
            if(key.getAction() == KeyEvent.ACTION_UP) {
                int keycode = key.getKeyCode();
                if(keycode == KeyEvent.KEYCODE_MEDIA_NEXT) {
                    Log.d("TestApp", "Next Pressed");
                } else if(keycode == KeyEvent.KEYCODE_MEDIA_PREVIOUS) {
                    Log.d("TestApp", "Previous pressed");
                } else if(keycode == KeyEvent.KEYCODE_HEADSETHOOK) {
                    Log.d("TestApp", "Head Set Hook pressed");
                }
            }

        }
    };
    registerReceiver(brMediaButton, mediaButtonFilter);

Все, что мне действительно нужно для проверки, это KEYCODE_HEADSETHOOK, но не мешало бы иметь другой код для тестирования, я исправлю его, как только смогу заставить все работать правильно.

В моем манифесте:

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

Первоначально я думал, что это может быть проблема с разрешениями, так как я не указал никаких разрешений для этого, однако я не получил никакого сообщения об ошибке.

Как я уже говорил ранее, я попробовал много вариантов этого. Одним из примеров было использование кода по этой ссылке широковещательный приемник при получении проблемы ACTION_MEDIA_BUTTON Android с исправлениями CommonsWare. Опять же, однако, я изменил его, чтобы он не был в отдельном классе.

Спасибо заранее за вашу помощь.

3 ответа

Решение

Я проверял это на Samsung Galaxy S5 с Android 4.4.2. Итак, что важно, а что не упоминается в других постах:

  • Зарегистрируйте получателя в AndroidManifest.xml внутри тега приложения, но вне каждого тега активности.
  • Ваш приемник Broadcastreceiver должен быть публичным и статичным
  • Для одного действия необходимо зарегистрировать MediaButtonEventReceiver для прослушивания нажатий кнопок.

Хорошо, и вот пример кода:

mAudioManager =  (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mReceiverComponent = new ComponentName(this,YourBroadcastReceiver.class);
...
mAudioManager.registerMediaButtonEventReceiver(mReceiverComponent);
...
// somewhere else
mAudioManager.unregisterMediaButtonEventReceiver(mReceiverComponent);

Вот получатель:

public static class YourBroadcastReceiver extends BroadcastReceiver{

    // Constructor is mandatory
    public MediaBroadcastReceiver ()
    {
        super ();
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        Log.i (TAG_MEDIA, intentAction.toString() + " happended");
        if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
            Log.i (TAG_MEDIA, "no media button information");
            return;
        }
        KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
        if (event == null) {
            Log.i (TAG_MEDIA, "no keypress");
            return;
        }
        // other stuff you want to do
    }
}

И тут манифест отрывок. При необходимости добавьте приоритет для фильтра намерений, но мне это не понадобилось:

<application>
    <receiver android:name="OuterClass$YourBroadcastReceiver">
        <intent-filter>
           <action android:name="android.intent.action.MEDIA_BUTTON" />
         </intent-filter>
    </receiver>
    <activity> ... </activity>
</application>

Для ссылок:

mediaButtonReceiver = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName());

mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

mAudioManager.registerMediaButtonEventReceiver(mediaButtonReceiver);

Этот код будет привязывать кнопку наушников к вашему приложению и вашему приложению только до тех пор, пока вы не позвоните:

mAudioManager.unregisterMediaButtonEventReceiver(mediaButtonReceiver);

Вы можете избежать использования Broacastreceiver для Android >5.0 (API уровня 21 LOLLIPOP), используя MediaSession, описанный здесь: /questions/31808555/kak-proslushat-sobyitie-actiondown-nazhatie-klavishi-v-android-onmediabuttonevent-chtobyi-izmerit-vremya/31808558#31808558

Другие вопросы по тегам