2010-06-06 8 views
26

Chciałbym uruchomić usługę Android w tle, która będzie działała jako keylistener z ekranu głównego lub gdy telefon będzie w stanie uśpienia. czy to możliwe?Czy jest możliwe utworzenie usługi Android, która nasłuchuje naciśnięć przycisków sprzętowych?

Z częściowo pokrewnych przykładów w Internecie, zestawię następujące usługi, ale otrzymuję błąd, "onKeyDown jest niezdefiniowany dla typu Service". Czy to oznacza, że ​​nie da się tego zrobić bez przepisywania Launchera, czy jest coś oczywistego, czego mi brakuje?

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

Zdaję sobie sprawę, Android domyślnie pasku wyszukiwania po wpisaniu na ekranie głównym, ale to naprawdę jest tylko dla bardzo konkretnego zastosowania. Naprawdę nie oczekuję, że ktoś oprócz mnie będzie tego chciał. Po prostu myślę, że byłoby miło, na przykład, użyć przycisku aparatu, aby obudzić telefon.

+2

hiii jeśli znaleźli obejście tego, pozwól mi know.thnx –

Odpowiedz

16

O ile mi wiadomo, KeyEvents mogą być obsługiwane tylko przez czynności, ponieważ są one interfejsem użytkownika naciskającego klawisze. Usługi działają w tle i nie mają na celu reagować na dane wprowadzone przez użytkownika. To jest również powód ostrzeżenia twojego kompilatora "onKeyDown jest niezdefiniowany dla typu Service". Usługa lub jej Superklasy nie implementują interfejsu KeyEvent.Callback. Aby obejść ten problem, można zarejestrować działanie w swojej AndroidManifest.xml, aby reagować na niektóre powiadomienia systemowe, takie jak android.intent.action.SCREEN_ON. Po naciśnięciu przycisku zasilania, aby włączyć ekran, możesz rozpocząć aktywność, zainicjować usługę i wrócić do tła. Jeśli to właśnie zamierzasz zrobić. Zobacz Intent docs dla możliwych działań.

Mam nadzieję, że pomogło ...

+1

Przepraszam, jeśli źle. Romain Guy pracuje w zespole Android, on [potwierdzone] (http://stackoverflow.com/a/3455094/942821), że. –

0

Chociaż nie jest to możliwe, aby słuchać sprzętowych naciśnięć klawiszy bezpośrednio w serwisie, można czasami posłuchać za skutki tych naciśnięć klawiszy. Na przykład: this answer opisuje, w jaki sposób wnioskować naciśnięcia przycisków głośności ze zmian głośności multimediów.

0

wymaga Lollipop (v5.0/API 21) lub wyższym, i może wykrywać tylko klawisze głośności

Będzie ona zastąpić głośności działania klucza, więc stosując go w skali globalnej nie może być pożądana.

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(); 
     } 
    } 
} 
Powiązane problemy