2010-08-11 8 views
16

Quello che sto cercando di ottenere sono tasti di scelta rapida globali personalizzati o, in altre parole, "le cose accadranno quando premo determinati pulsanti indipendentemente dal programma attualmente in cima".
Suppongo che sia necessario un servizio.onKeyDown in un servizio? (Tasti di scelta rapida globali)

Ho un test rapido e sporco che mi dice solo cosa è stato premuto che funzionerà se è la finestra attiva.

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

Ma ovviamente se cambio finestra o vado in una casella di testo non funziona. Se lo inserisco direttamente in un servizio (o un imputmethodservice) e avvio il servizio, non succede nulla. (Alcune autorizzazioni richieste forse?) Qualche suggerimento dove sto andando male? O un modo migliore di catturare quale pulsante è premuto?

Grazie!

+0

hiii se si tratta di una soluzione per questo, allora fammi fare knw. –

+1

@Vincent Romain Guy lavora nel team Android, ha detto che è [impossibile] (http://stackoverflow.com/a/3455094/942821). E Fizz, potresti accettare la risposta di Romain? –

+0

possibile duplicato di [È possibile creare un servizio Android che è in ascolto per la pressione dei tasti hardware?] (Http://stackoverflow.com/questions/2986337/is-it-possibile-per-creare-an-android-service- that-listens-for-hardware-key-presse) – isalgueiro

risposta

17

Non si può fare questo :)

+1

Anche in un'applicazione di accessibilità? Non c'è modo di reagire ai pulsanti o ai softkey in un servizio? – amfcosta

+0

@Romain Guy - Signore, e se premendo a casa mi piacerebbe impostare lo schermo? Come lo farebbe Samsung Note II? –

+2

@Romain - Elaborazione per favore - grazie –

0

Questo richiede Lollipop (v5.0/API 21) o superiore

Il mio obiettivo era quello di regolare il volume del sistema da un servizio, quindi questo sarà solo ascolto per il rocker . Tuttavia, qualsiasi azione può essere presa sulla stampa.

Sostituisce l'azione del tasto del volume, pertanto potrebbe non essere opportuno utilizzarlo a livello globale.

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