studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android listener keyevent

programacion - ¿Es posible crear un servicio de Android que escuche las pulsaciones de teclas de hardware?



manual de programacion android pdf (3)

Me gustaría ejecutar un servicio de fondo de Android que actuará como un keylistener desde la pantalla de inicio o cuando el teléfono está dormido. es posible?

A partir de ejemplos semi relacionados en línea, armé el siguiente servicio, pero obtengo el error, "onKeyDown no está definido para el tipo de servicio". ¿Esto significa que no se puede hacer sin volver a escribir Launcher, o hay algo obvio que me estoy perdiendo?

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

Me doy cuenta de que Android está predeterminado en la barra de búsqueda cuando escribes desde la pantalla de inicio, pero esto es solo para un uso muy particular. Realmente no espero que nadie más que yo quiera esto. Creo que sería bueno, por ejemplo, usar el botón de la cámara para reactivar el teléfono.


Esto requiere Lollipop (v5.0 / API 21) o superior, y solo puede detectar claves de volumen

Anulará la acción de la tecla de volumen, por lo que su uso global puede no ser deseable.

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


Hasta donde yo sé, KeyEvents solo puede ser manejado por Actividades, ya que son la interfaz para el usuario que presiona las teclas. Los servicios se ejecutan en segundo plano y no tienen la intención de reaccionar ante la entrada del usuario. Esa es también la razón de la advertencia del compilador "onKeyDown no está definido para el tipo de servicio". El servicio o cualquiera de sus Superclases no implementa la interfaz KeyEvent.Callback. Como solución, puede registrar una actividad en su AndroidManifest.xml para reaccionar ante ciertas notificaciones del sistema, como android.intent.action.SCREEN_ON . Cuando se presiona el botón de encendido para encender la pantalla, se puede iniciar su actividad, inicializando un servicio de algún tipo y volviendo al fondo. Si eso es lo que intentas hacer. Ver Intent docs para posibles acciones.

Espero que haya ayudado ...


Si bien no es posible escuchar las pulsaciones de teclas de hardware directamente en un servicio, a veces puede escuchar los efectos de esas pulsaciones de teclas. Por ejemplo, esta respuesta describe cómo inferir pulsaciones de teclas de volumen a partir de cambios en el volumen de medios.