Czy możliwe jest stworzenie usługi Android, która nasłuchuje klawiszy sprzętowych?

Chciałbym uruchomić usługę w tle Androida, która będzie działać jako keylistener z ekranu głównego lub gdy telefon jest uśpiony. Czy to możliwe?

Z częściowo powiązanych przykładów online, ułożyłem następującą usługę, ale dostaję błąd, "onKeyDown jest niezdefiniowany dla usługi typu". Czy to oznacza, że nie można tego zrobić bez przepisania Launchera, czy jest coś oczywistego, czego mi brakuje?

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

Zdaję sobie sprawę, że Android domyślnie pasek wyszukiwania po wpisaniu z ekran główny, ale to naprawdę jest tylko do bardzo konkretnego zastosowania. Nie oczekuję, że ktoś inny będzie tego chciał. Po prostu myślę, że byłoby miło, na przykład, użyć przycisku aparatu, aby obudzić telefon.

Author: Brian, 2010-06-07

3 answers

O ile wiem KeyEvents mogą być obsługiwane tylko przez działania, ponieważ są one interfejsem użytkownika naciskającego klawisze. Usługi działają w tle i nie są przeznaczone do reagowania na dane użytkownika. Jest to również powód ostrzeżenia kompilatora "onKeyDown jest niezdefiniowany dla usługi typu". Usługa lub żadna z jej Superklas nie implementuje KeyEvent.Interfejs oddzwaniania. Jako obejście można zarejestrować aktywność w AndroidManifest.xml, aby reagować na określone powiadomienia systemowe, takie jak android.intent.action.SCREEN_ON. Po naciśnięciu przycisku zasilania, aby włączyć ekran, Twoja aktywność może zostać rozpoczęta, inicjując jakąś usługę i wrócić do tła. Jeśli to właśnie zamierzasz zrobić. Zobacz Intent docs dla możliwych działań.

Mam nadzieję, że to pomogło...
 16
Author: MarioB.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-16 13:10:03

Wymaga Lollipop (v5.0/API 21) lub wyższej i może wykrywać tylko klucze głośności

Nadpisze akcję klawisza volume, więc używanie jej globalnie może nie być pożądane.

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();
        }
    }
}
 1
Author: Gibolt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-10 19:45:03

Podczas gdy nie jest możliwe słuchanie sprzętowych naciśnięć klawiszy bezpośrednio w serwisie, czasami można słuchać efektów tych naciśnięć klawiszy. Na przykład, Ta odpowiedź opisuje, jak wywnioskować naciśnięcia klawiszy głośności na podstawie zmian głośności mediów.

 0
Author: Tad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:24