我基本上想要实现的是自定义全局热键,换句话说,“当我按下某些按钮时会发生某些事情,无论当前哪个程序位于顶部”。
我认为需要一项服务。
我有一个快速而肮脏的测试,它只是告诉我如果它是活动窗口会被按下的是什么。
public boolean onKeyDown(int keyCode, KeyEvent event) {
char pop;
pop = (char)event.getUnicodeChar();
Toast.makeText(this, Character.toString(pop) , Toast.LENGTH_SHORT).show();
return super.onKeyDown(keyCode, event);
}
但很明显,如果我更改窗口或进入文本框,它将无效。如果我将它直接粘贴到服务(或imputmethodservice)并启动所述服务没有任何反应。 (可能需要一些权限?) 我出错的任何建议?或者更好的方法来捕捉按下哪个按钮?
谢谢!
答案 0 :(得分:17)
你不能这样做:)。
答案 1 :(得分:2)
我的目标是从服务调整系统音量,这样只会听摇杆。不过可以采取任何行动。
它将覆盖音量键操作,因此可能不需要全局使用它。
public class VolumeKeyController {
private MediaSessionCompat mMediaSession;
private final Context mContext;
public VolumeKeyController(Context context) {
mContext = context;
}
private void createMediaSession() {
mMediaSession = new MediaSessionCompat(mContext, KeyUtil.log);
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mMediaSession.setPlaybackState(new Builder()
.setState(PlaybackStateCompat.STATE_PLAYING, 0, 0)
.build());
mMediaSession.setPlaybackToRemote(getVolumeProvider());
mMediaSession.setActive(true);
}
private VolumeProviderCompat getVolumeProvider() {
final AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
int STREAM_TYPE = AudioManager.STREAM_MUSIC;
int currentVolume = audio.getStreamVolume(STREAM_TYPE);
int maxVolume = audio.getStreamMaxVolume(STREAM_TYPE);
return new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) {
@Override
public void onAdjustVolume(int direction) {
// Volume Up = AudioManager.ADJUST_LOWER, Volume Down = AudioManager.ADJUST_LOWER, Release = AudioManager.ADJUST_SAME
// Replace with your action, if you don't want to adjust system volume
if (direction == AudioManager.ADJUST_RAISE) {
audio.adjustStreamVolume(STREAM_TYPE,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
}
else if (direction == AudioManager.ADJUST_LOWER) {
audio.adjustStreamVolume(STREAM_TYPE,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
}
setCurrentVolume(audio.getStreamVolume(STREAM_TYPE));
}
};
}
// Call when control needed, add a call to constructor if needed immediately
public void setActive(boolean active) {
if (mMediaSession != null) {
mMediaSession.setActive(active);
return;
}
createMediaSession();
}
// Call from Service's onDestroy method
public void destroy() {
if (mMediaSession != null) {
mMediaSession.release();
}
}
}