2010-06-06 12 views
26

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?¿Es posible crear un servicio Android que escuche las pulsaciones de teclas de hardware?

De ejemplos semi relacionados en línea, reúno el siguiente servicio, pero aparece 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); 
    } 
} 

que se dan cuenta de valores por defecto de Android a la barra de búsqueda cuando se escribe en la pantalla principal, pero esto realmente es sólo 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.

+2

hiii si se ha encontrado una solución para esto, entonces déjame know.thnx –

Respuesta

16

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.

esperanza de que ayudó ...

+1

Lo siento si no he entendido bien. Romain Guy trabaja en el equipo de Android, él [confirmó] (http://stackoverflow.com/a/3455094/942821) que. –

0

Si bien no es posible escuchar al presionar una tecla de hardware directamente en un servicio, a veces se puede escuchar a los efectos de esas pulsaciones de teclas. Por ejemplo, this answer describe cómo inferir pulsaciones de teclas de volumen a partir de cambios en el volumen de medios.

0

Esto requiere Lollipop (v5.0/API 21) o superior, y sólo puede detectar teclas de volumen

se anulará la acción tecla de volumen, por lo que su uso a nivel mundial no puede 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(); 
     } 
    } 
} 
Cuestiones relacionadas