18

Android OS のバージョン 4.0.3 (ICS) 用の Android アプリケーションを作成しています。問題は、BroadcastReceiver の onReceive() メソッドで Log.d() から出力を取得していないことです。これは、アプリケーションがブロードキャストを適切に処理していないことを意味します。

ACTION_MEDIA_BUTTON がクリックされたときにコードを実行する方法について、無数の質問を読みました。私のコードが機能しなかったときに、コードが機能するかどうかを確認するために、コードをコピーして貼り付けたことさえあります。

私が処理したい ACTION_MEDIA_BUTTON は、ユーザーが通話のピックアップ/終了、音楽の再生/一時停止を可能にするイヤホンの単一のボタンです。このボタンをクリックすると、アプリケーションがこのボタンを処理する代わりに、Nexus S Android のストック ミュージック プレーヤーが曲の再生を開始します。

コードを別のクラスに配置していません。おそらくこれが機能していないのですか?

onCreate() メソッドで見つかったコードは次のとおりです (この特定のコードは、私が書いたコードが機能しなかった後に Web サイトからコピーしたものです)。

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>

これには権限を指定しなかったため、最初は権限の問題である可能性があると考えていましたが、エラー メッセージは表示されませんでした。

先に述べたように、私はこれの多くのバリエーションを試しました。1 つの例は、 CommonsWareの修正を伴うこのリンクのコードの使用でした。繰り返しますが、別のクラスにならないように変更しました。

よろしくお願いいたします。

4

3 に答える 3

14

Android 4.4.2 を搭載した Samsung Galaxy S5 でこれをテストしました。重要なことと、他の投稿で言及されていないことは次のとおりです。

  • アプリケーションタグ内のAndroidManifest.xmlにレシーバーを登録しますが、すべてのアクティビティタグの外部に登録します。
  • レシーバーBroadcastreceiverはパブリックで静的である必要があります
  • ボタンの押下をリッスンするために、 1 つのアクティビティで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>

参照用:

于 2015-04-08T14:15:03.507 に答える
4
mediaButtonReceiver = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName());

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

mAudioManager.registerMediaButtonEventReceiver(mediaButtonReceiver);

このコードは、ヘッドフォン ボタンをアプリにバインドし、次の呼び出しを行うまでアプリのみをバインドします。

mAudioManager.unregisterMediaButtonEventReceiver(mediaButtonReceiver);
于 2012-04-27T08:47:01.710 に答える
1

ここで説明されている MediaSession を使用して、Android > 5.0 (API レベル 21 LOLLIPOP) 用の Broacastreceiver の使用を避けることができます: https://stackoverflow.com/a/39413753/1386969

于 2016-09-12T06:15:38.107 に答える