2010-08-11 4 views
16

Lo que básicamente intento lograr son teclas de acceso rápido globales personalizadas o, en otras palabras, 'sucederán cosas cuando presiono ciertos botones, sin importar qué programa esté actualmente en la parte superior'.
Supongo que se necesita un servicio.onKeyDown en un servicio? (Global Hot Keys)

Tengo una prueba rápida y sucia que simplemente me dice qué se ha presionado que funcionará si es la ventana activa.

public boolean onKeyDown(int keyCode, KeyEvent event) { 
    char pop; 
    pop = (char)event.getUnicodeChar(); 
    Toast.makeText(this, Character.toString(pop) , Toast.LENGTH_SHORT).show(); 
    return super.onKeyDown(keyCode, event); 
    } 

Pero obviamente, si cambio de ventana o entro en un cuadro de texto, no funciona. Si lo incluyo directamente en un servicio (o un servicio de imputmethod) y lo ejecuto, no ocurre nada. (Algunos permisos necesarios tal vez?) ¿Alguna sugerencia de dónde me estoy equivocando? ¿O una mejor forma de capturar qué botón se presiona?

Gracias!

+0

hiii si tienes alguna solución para esto entonces por favor déjame saber. –

+1

@Vincent Romain Guy trabaja en el equipo de Android, dijo que esto es [imposible] (http://stackoverflow.com/a/3455094/942821). Y Fizz, ¿podrías aceptar la respuesta de Romain? –

+0

posible duplicado de [¿Es posible crear un servicio de Android que escuche las pulsaciones de teclas de hardware?] (Http://stackoverflow.com/questions/2986337/is-it-possible-to-create-an-android-service- that-listens-for-hardware-key-presse) – isalgueiro

Respuesta

17

No se puede hacer esto :)

+1

¿Incluso en una aplicación de accesibilidad? ¿No hay forma de reaccionar a las pulsaciones de teclas o botones en un servicio? – amfcosta

+0

@Romain Guy - Señor, ¿qué pasa si al presionar a casa me gustaría configurar la pantalla? ¿Cómo lo haría Samsung Note II? –

+2

@Romain - Elaborar por favor - gracias –

0

Esto requiere Lollipop (v5.0/API 21) o superior

Mi objetivo era ajustar el volumen del sistema de un servicio, por lo que esto sólo va a escuchar para el eje de balancín . Sin embargo, cualquier acción puede tomarse en la prensa.

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