ACTION_MEDIA_BUTTON的广播接收器无法工作

18

我正在为Android 4.0.3 (ICS)版本编写应用程序。问题是,在BroadcastReceiver的onReceive()方法中,我没有从Log.d()获得输出,这意味着我的应用程序没有正确处理广播。

我已经阅读了很多关于如何在单击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>

一开始我以为这可能是一个权限问题,因为我没有为此指定任何权限,但是我没有收到任何错误消息。

像我之前说的,我已经尝试了很多变化。其中一个例子是使用这个链接中的代码broadcastreceiver onReceive problem ACTION_MEDIA_BUTTON Android 和CommonsWare的修正。然而,我对它进行了修改,所以它不是在一个单独的类中。

提前感谢您的帮助。


请查看这个这个。希望这能解决你的问题。 - silwar
我有和你几乎一样的代码,在Android 2.2 / 2.3上运行良好。但是像你一样,我无法使其在ICS上工作... - user1026605
一样的情况。在 Android 4.0 之前是可以工作的,但 API 发生了变化或其他什么原因导致无法工作了。 - joepetrakovich
1
我已经在同样的问题上开始了悬赏...https://dev59.com/T2Yr5IYBdhLWcg3w8-vA - Du3
3个回答

14

我在三星Galaxy S5上测试过这个问题,安卓版本是4.4.2。所以重要的是什么,而且其他帖子中没有提到的是

  • 将接收器在AndroidManifest.xml中的application标签内注册,但在每个activity标签之外。
  • 你的接收器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
    }
}

这里是清单片段。如果需要,可以为intent-filter添加优先级,但对我来说不需要:

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

参考文献:


我正在尝试在三星设备上实现同样的功能,当我的活动进入后台时,onReceive()总是被调用,但在Nexus上,onReceive()在后台永远不会被调用。你能解释一下为什么吗? - Ajit Kumar Dubey

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

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

mAudioManager.registerMediaButtonEventReceiver(mediaButtonReceiver);

这段代码将把你的耳机按钮绑定到你的应用程序上,只有在你调用以下代码之前才会解除绑定:

mAudioManager.unregisterMediaButtonEventReceiver(mediaButtonReceiver);

3
直到其他应用调用了registerMediaButtonEventReceiver(),我才会停止。 ;) - cprcrack
我在哪里可以注册广播。我只在清单文件中注册了接收器。 - Vineesh TP

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接