rupinderjeet47 rupinderjeet47 - 2 months ago 21
Android Question

InputMethodService and Detect Volume KeyEvents from this service

I have one activity and one InputMethodService. The activity UI have two buttons that start and stop this Service. Then, I get out of my app while Service is still running.

I want this service to respond to Volume Buttons. I don't want to effect System/Other Processes associated with Volume Buttons. So, If i press Volume_Up key, System must be increasing volume as it does, and trigger my Service.

For now, I am just showing Toasts on these triggers. Have a look at what i have tried so far by extending InputMethodService:

@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent){
switch(keyCode){
case KeyEvent.KEYCODE_VOLUME_DOWN:
Toast.makeText(this, "Volume Down", Toast.LENGTH_SHORT).show(); break;
case KeyEvent.KEYCODE_VOLUME_UP:
Toast.makeText(this, "Volume Up", Toast.LENGTH_SHORT).show(); break;
default:
Toast.makeText(this, keyCode, Toast.LENGTH_SHORT).show();
}

return false;
}


But, this doesn't do anything besides changing System Volume. My Service is running for sure, i can see it in running services.

Answer

I had wrong impression about InputMethodService. It can't listen to Volume Buttons. The only way i was able to perform this was using a BroadcastReceiver. This receiver listens to an undocumented and risky broadcast of android.media.VOLUME_CHANGED_ACTION. This broadcast is fired when background music is playing, and you control it from a locked screen. So, in order to listen to Volume Buttons, you can register a receiver who listens to mentioned broadcast And start a service which uses MediaPlayer to play a sound with Zero volume. Whenever volume button is pressed, receiver will receive the broadcast.

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound);
mediaPlayer.setVolume(0, 0);
mediaPlayer.setLooping(true);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.start();

and register receiver like:

<receiver
    android:name=".MediaButtonReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="android.media.VOLUME_CHANGED_ACTION" />
    </intent-filter>
</receiver>

Beware: this method is very experimental.

Comments