React Native音量增减监听方案咨询
React Native 音量增减监听解决方案
Android 端实现
方法一:利用 react-native-keyevent 监听物理音量键
这个库支持监听物理按键事件,你之前可能没完成完整配置:
- 在
AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.VIBRATE" />
- 修改
MainActivity.java注册按键回调:
import com.github.kevinejohn.keyevent.KeyEventModule; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { KeyEventModule.getInstance().onKeyDownEvent(keyCode, event); return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { KeyEventModule.getInstance().onKeyUpEvent(keyCode, event); return super.onKeyUp(keyCode, event); }
- React Native 侧监听逻辑:
import KeyEvent from 'react-native-keyevent'; import { useEffect } from 'react'; useEffect(() => { const handleKeyDown = (event) => { if (event.keyCode === KeyEvent.KEYCODE_VOLUME_UP) { console.log('音量+键触发'); // 这里可结合音量库获取当前音量,执行自定义逻辑 } else if (event.keyCode === KeyEvent.KEYCODE_VOLUME_DOWN) { console.log('音量-键触发'); } }; KeyEvent.onKeyDownListener(handleKeyDown); return () => KeyEvent.removeKeyDownListener(); }, []);
方法二:原生封装音量变化广播接收器
如果现有库满足不了需求,可以自己写原生模块监听系统音量广播:
- 创建广播接收器捕获音量变化:
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.media.AudioManager; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.WritableMap; import com.facebook.react.modules.core.DeviceEventManagerModule; public class VolumeChangeReceiver extends BroadcastReceiver { private final ReactContext reactContext; public VolumeChangeReceiver(ReactContext context) { this.reactContext = context; } @Override public void onReceive(Context context, Intent intent) { if (AudioManager.VOLUME_CHANGED_ACTION.equals(intent.getAction())) { int currentVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1); int prevVolume = intent.getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1); WritableMap params = Arguments.createMap(); params.putInt("currentVolume", currentVolume); params.putInt("prevVolume", prevVolume); reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("volumeChanged", params); } } }
- 在原生模块中注册广播,并在 JS 侧监听事件:
import { NativeEventEmitter, NativeModules } from 'react-native'; import { useEffect, useRef } from 'react'; const VolumeEmitter = new NativeEventEmitter(NativeModules.VolumeModule); useEffect(() => { const prevVolume = useRef(null); const subscription = VolumeEmitter.addListener('volumeChanged', (data) => { if (prevVolume.current === null) { prevVolume.current = data.currentVolume; return; } if (data.currentVolume > prevVolume.current) { console.log('音量增加,当前值:', data.currentVolume); } else if (data.currentVolume < prevVolume.current) { console.log('音量减少,当前值:', data.currentVolume); } prevVolume.current = data.currentVolume; }); return () => subscription.remove(); }, []);
iOS 端实现
方法一:使用 react-native-volume-manager 监听音量变化
这个库其实内置了音量监听,你可以这样用:
import VolumeManager from 'react-native-volume-manager'; import { useEffect, useRef } from 'react'; useEffect(() => { const prevVolume = useRef(null); const listener = VolumeManager.addVolumeListener((result) => { const { volume } = result; if (prevVolume.current === null) { prevVolume.current = volume; return; } if (volume > prevVolume.current) { console.log('音量增加至:', volume); } else if (volume < prevVolume.current) { console.log('音量减少至:', volume); } prevVolume.current = volume; }); return () => VolumeManager.removeVolumeListener(listener); }, []);
注意:iOS 14+ 需要在 Info.plist 中添加权限描述:
<key>NSMicrophoneUsageDescription</key> <string>需要访问音频会话以监听音量变化</string>
方法二:原生监听 AVAudioSession 通知
自己封装原生模块监听系统音量变化通知:
import AVFoundation import React @objc(VolumeModule) class VolumeModule: NSObject, RCTBridgeModule { static func moduleName() -> String { "VolumeModule" } static func requiresMainQueueSetup() -> Bool { true } private var observer: NSObjectProtocol? override init() { super.init() observer = NotificationCenter.default.addObserver( forName: .AVAudioSessionOutputVolumeDidChange, object: AVAudioSession.sharedInstance(), queue: .main ) { [weak self] notification in guard let volume = notification.userInfo?[AVAudioSessionOutputVolumeKey] as? Float else { return } self?.sendVolumeEvent(volume: volume) } } private func sendVolumeEvent(volume: Float) { guard let bridge = RCTBridge.current() else { return } bridge.eventDispatcher().sendAppEvent( withName: "volumeChanged", body: ["volume": volume] ) } deinit { if let observer = observer { NotificationCenter.default.removeObserver(observer) } } }
JS 侧监听方式和 Android 原生模块一致。
内容的提问来源于stack exchange,提问作者황시나
相关产品推荐
相关产品推荐

