在 Android 上监听音量变化事件

问题描述 投票:0回答:6

有没有办法在Android上监听音量变化的事件,而不只是接管音量按钮?

我发现唯一有效的是这里,但它只有在音量控制消失后才有效。

并非所有设备都有音量按钮,我需要在音量变化发生时立即捕获它们,而不是在音量对话框消失后捕获。

android event-handling volume
6个回答
30
投票

更好的是,您可以按如下方式注册

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

但需要注意的是 - 有时,如果快速按下大量按钮,通知似乎会延迟。


4
投票

好吧,现在,我所做的是使用 onKeyDown 监听音量按钮(并检查 KEYCODE_VOLUME_DOWN、KEYCODE_VOLUME_MUTE、KEYCODE_VOLUME_UP ),并使用我发布的新的可运行程序来检查音量级别。

另外,由于某些设备有音量对话框,因此我根据此链接添加了一个侦听器来监听它何时消失。


2
投票

使用广播接收器VOLUME_CHANGED_ACTION,然后使用AudioManager获取当前音量。

<receiver android:name="VolumeChangeReceiver" >
    <intent-filter>
         <action android:name="android.media.VOLUME_CHANGED_ACTION" />
    </intent-filter>
</receiver>

1
投票

2023 年带有广播接收器的解决方案

可与音量按钮和 Android 系统 UI 配合使用。 在本例中,我使用 BroadcastReceiver 作为 Inner Class。 我正在使用与此类似的实现来更新片段中的搜索栏。

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


0
投票

您可以使用: 注册MediaButtonEventReceiver(组件名称事件接收器) 它将组件注册为 MEDIA_BUTTON 意图的唯一接收者。

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

我们在这里所做的是定义一个处理 ACTION_MEDIA_BUTTON 的 BroadcastReceiver。并使用 EXTRA_KEY_EVENT ,它包含导致广播获取按下的内容并对其采取行动的按键事件。


0
投票

对于使用 kotlin 流的用户,您可以使用以下方法来监听特定流的音量变化(本例中为通知):

private val Context.notificationVolumeFlow
    get() = callbackFlow {
        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                when (intent.getIntExtra("android.media.EXTRA_VOLUME_STREAM_TYPE", 0)) {
                    AudioManager.STREAM_NOTIFICATION -> trySend(
                        intent.getIntExtra(
                            "android.media.EXTRA_VOLUME_STREAM_VALUE",
                            0
                        )
                    )
                }
            }
        }

        registerReceiver(receiver, IntentFilter("android.media.VOLUME_CHANGED_ACTION"))
        awaitClose { unregisterReceiver(receiver) }
    }

您可以按照以下方式领取:

lifecycleScope.launch {
    notificationVolumeFlow.collect { Log.d("SOME_TAG", "Notification stream volume: $it") }
}
© www.soinside.com 2019 - 2024. All rights reserved.