Слушать кнопки громкости в фоновом режиме?

Я знаю, как слушать кнопки громкости в действии. Но могу ли я сделать это в фоновом режиме? Если да, как это сделать?

Solutions Collecting From Web of "Слушать кнопки громкости в фоновом режиме?"

Судя по парам других вопросов по этой теме, нет.

Другой вопрос 1 , Другой вопрос 2

Сервисы просто не получают обратные вызовы KeyEvent.

Мне очень жаль вас рассказать, но ВОЗМОЖНО. Используйте код ниже (ДЛЯ НОВЫХ ANDROIDS, ESP. MARSHMALLOW, ВИДЕТЬ НИЖНЕЙ ЧАСТИ ОТВЕТА):

public class SettingsContentObserver extends ContentObserver { int previousVolume; Context context; public SettingsContentObserver(Context c, Handler handler) { super(handler); context=c; AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); previousVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC); } @Override public boolean deliverSelfNotifications() { return super.deliverSelfNotifications(); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); int currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC); int delta=previousVolume-currentVolume; if(delta>0) { Logger.d("Ściszył!"); previousVolume=currentVolume; } else if(delta<0) { Logger.d("Zrobił głośniej!"); previousVolume=currentVolume; } } } 

Затем в вашем сервисе onCreate зарегистрируйте его с помощью:

 mSettingsContentObserver = new SettingsContentObserver(this,new Handler()); getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver ); 

Затем отмените регистрацию в onDestroy:

 getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver); 

Обратите внимание, что в этом примере определяется изменение громкости мультимедиа, если вы хотите использовать другой том, измените его!

ОБНОВИТЬ:

Вышеуказанный метод, по-видимому, не работает на Marshmallow, НО есть намного лучший путь с момента появления MediaSession! Поэтому сначала вам нужно перенести свой код на шаблон MediaController / MediaSession, а затем использовать этот код:

 private VolumeProviderCompat myVolumeProvider = null; myVolumeProvider = new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) { @Override public void onAdjustVolume(int direction) { // <0 volume down // >0 volume up } }; mSession.setPlaybackToRemote(myVolumeProvider); 

Как-то нажатие кнопки регулировки громкости обнаруживается даже при выключенном экране (просто обязательно зарегистрируйте правильный приемник кнопки медиа-кнопки, если это применимо для вашей платформы!)

ОБНОВЛЕНИЕ 2, так как GalDude запросил дополнительную информацию о получении медиа-MediaSession / MediaController. Извините, но поскольку я прекратил использовать Java, он будет в Kotlin:

 lateinit var mediaSession: MediaSessionCompat // you have to initialize it in your onCreate method val kontroler: MediaControllerCompat get() = mediaSession.controller // in Java it's just getController() on mediaSession // in your onCreate/start method: mediaSession = MediaSessionCompat(this, "YourPlayerName", receiver, null) mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS) mediaSession.isActive = true if (ratingIsWorking) // note: rating crashes on some machines you have to check it! mediaSession.setRatingType(RatingCompat.RATING_5_STARS) mediaSession.setCallback(object : MediaSessionCompat.Callback() { ... // here you have to implement what happens with your player when play/pause/stop/ffw etc. is requested - see exaples elsewhere }) // onDestroy/exit method: mediaSession.isActive = false mediaSession.release() 

Приложение AOSP Music имеет службу ( MediaPlaybackService ), которая реагирует на события громкости, регистрируя BroadcastReceiver ( MediaButtonIntentReceiver ).

Вот фрагмент кода, где он регистрирует приемник:

  mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); ComponentName rec = new ComponentName(getPackageName(), MediaButtonIntentReceiver.class.getName()); mAudioManager.registerMediaButtonEventReceiver(rec); 

Кроме того, не забывайте о манифесте:

  <receiver android:name="com.android.music.MediaButtonIntentReceiver"> <intent-filter> <action android:name="android.intent.action.MEDIA_BUTTON" /> <action android:name="android.media.AUDIO_BECOMING_NOISY" /> </intent-filter> </receiver> 

Это работает, даже если приложение «Музыка» не находится на переднем плане. Разве это не то, чего вы хотите?

Android не документирует API при взаимодействии с кнопками громкости в этом случае. Поэтому я думаю, что ответ не …

В зависимости от контекста, в котором требуется обратный вызов, может быть доступно альтернативное решение.

Чтобы быть способным обнаруживать кнопку громкости, для Activity необходимо переопределить функцию dispatchKeyEvent . Чтобы это существовало в нескольких действиях, можно было написать суперкласс, содержащий переопределенную функцию, которая расширяется всеми последующими действиями.

Вот код для обнаружения нажатий клавиш увеличения и уменьшения громкости:

  // Over-ride this function to define what should happen when keys are pressed (eg Home button, Back button, etc.) @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_VOLUME_UP: // Volume up key detected // Do something return true; case KeyEvent.KEYCODE_VOLUME_DOWN: // Volume down key detected // Do something return true; } } return super.dispatchKeyEvent(event); } 

Я смог заставить его работать на устройствах Android 5+, используя MediaSession . Однако ContentObserver предложенный @ssuukk, не работал для меня как на устройствах 4.4, так и на 7.0 (по крайней мере, на ПЗУ, которые я тестировал). Вот полный пример, который работает на android 5+.

Обслуживание:

 import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.v4.media.VolumeProviderCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; public class PlayerService extends Service { private MediaSessionCompat mediaSession; @Override public void onCreate() { super.onCreate(); mediaSession = new MediaSessionCompat(this, "PlayerService"); mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mediaSession.setPlaybackState(new PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_PLAYING, 0, 0) //you simulate a player which plays something. .build()); //this will only work on Lollipop and up, see https://code.google.com/p/android/issues/detail?id=224134 VolumeProviderCompat myVolumeProvider = new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, /*max volume*/100, /*initial volume level*/50) { @Override public void onAdjustVolume(int direction) { /* -1 -- volume down 1 -- volume up 0 -- volume button released */ } }; mediaSession.setPlaybackToRemote(myVolumeProvider); mediaSession.setActive(true); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); mediaSession.release(); } } 

В AndroidManifest.xml :

 <application ...> ... <service android:name=".PlayerService"/> </application> 

В вашей деятельности:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... startService(new Intent(this, PlayerService.class)); } 

Есть несколько вещей, о которых нужно знать:

  • Он полностью перехватывает кнопки громкости, поэтому пока этот код работает, вы не сможете регулировать громкость звонка с помощью кнопок регулировки громкости. Это можно исправить, я просто не пробовал.
  • Если вы запустите пример как есть, кнопки регулировки громкости будут оставаться под контролем приложения, даже если экран выключен, и приложение было удалено из списка «Недавние приложения». Вам нужно будет перейти в Settings->Applications , найти приложение и принудительно остановить его, чтобы вернуть кнопки громкости.

Checkout Контроль громкости и воспроизведения вашего приложения … Это поможет решить вашу проблему … несколько приложений могут захотеть прослушивать нажатия кнопок из фона, это может быть причиной того, что KeyEvents могут обрабатываться только действиями, поскольку они являются интерфейсом Пользователю, нажимая клавиши.