Можно ли создать службу Android, которая будет прослушивать нажатия аппаратных клавиш? - PullRequest
27 голосов
/ 07 июня 2010

Я бы хотел запустить фоновый сервис Android, который будет работать как клавиатурный слот с главного экрана или когда телефон спит. Возможно ли это?

Из полусвязанных примеров в Интернете я собрал следующий сервис, но получил ошибку: «onKeyDown не определен для типа Сервис». Означает ли это, что это не может быть сделано без переписывания Launcher, или есть что-то очевидное, что мне не хватает?

public class ServiceName extends Service {

    @Override
    public void onCreate() {
        //Stuff
    }

    public IBinder onBind(Intent intent) {
        //Stuff
        return null;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(event.getAction() == KeyEvent.ACTION_DOWN) {
        switch(keyCode) {
        case KeyEvent.KEYCODE_A:
            //Stuff
            return true;
        case KeyEvent.KEYCODE_B:
            //Stuff
            return true;

            //etc.
        }
        }

        return super.onKeyDown(keyCode, event);
    }
}

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

Ответы [ 3 ]

16 голосов
/ 16 ноября 2010

Насколько я знаю, KeyEvents может обрабатываться только Операциями, поскольку они являются интерфейсом для пользователя, нажимающего клавиши.Службы работают в фоновом режиме и не предназначены для реагирования на ввод пользователя.Это также является причиной предупреждения вашего компилятора "onKeyDown не определен для типа Service".Служба или любой из ее суперклассов не реализуют интерфейс KeyEvent.Callback.В качестве обходного пути вы можете зарегистрировать Activity в вашем AndroidManifest.xml, чтобы реагировать на определенные системные уведомления, такие как android.intent.action.SCREEN_ON.Если нажать кнопку питания, чтобы включить экран, вы можете начать свою деятельность, инициализируя какую-либо службу и вернуться в фоновый режим.Если это то, что вы намерены сделать.См. Intent docs для возможных действий.

Надеюсь, что помогло ...

4 голосов
/ 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 = mContext.getSystemService(Context.AUDIO_SERVICE);

        int STREAM_TYPE = AudioManager.STREAM_MUSIC;
        int currentVolume = audio.getStreamVolume(STREAM_TYPE);
        int maxVolume = audio.getStreamMaxVolume(STREAM_TYPE);
        final int VOLUME_UP = 1;
        final int VOLUME_DOWN = -1;

        return new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) {
            @Override
            public void onAdjustVolume(int direction) {
                // Up = 1, Down = -1, Release = 0
                // Replace with your action, if you don't want to adjust system volume
                if (direction == VOLUME_UP) {
                    audio.adjustStreamVolume(STREAM_TYPE,
                            AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                else if (direction == VOLUME_DOWN) {
                    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();
        }
    }
}
0 голосов
/ 22 мая 2015

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

...