1

I'm trying to create an application that responds when the phone ringer volume is changed via the Volume Key. I've created a Service that registers a BroadcastReceiver, but the onReceive is not getting called.

I've seen examples in this forum of using audioManager.registerMediaButtonEventReceiver and also using context.registerReceiver. My class can try either of them depending on the state of useAudioManager. Either way, the class is being registered, but onReceive never gets called.

    public class VolumeKeyReceiver extends BroadcastReceiver
    {
      private static final boolean useAudioManager = true;

      @Override
      public void onReceive( Context context, Intent intent )
      {
        Log.d( "Monitor", "Volume key" );
      }

      public void register( Context context )
      {
        if ( useAudioManager )
        {
          AudioManager audioManager = (AudioManager)(context.getSystemService(Context.AUDIO_SERVICE));
          ComponentName componentName = new ComponentName( context, this.getClass() );
          audioManager.registerMediaButtonEventReceiver( componentName );
          Log.d( "Monitor", "registered via AudioManager" );
        }
        else
        {
          IntentFilter filter = new IntentFilter( Intent.ACTION_MEDIA_BUTTON );
          filter.setPriority( IntentFilter.SYSTEM_HIGH_PRIORITY );
          context.registerReceiver( this, filter );
          Log.d( "Monitor", "registered via Context" );
        }
      }
    }


    public class MonitorService extends Service
    {
      private VolumeKeyReceiver volumeKeyReceiver = null;
      @Override
      public void onCreate()
      {
        super.onCreate();
        volumeKeyReceiver = new VolumeKeyReceiver();
      }
      @Override
      public int onStartCommand(Intent intent, int flags, int startId)
      {
        volumeKeyReceiver.register( this );
        return START_STICKY;
      }
    }

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

I've omitted onDestroy() and unregister() for brevity.

Any idea why I'm not getting the notifications? Any permissions I'm missing? I'm testing it on a Galaxy S3.

ridoy
  • 6,274
  • 2
  • 29
  • 60
Jerry Agin
  • 629
  • 1
  • 5
  • 15

3 Answers3

1

You need to use action as below to listen to volume controls

<action android:name="android.media.VOLUME_CHANGED_ACTION" />
Don Cesar D'Bazar
  • 321
  • 1
  • 2
  • 9
  • this is useful for capturing the actual volume key presses. for instance, if the display is off, the volume won't change and the `VOLUME_CHANGED_ACTION` intent won't fire. – Michael Apr 21 '14 at 21:57
0

It turns out I'm using the wrong callback. Services apparently do not receive KeyEvent callbacks. Instead I should be using a ContentObserver.

The following link shows how: Listen to volume buttons in background service?

Community
  • 1
  • 1
Jerry Agin
  • 629
  • 1
  • 5
  • 15
  • only this doesn't work either. not for volume keys, and not when the screen is off (or the volume doesn't actually change). – Michael Apr 21 '14 at 21:56
0

I hit the same problem. And there are many wrong information for this case. All you need to receive bluetooth media button event are:

  1. Write intent-filter section in AndroidManifest.xml

    <receiver
        android:name=".RemoteControlReceiver"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </receiver>
    

No priority is required.

  1. Implement RemoteControlReceiver class
  2. call registerMediaButtonEventReceiver (at onCreate, for example)

        AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
        receiverName = new ComponentName(this, RemoteControlReceiver.class);
        am.registerMediaButtonEventReceiver(receiverName);
    
  3. Wait some time (about 2 min for my phone) after install apk.

That's all. For developing phase, 4 is the most important point but nobody mentioned. You need to wait sometime before registered receiver to Android system. It takes longer than I (and most of the developer, I guess) expect.

I add some note:

  1. You don't need to add to AndroidManifest.xml for receiving media button event.
  2. You don't need to call requestAudioFocus to receive this event.
  3. You don't need to call register intent-filter programatically.
  4. You don't need to set priority

Wait some minutes after adb install. This is the most important point.