在安卓锁屏界面如何处理音量变化?

3
我想要做的是,在Android 4.4上能够捕获锁屏界面上音量增减按钮的操作。 Google Cast Design Checklist文档描述了锁屏要求“通过硬件按钮提供访问音量控制”的功能。我尝试了多种方法来处理锁屏界面上的硬件音量按钮,但都没有成功。
  1. onKeyDown/dispatchKeyEvent - 我尝试在Activity上重写onKeyDown和dispatchKeyEvent方法,但这些方法在锁屏时都不会执行,只有当我的应用程序获得焦点时才有效。

  2. Settings.System.CONTENT_URI/ContentObserver - 在主活动的内容解析器上注册内容观察器确实可以捕获系统设置更改,但这也不会发生在锁屏时。

  3. android.intent.action.MEDIA_BUTTON - 在清单中设置此过滤器,我能够从锁屏接收到播放/暂停操作,但无法接收音量更改事件。

  4. android.media.VOLUME_CHANGED_ACTION - 在清单中设置此过滤器,此事件将在我的广播接收器中接收,但不幸的是,在锁屏时其额外值永远不会改变。即使我不断按音量按钮,返回的android.media.EXTRA_VOLUME_STREAM_VALUE仍然相同(即始终为1),尽管广播接收器接收到了CHANGED动作。

  5. CastVideos-android - 参考Android发送方应用似乎能够在接收方上控制音量,即使从发送者的锁屏上进行控制,但是即使在Cast.CastApi.setVolume()周围放置断点,也无法捕获它们。因此,看起来命令是从我无法找到的地方发送到接收器。

我还可以看到其他应用程序能够捕获硬件音量键,例如播放音乐应用程序。因此,我的设备肯定有能力...

有人可以建议任何有效的解决方案吗?


1
对于 CastVideos-Android,它在 CastCompanionLibrary 中处理。我相信是通过 VideoCastManager 实现的。 - Andy
2个回答

2

如果您在使用Android低版本(Lollipop之前),则需要使用RemoteControlClient。如果是在最近引入的版本中,则需要使用MediaSession。例如,可以查看CastCompanionLibrary, VideoCastManager#setUpRemoteControl()方法,在其中使用MediaRouter注册RCC。如果使用MediaSession,则需要使用MediaRouter注册MediaSession。


谢谢您指引我正确的方向,我确实需要调用 mediaRouter.addRemoteControlClient() - Yoz

1
在最后,似乎我缺少了一行代码:
MediaRouter.getInstance(context).addRemoteControlClient(remoteControlClient);

或者

MediaRouter.getInstance(activity).setMediaSession(session.getMediaSession());

这是我在4.0+版本中实现的更多代码:

import android.media.AudioManager;
import android.media.RemoteControlClient;
import android.support.v7.media.MediaRouter;

remoteControlClient = new RemoteControlClient(pendingIntent);
remoteControlClient.setTransportControlFlags(RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE);

audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.registerMediaButtonEventReceiver(receiver);
audioManager.registerRemoteControlClient(remoteControlClient);

MediaRouter.getInstance(context).addRemoteControlClient(remoteControlClient);

而对于5.0+:
import android.media.AudioManager;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v7.media.MediaRouter;

session = new MediaSessionCompat(activity, TAG);
session.setPlaybackToLocal(AudioManager.STREAM_MUSIC);

MediaRouter.getInstance(activity).setMediaSession(session.getMediaSession());

有趣的是,有些黑魔法可以在内部控制接收器音量,你自己的Cast.CastApi.setVolume()调用并没有参与其中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接