有没有一种方法可以监听 Android 设备的音量变化事件,而不只是接管音量按钮?
我所找到的唯一有效方法是这里,但它仅在音量控制消失后才开始生效。
并非所有设备都有音量按钮,我需要尽早捕获音量变化,而不是在音量对话框消失之后。
有没有一种方法可以监听 Android 设备的音量变化事件,而不只是接管音量按钮?
我所找到的唯一有效方法是这里,但它仅在音量控制消失后才开始生效。
并非所有设备都有音量按钮,我需要尽早捕获音量变化,而不是在音量对话框消失之后。
更好的方式是,您可以按照以下方式注册ContentObserver
:
getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, new ContentObserver(){...} );
您的ContentObserver可能看起来像这样:
public class SettingsContentObserver extends ContentObserver {
private AudioManager audioManager;
public SettingsContentObserver(Context context, Handler handler) {
super(handler);
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
}
@Override
public boolean deliverSelfNotifications() {
return false;
}
@Override
public void onChange(boolean selfChange) {
int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "Volume now " + currentVolume);
}
}
完成后:
getApplicationContext().getContentResolver().unregisterContentObserver(mContentObserver);
但需要注意的是,如果快速按下大量按钮,通知有时会出现延迟。
目前,我的做法是使用onKeyDown监听音量按钮(并检查KEYCODE_VOLUME_DOWN、KEYCODE_VOLUME_MUTE、KEYCODE_VOLUME_UP),然后使用一个处理程序将新的可运行对象发布来检查音量级别。
此外,由于一些设备有音量对话框,我已添加了一个侦听器以在其消失时执行操作,参考此链接。
使用广播接收器VOLUME_CHANGED_ACTION,然后使用AudioManager获取当前音量。
<receiver android:name="VolumeChangeReceiver" >
<intent-filter>
<action android:name="android.media.VOLUME_CHANGED_ACTION" />
</intent-filter>
</receiver>
可通过音量按钮和Android系统UI操作。 在此示例中,我将BroadcastReceiver作为内部类使用。 我在片段中使用类似的实现来更新拖动条。
public class AFragment extends Fragment {
private Context context;
private AudioManager audioManager;
// THE STREAM TYPE YOU WANT VOLUME FROM
private final int streamType = AudioManager.STREAM_MUSIC;
private VolumeChangeListener volumeChangeListener;
private IntentFilter intentFilter;
private final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
public AFragment(Context context) {
this.context = context;
this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
this.volumeChangeListener = new VolumeChangeListener();
this.intentFilter = new IntentFilter(VOLUME_CHANGED_ACTION);
}
@Override
public void onDestroy() {
super.onDestroy();
context.unregisterReceiver(volumeChangeListener);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context.registerReceiver(volumeChangeListener, intentFilter);
}
private class VolumeChangeListener extends BroadcastReceiver {
// VOLUME CHANGED ACTION triggers 3 times
// Making use of increment variable to make sure to skip the extra calls
private int callCount = 0;
@Override
public void onReceive(Context context, Intent intent) {
callCount++;
if (intent.getAction().equals(VOLUME_CHANGED_ACTION)) {
if (callCount % 3 == 0) {
int SYSTEM_currentVolume = audioManager.getStreamVolume(streamType);
// DO WHATEVER YOU WANT WITH THE NEW VOLUME VALUE
}
}
}
}
}
IntentFilter android.media.VOLUME_CHANGED_ACTION 可在此处找到:Android Google Source
// in your activity.
MediaButtonReceiver receiver = new MediaButtonReceiver();
// in onCreate put
registerMediaButtonEventReceiver(receiver);
class MediaButtonReceiver implements BroadcastReceiver {
void onReceive(Intent intent) {
KeyEvent ke = (KeyEvent)intent.getExtra(Intent.EXTRA_KEY_EVENT);
if (ke .getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
//action when volume goes down
}
if (ke .getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
//action when volume goes up
}
}
}
//In both onStop and onPause put :
unregisterMediaButtonEventReceiver(receiver);