2010-06-06 3 views
26

Я хотел бы запустить фоновый сервис Android, который будет выступать в роли клавишника с главного экрана или когда телефон спит. Это возможно?Возможно ли создать Android-сервис, который прослушивает аппаратные нажатия клавиш?

Из полу связанных примеров онлайн я собрал следующую службу, но получаю сообщение об ошибке: «onKeyDown не определено для типа« Сервис ». Означает ли это, что это невозможно сделать без переписывания Launcher, или есть что-то очевидное, что я не хватает?

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

Я понимаю, что Android по умолчанию в строке поиска при вводе на главном экране, но это действительно только для очень конкретного использования. Я не ожидаю, что кто-нибудь, кроме меня, захочет этого. Я просто думаю, что было бы неплохо, например, использовать кнопку камеры, чтобы разбудить телефон.

+2

Hiii если вы нашли обходной путь для этого, то дайте мне know.thnx –

ответ

16

Насколько я знаю, KeyEvents могут обрабатываться только действиями, поскольку они являются интерфейсом для пользователя, нажимающего клавиши. Службы работают в фоновом режиме и не предназначены для реагирования на ввод пользователя. Это также является причиной предупреждения вашего компилятора «onKeyDown не определено для типа Service». Сервис или любой из его Суперклассов не реализуют интерфейс KeyEvent.Callback. В качестве обходного пути вы можете зарегистрировать Activity в своем AndroidManifest.xml, чтобы реагировать на определенные системные уведомления, такие как android.intent.action.SCREEN_ON. Когда кнопка питания нажата, чтобы включить экран, можно начать свою деятельность, инициализировав какую-либо услугу и вернитесь на задний план. Если это то, что вы намереваетесь сделать. См. Intent docs для возможных действий.

Надежда, что помогло ...

+1

Извините, если я неправильно понял. Ромен Гай работает в команде Android, он [подтвердил] (http://stackoverflow.com/a/3455094/942821), что. – 2012-07-09 14:50:00

0

Хотя это не возможно слушать аппаратных нажатий клавиш непосредственно в службе, иногда вы можете слушать эффекты этих нажатий клавиш. Например, this answer описывает, как вывести нажатия клавиш громкости из-за изменений в громкости.

0

Это требует Lollipop (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(); 
     } 
    } 
} 
Смежные вопросы