2010-08-11 46 views
16

我基本上試圖實現的是自定義全局熱鍵,換言之,當我按下某些按鈕時,無論當前哪個程序在最前面,都會發生這種情況。
我假設需要一項服務。onKeyDown在服務中? (全球熱鍵)

我有一個快速和骯髒的測試,只是告訴我什麼被按下,如果它是活動窗口將工作。

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

但很明顯,如果我改變窗口或進入文本框它不起作用。如果我將它直接粘貼到一個服務(或一個imputmethodservice)中並啓動所述服務,則不會發生任何事情。 (需要一些權限?) 任何建議,我哪裏出錯了?或者更好地捕獲哪個按鈕被按下?

謝謝!

+0

hiii 如果你有這個解決方法,然後plz讓我knw。 – 2012-02-13 08:08:56

+1

@Vincent Romain Guy在Android團隊工作,他說這是[不可能](http://stackoverflow.com/a/3455094/942821)。和Fizz,你能接受Romain的回答嗎? – 2012-07-09 14:51:56

+0

可能的重複[是否有可能創建一個監聽硬件按鍵的Android服務?](http://stackoverflow.com/questions/2986337/is-it-possible-to-create-an-android-service-即聽 - 硬件密鑰壓力) – isalgueiro 2015-02-20 12:20:37

回答

17

你不能做到這一點:)

+1

即使在一個可訪問性應用程序?沒有辦法對服務中的按鈕或軟鍵進行響應? – amfcosta 2013-02-21 11:44:30

+0

@羅曼蓋伊 - 先生,如果在家中按下我想設置屏幕呢?三星note II將如何做? – 2014-03-12 08:27:01

+2

@Romain - 精心製作 - 謝謝 – 2014-07-31 14:54:59

0

這需要棒棒堂(V5.0/API 21)或更高

我的目標是調整從服務系統卷,所以這隻會偵聽搖桿。任何行動都可以在新聞界採取。

它將覆蓋音量鍵操作,因此可能不希望全局使用它。

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