在Android中如何拦截耳机按钮按下事件?

13

我研究了ACTION_MEDIA_BUTTON意图并试图使用它来拦截按钮按下事件,并使用toast在屏幕上呈现它们。我注册了接收器以拦截两个意图:

  1. ACTION_HEADSET_PLUG - 插入耳机

  2. ACTION_MEDIA_BUTTON - 接收按钮按下事件

这是在我的主要活动中完成的:

        IntentFilter mediaFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
        mediaFilter.setPriority(10000);
        registerReceiver(_receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
        registerReceiver(_receiver, mediaFilter);
这是接收器中处理按钮按下的部分:
    if (action.equals(Intent.ACTION_HEADSET_PLUG))
    {
        Toast.makeText(context, "earphones activity",Toast.LENGTH_SHORT).show();
        if (intent.getExtras().getInt("state")==1)//if plugged
            Toast.makeText(context, "earphones plugged",Toast.LENGTH_LONG).show();
        else Toast.makeText(context, "earphones un-plugged",Toast.LENGTH_LONG).show();
    }
    else 
    if (action.equals(Intent.ACTION_MEDIA_BUTTON))
    {
        Toast.makeText(context, "button pressed",Toast.LENGTH_LONG).show();
        key=intent.getExtras().getString("EXTRA_KEY_EVENT");
        Toast.makeText(context, key,Toast.LENGTH_LONG).show();
    }

现在处理耳机插入和拔出的部分运行良好,但截取按钮按下的部分没有起作用。

有没有什么原因导致处理 ACTION_MEDIA_BUTTON 的代码不起作用?

我是否需要特殊权限来截取这样的意图?

我正在使用三星Galaxy S2测试代码。

我查看了所有类似的帖子并尝试了一切。不幸的是,似乎没有任何作用。


你在测试哪个设备? - slayton
我不确定,但可能是TouchWiz没有正确实现ANDROID_MEDIA_BUTTON意图... - slayton
有没有一种验证它的方法,或者绕过它使其工作的方法?也许可以使用另一个意图? - Gabriel H
3个回答

3

最近我开发了一个响应媒体按钮的应用程序。我在三星Galaxy S II上进行了测试,它可以正常工作。

首先,在你的AndroidManifest.xml文件中,在<application>标签内添加以下内容:

<!-- Broadcast Receivers -->
<receiver android:name="net.work.box.controller.receivers.RemoteControlReceiver" >
    <intent-filter android:priority="1000000000000000" >
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

接下来,在不同的文件中创建一个BroadcastReceiver:

public class RemoteControlReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) {
            KeyEvent event = (KeyEvent) intent .getParcelableExtra(Intent.EXTRA_KEY_EVENT);

            if (event == null) {
                return;
            }

            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                context.sendBroadcast(new Intent(Intents.ACTION_PLAYER_PAUSE));
            }
        }
    }

}

这可能不是最好的解决方案(特别是上面硬编码的android:priority)。然而,我尝试了几种其他技术,但似乎都没有起作用。所以我只能采用这个...希望能有所帮助。


3
请查看以下链接。简短易懂。 http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html - Milton
PS:优先级必须为1000,如果您使用android:priority="1000000000000000",则应该会收到警告或错误提示。正确的做法是:<intent-filter android:priority="1000">。 - leoneboaventura

2
感谢您的贡献。
对于其他人的困惑,以下是最终结论:
经过许多泪水的努力,我最终意识到我可以拦截两种类型的广播:像 ACTION_HEADSET_PLUG 这样的广播需要在活动代码中注册。
ACTION_MEDIA_BUTTON 这样的广播需要在清单文件中注册。
在这个例子中,我们需要同时在代码和清单文件中设置它来拦截两个意图。

0
if (Intent.ACTION_MEDIA_BUTTON.equals(action)) {
    if (intent.hasExtra(Intent.EXTRA_KEY_EVENT)) {
        String key = intent.getStringExtra(Intent.EXTRA_KEY_EVENT);
        toast("Button "+key+" was pressed");
    } else
        toast("Some button was pressed");
}

这段代码会返回一个 Toast,内容为“按钮为空被按下”


如果您遇到问题,请发表评论而不是提供答案。 - Mercurial

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