Est-il possible de créer un service Android qui écoute les presses à clé matérielle?

StackOverflow https://stackoverflow.com/questions/2986337

  •  24-10-2019
  •  | 
  •  

Question

Je voudrais lancer un service d'arrière-plan Android qui agira comme keyListener de l'écran d'accueil ou lorsque le téléphone est en veille. Est-ce possible?

A partir d'exemples semi-apparentés en ligne, je mets ensemble le service suivant, mais je reçois l'erreur, « onKeyDown n'est pas défini pour le type de service ». Est-ce que cela veut dire qu'il ne peut pas se faire sans réécriture de lancement, ou est-il quelque chose d'évident, je suis absent?

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

Je me rends compte par défaut Android à la barre de recherche lorsque vous tapez à partir de l'écran d'accueil, mais ce qui est vraiment juste pour une utilisation très particulière. Je ne pense pas vraiment personne, mais je veux que ce. Je pense que ce serait bien, par exemple, d'utiliser le bouton de la caméra pour réveiller le téléphone.

Était-ce utile?

La solution

As far as I know KeyEvents can only be handled by Activities as they are the interface to the user pressing the keys. Services run in the background and are not intended to react on user input. That's also the reason of your compiler warning "onKeyDown is undefined for the type Service". Service or any of it's Superclasses don't implement the KeyEvent.Callback interface. As a workaround you could register an Activity in your AndroidManifest.xml to react on certain system notifications such as android.intent.action.SCREEN_ON. When the power button is pressed to turn on the screen your activity could be started, initializing a service of some kind and go back to the background. If that's what you intend to do. See Intent docs for possible Actions.

Hope that helped...

Autres conseils

This requires Lollipop (v5.0/API 21) or higher, and can only detect volume keys

It will override volume key action, so using it globally may not be desired.

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

While it is not possible to listen for hardware key presses directly in a service, you can sometimes listen for the effects of those key presses. For example, this answer describes how to infer volume key presses from changes in media volume.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top