Android BroadcastReceiver won't register

2019-02-26 11:22发布

问题:

I'm trying to add a simple broadcast receiver to my audio application, so that I can mute everything when the user clicks their ACTION_MEDIA_BUTTON on their headset. I've read that you can either register it in the manifest, or dynamically in the code. I have gone down the path of registering it in the code, as I need to call methods within my main activity class to react to the media button press. For some reason however, my BroadcastReceiver just will not register, and I can't find anything that explains why (grey hairs increasing).

The following is what I have in MainActivity.java:

public class MainActivity extends Activity {

  public IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);

  public BroadcastReceiver MediaButtonIntentReceiver =
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {

                    String intentAction = intent.getAction();
                    if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
                        KeyEvent event = (KeyEvent) intent
                                .getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                        int action = event.getAction();
                        if (action == KeyEvent.ACTION_DOWN) {

                            Log.e("INFO", "Media Button Pressed");
                            MuteAll();

                        }


                }
           }
  };

  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);       

      // Register media button event receiver
      intentFilter.addAction("android.intent.action.ACTION_MEDIA_BUTTON");
      intentFilter.setPriority(10000);
      this.registerReceiver(MediaButtonIntentReceiver, intentFilter);

      }

@Override
protected void onDestroy() {
    super.onDestroy();

    // Unregister media button event receiver
    unregisterReceiver(MediaButtonIntentReceiver);

    }
};

I am certain that the BroadcastReceiver doesn't register, as wrapping the register as below gives me a toast confirming it is null:

  if (registerReceiver(MediaButtonIntentReceiver, intentFilter) == null) 
  {
      Toast.makeText(this, "Could not register receiver", Toast.LENGTH_LONG).show();
  } else {
      Toast.makeText(this, "Receiver registered", Toast.LENGTH_LONG).show();
  }

EDIT: I've also tried the following based on suggestions so far:

Reading through - http://developer.android.com/training/managing-audio/volume-playback.html I tried registering my receiver within the manifest like so...

<receiver android:name="com.mydomain.myapp.MainActivity$MediaButtonIntentReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

And then added the following example code:
public AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
...
// Start listening for button presses
am.registerMediaButtonEventReceiver(RemoteControlReceiver);

Eclipse complained that mContext didn't resolve to anything, so I added the following:

private Context mContext;

Then it complained about the "mContext.getSystemService(Context.AUDIO_SERVICE)" portion, saying "Type mismatch: cannot convert from Object to AudioManager"

So I added a cast to AudioManager:

public AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

And then added the suggested receiver registration code:

am.registerMediaButtonEventReceiver(MediaButtonIntentReceiver);

To which it complained about "registerMediaButtonEventReceiver" saying "The method registerMediaButtonEventReceiver(ComponentName) in the type AudioManager is not applicable for the arguments (BroadcastReceiver)"

Clearly I'm doing something wrong here. I've entered their example code as shown, yet it doesn't even compile.

--- END EDIT -----------------------------

Hoping someone out there can please help me. Please let me know if I need to supply anything further.

回答1:

A Receiver for the ACTION_MEDIA_BUTTON action should be registered with AudioManager's registerMediaButtonEventReceiver() method, instead of the regular registerReceiver() method in the Activity. Unlike normal dynamic Receiver registration, however, this method takes the class as the parameter, instead of an instance of the class. The easiest way to this is to create a separate class file for it:

public class MediaButtonIntentReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        ...
    }
}

And we would need this Receiver listed in the manifest, as well:

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

Now, the example in the link we've referred to is wrong, as the registerMediaButtonEventReceiver() method is expecting a ComponentName object, not just the name of the Receiver class itself. We need to change the example as follows:

AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
am.registerMediaButtonEventReceiver(
    new ComponentName(this, MediaButtonIntentReceiver.class));

And, as we've established, you don't need the mContext field, as you are in anActivity Context, and can just use getSystemService() without qualification. You can also do away with the IntentFilter object, as the listing in the manifest takes care of that already.