onKeyDown в сервисе? (Глобальные горячие клавиши) - PullRequest
18 голосов
/ 11 августа 2010

То, чего я в основном пытаюсь добиться, - это настраиваемые глобальные горячие клавиши или, другими словами, «когда я нажимаю определенные кнопки, все происходит независимо от того, какая программа в данный момент находится на вершине».
Я предполагаю, что услуга нужна.

У меня есть быстрый и грязный тест, который просто сообщает мне, что было нажано, и это будет работать, если это активное окно.

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);
  }

Но, очевидно, если я изменю окно или захожу в тексткоробка это не работает.Если я вставляю его непосредственно в сервис (или в сервисный сервис) и запускаю указанный сервис, ничего не происходит.(Может быть, требуется какое-то разрешение?) Есть предложения, где я ошибаюсь?Или лучший способ захвата, какая кнопка нажата?

Спасибо!

Ответы [ 2 ]

17 голосов
/ 11 августа 2010

Вы не можете сделать это:)

2 голосов
/ 10 марта 2018

Для этого требуется Lollipop (v5.0 / API 21) или выше

Моя цель состояла в том, чтобы отрегулировать громкость системы из Сервиса, так что это будет слушать только рокер. Любые действия могут быть предприняты для прессы.

Он отменяет действие клавиши регулировки громкости, поэтому его использование в глобальном масштабе может быть нежелательным.

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();
        }
    }
}
...