react-native-volume-manager

repository·main·Indexed 43 days ago

https://github.com/hirbod/react-native-volume-manager

A React Native library for controlling and observing system volume, iOS silent switch status, and Android ringer modes. Version 2.2.0 provides APIs to get and set volume, suppress native volume UI, manage iOS AVAudioSession categories, and handle Android Do Not Disturb access. Includes hooks like useSilentSwitch and useRingerMode for reactive state management.

Tokens
6.1K
Snippets
23
Records
25
Agent score
52%

What's inside react-native-volume-manager

  1. Install react-native-volume-manager

    main

    Install the package using yarn or npm. For iOS, you must run pod install in the ios directory.

    Requirements:

    • React Native 0.85 or newer (recommended).
    • iOS 15.0 or newer.
    • Android min SDK 24.
    • New Architecture projects are the supported path.
    • Expo: Requires a custom development build. Expo Go is not supported.

    If using Expo and targeting iOS below 15.0, configure expo-build-properties in your app.json to set the deploymentTarget to 15.0.

    yarn add react-native-volume-manager
    # or
    npm install react-native-volume-manager
    
    cd ios && pod install
  2. Run the React Native Volume Manager example project

    main

    To run the example project, navigate to the example directory and execute the following commands. This project requires a native build because the module is not supported in Expo Go.

    Note: This example uses Expo SDK 57 and React Native 0.86.

    yarn
    npx expo prebuild --clean
    npx expo run:ios
    npx expo run:android
  3. Configure Expo for react-native-volume-manager

    main

    Since this package requires native code, you must use development builds. Use npx expo prebuild to generate native directories and then run the platform-specific command. If you need to support iOS 15.0 specifically for this library, update your app.json configuration.

    [
      "expo-build-properties",
      {
        "ios": {
          "deploymentTarget": "15.0"
        }
      }
    ]
  4. Understand Ringer Modes and Device Modes

    main

    The library uses two different representations for ringer/device states:

    1. RingerModeType: Numeric values used for ringer settings.

      • RINGER_MODE.silent (0)
      • RINGER_MODE.vibrate (1)
      • RINGER_MODE.normal (2)
    2. Mode (Enum): String-based modes representing the device state, often used in event callbacks.

      • Mode.SILENT ('SILENT')
      • Mode.VIBRATE ('VIBRATE')
      • Mode.NORMAL ('NORMAL')
      • Mode.MUTED ('MUTED')
    // Numeric Ringer Mode
    const ringerMode: RingerModeType = RINGER_MODE.vibrate;
    
    // String-based Device Mode
    const deviceMode: Mode = Mode.SILENT;
  5. Web platform support and limitations

    main

    The react-native-volume-manager package provides a web implementation (module.web.ts) to prevent runtime errors when using the library in a web environment.

    Important Limitations:

    • No Functionality: All API methods are no-op (no-operation) implementations. They will not actually change volume, ringer modes, or audio sessions on the web.
    • Return Values: Methods like getVolume return a default VolumeResult (volume: 1), while others return undefined or null.
    • Development Warning: In development mode (__DEV__), a warning will be logged to the console to notify you that the methods have no actual effect on the web platform.
  6. Troubleshoot react-native-volume-manager

    main

    Common issues:

    • Package not linked: Rebuild the native app. For iOS, ensure you run pod install first.
    • Expo Go does not work: This package contains native code. You must use a custom development build.
    • Android keyboard does not dismiss: This was caused by focus interception in older versions. Ensure you are using version 2.1.0 or newer.
  7. Use the VolumeManager API for cross-platform volume control

    main

    The VolumeManager class provides methods to read, set, and observe system volume.

    • getVolume(): Returns the current volume.
    • setVolume(value, config?): Sets the volume. value must be between 0 and 1.
    • showNativeVolumeUI({ enabled }): Shows or hides the native system volume UI. When disabled, the module intercepts hardware volume keys, allowing you to build custom UI.
    • addVolumeListener(callback): Subscribes to volume changes. On Android, the callback receives a VolumeResult containing the volume and the type (e.g., music, ring, etc.).
    import { VolumeManager } from 'react-native-volume-manager';
    
    // Read the current volume.
    const { volume } = await VolumeManager.getVolume();
    
    // Set the music volume to 50%.
    await VolumeManager.setVolume(0.5);
    
    // Hide the native volume UI for custom controls.
    await VolumeManager.showNativeVolumeUI({ enabled: false });
    
    // Restore the native volume UI.
    await VolumeManager.showNativeVolumeUI({ enabled: true });
    
    // Listen for volume changes.
    const listener = VolumeManager.addVolumeListener((result) => {
      console.log(result.volume, result.type);
    });
    
    listener.remove();
  8. Detect the iOS Silent Switch

    main

    On iOS, you can detect if the hardware silent switch is active.

    Subscription Method: Use addSilentListener(callback) for a subscription-based approach.

    React Hook Method: Use useSilentSwitch(nativeIntervalCheck?) inside components. It returns undefined until the first result is available and returns undefined on non-iOS platforms. You can pass a number to useSilentSwitch to adjust the native polling interval in seconds.

    import { VolumeManager, useSilentSwitch } from 'react-native-volume-manager';
    
    // Subscription approach
    const listener = VolumeManager.addSilentListener((status) => {
      console.log(status.isMuted);
      console.log(status.initialQuery);
    });
    listener.remove();
    
    // Hook approach
    export function SilentSwitchStatus() {
      const status = useSilentSwitch(2); // Poll every 2 seconds
    
      return (
        <View>
          <Text>
            Silent switch: {status?.isMuted === true ? 'muted' : 'not muted'}
          </Text>
        </View>
      );
    }
  9. Manage iOS Audio Session

    main

    The following APIs are iOS-only. On Android, these methods resolve without changing device state. They allow you to control the audio session category, mode, and activation.

    • enable(enabled?, async?): Enables/disables the audio session.
    • setActive(value?, async?): Activates/deactivates the session.
    • setCategory(value, mixWithOthers?): Sets the session category.
    • setMode(value): Sets the session mode.
    • enableInSilenceMode(enabled?): Allows playback even when the hardware silent switch is on.
    • setNativeSilenceCheckInterval(value): Sets the polling interval for the silent switch.
    import { VolumeManager } from 'react-native-volume-manager';
    
    await VolumeManager.enable(true);
    await VolumeManager.setActive(true);
    await VolumeManager.setCategory('Playback', true);
    await VolumeManager.setMode('Default');
    await VolumeManager.enableInSilenceMode(true);
  10. Set a specific Android volume stream

    main

    On Android, you can target specific volume streams (like ringer or alarm) using the setVolume method with a configuration object.

    Available Android Volume Types:

    • music
    • call
    • system
    • ring
    • alarm
    • notification
    import { VolumeManager } from 'react-native-volume-manager';
    
    await VolumeManager.setVolume(0.25, {
      type: 'ring',
      showUI: false,
      playSound: false,
    });
  11. Manage Android Ringer Mode

    main

    On Android, you can read, set, and observe the device's ringer mode (e.g., silent, vibrate, normal).

    Key Operations:

    • getRingerMode(): Returns the current mode.
    • setRingerMode(mode): Sets the mode using the RINGER_MODE enum.
    • addRingerListener(callback): Subscribes to changes.
    • checkDndAccess(): Checks if the app has Do Not Disturb access.
    • requestDndAccess(): Requests Do Not Disturb access (opens Android settings).

    React Hook: useRingerMode() provides mode, error, and setMode directly in your component.

    import {
      RINGER_MODE,
      VolumeManager,
      useRingerMode,
    } from 'react-native-volume-manager';
    
    // Imperative usage
    const currentMode = await VolumeManager.getRingerMode();
    await VolumeManager.setRingerMode(RINGER_MODE.vibrate);
    
    const listener = VolumeManager.addRingerListener((status) => {
      console.log(status.mode, status.status);
    });
    VolumeManager.removeRingerListener(listener);
    
    // Hook usage
    export function RingerControls() {
      const { mode, error, setMode } = useRingerMode();
    
      return (
        <View>
          <Text>Ringer mode: {mode}</Text>
          <Button title="Silent" onPress={() => setMode(RINGER_MODE.silent)} />
          <Button title="Normal" onPress={() => setMode(RINGER_MODE.normal)} />
          <Button title="Vibrate" onPress={() => setMode(RINGER_MODE.vibrate)} />
          <Text>{error?.message}</Text>
        </View>
      );
    }
  12. Configure volume changes with VolumeManagerSetVolumeConfig

    main

    When using methods to set the volume, you can pass a VolumeManagerSetVolumeConfig object to control how the change is applied.

    • playSound (boolean): If true, a sound will play during the volume change. Defaults to false.
    • type (Android only): Specifies which Android volume stream to modify. Use values from AndroidVolumeTypes.
    • showUI (boolean): If true, the native system volume UI will be displayed. Defaults to false.
    const config: VolumeManagerSetVolumeConfig = {
      playSound: true,
      type: 'ring', // Android only
      showUI: true
    };