Giter Site home page Giter Site logo

hirbod / react-native-volume-manager Goto Github PK

View Code? Open in Web Editor NEW
223.0 3.0 15.0 4.24 MB

React Native module which adds the ability to change the system volume on iOS and Android, listen to volume changes and supress the native volume UI to build your own volume slider or UX. It can listen to iOS mute switch and ringer mode changes on Android (and let you set the ringer mode)

License: MIT License

Shell 0.21% Java 29.41% JavaScript 4.44% TypeScript 33.64% Ruby 5.99% Objective-C 14.58% Kotlin 5.65% Objective-C++ 4.24% Swift 1.86%
android expo ios react react-native

react-native-volume-manager's Introduction

React Native Volume Manager Ringer Mute Silent Switch

react-native-volume-manager

Enhance system volume control on iOS and Android with this native package. Adjust the volume, monitor changes, and create custom volume sliders and user experiences. The package provides an intuitive API for accessing the current volume level, detecting the silent switch status (iOS), and tracking ringer mode changes (Android).

React Native Volume Manager React Native Volume Manager

Features

  • Adjust system volume
  • Monitor volume changes
  • Suppress default volume UI
  • Access current volume level
  • Detect silent switch status (iOS)
  • Enable/disable audio session and change category (iOS)
  • Track ringer mode changes (Android)

Installation

Using npm:

npm install react-native-volume-manager

Using Yarn:

yarn add react-native-volume-manager

For React Native >= 0.60, manual linking is not required with Autolinking.

Note: This library is incompatible with Expo Go. To use it, you can install a custom development client as recommended in 2023.

Simulators / Emulators

  • iOS: The AVAudioSession API offers control over audio behaviors and settings on iOS devices. However, some hardware-specific features of AVAudioSession, such as volume control and audio route selection, don't have equivalent functionalities on macOS, which the simulator runs on. As a result, this package operates only on a real device, with events not being triggered on the simulator.
  • Android: It runs on both a real device (API level 21+) and the emulator (API level 33+).

Usage

All methods are available under the VolumeManager namespace or can be imported directly. Here are some examples:

import { VolumeManager } from 'react-native-volume-manager';

// Disable the native volume toast globally (iOS, Android)
VolumeManager.showNativeVolumeUI({ enabled: true });

// Set the volume (value between 0 and 1)
await VolumeManager.setVolume(0.5);

// Get the current volume async
const { volume } = await VolumeManager.getVolume();

// Listen to volume changes
const volumeListener = VolumeManager.addVolumeListener((result) => {
  console.log(result.volume);

  // On Android, additional volume types are available:
  // music, system, ring, alarm, notification
});

// Remove the volume listener
volumeListener.remove();

For more usage examples and detailed API documentation, please refer to the GitHub repository.

iOS Audio Session Management

This section provides methods related to AVAudioSession on iOS. For example:

import { VolumeManager } from 'react-native-volume-manager';

// Enable or disable iOS AudioSession
VolumeManager.enable(true, true); // Enable async
VolumeManager.enable(false, true); // Disable async, non-blocking

// Activate or deactivate the audio session
VolumeManager.setActive(true, true); // Activate async
VolumeManager.setActive(false, true); // Deactivate async, non-blocking

iOS Mute Switch Listener

To monitor the mute switch status on iOS, you can use the following:

import { VolumeManager } from 'react-native-volume-manager';

const silentListener = VolumeManager.addSilentListener((status) => {
  console.log(status.isMuted);
  console.log(status.initialQuery);
});

// Remove the silent listener
silentListener.remove();

Android Ringer Listener

To listen to ringer mode changes on Android, you can use the following:

import { VolumeManager } from 'react-native-volume-manager';

const ringerListener = VolumeManager.addRingerListener((status) => {
  console.log(status.ringerMode);
});

// Remove the ringer listener
VolumeManager.removeRingerListener(ringerListener);

useSilentSwitch hook

useSilentSwitch is a custom React hook that monitors the silent switch on an iOS device. The nativeIntervalCheck parameter (optional) allows you to set the interval at which the silent switch status is checked in seconds. If the parameter is not provided, a default interval is used (2.0).

The hook returns an object with two properties: isMuted (which represents the ring/mute switch position) and initialQuery (which indicates whether the reported status is the first one after the application launch). On non-iOS platforms or for the first call, the hook returns undefined. This hook is only applicable to iOS.

import React from 'react';
import { View, Text } from 'react-native';
import { useSilentSwitch } from 'react-native-volume-manager';

export default function App() {
  const status = useSilentSwitch();

  return (
    <View>
      <Text>Silent Switch Status:</Text>
      {status ? (
        <View>
          <Text>Is Muted: {status.isMuted ? 'YES' : 'NO'}</Text>
          <Text>Is Initial Query: {status.initialQuery ? 'YES' : 'NO'}</Text>
        </View>
      ) : (
        <Text>Fetching...</Text>
      )}
    </View>
  );
}

In this example, useSilentSwitch is used to monitor the status of the silent switch on iOS devices. The status of the switch (isMuted) and whether it's the initial query (initialQuery) are displayed. If the status is not available yet, "Fetching..." is displayed.

useRingerMode Hook

You can use the useRingerMode hook to get and set the ringer mode on Android:

import React from 'react';
import { View, Text, Button } from 'react-native';
import {
  useRingerMode,
  RINGER_MODE,
  RingerModeType,
} from 'react-native-volume-manager';

const modeText = {
  [RINGER_MODE.silent]: 'Silent',
  [RINGER_MODE.normal]: 'Normal',
  [RINGER_MODE.vibrate]: 'Vibrate',
};

export default function App() {
  const { mode, error, setMode } = useRingerMode();

  return (
    <View>
      <Text>Ringer Mode: {mode !== undefined ? modeText[mode] : null}</Text>

      <View>
        <Button title="Silent" onPress={() => setMode(RINGER_MODE.silent)} />
        <Button title="Normal" onPress={() => setMode(RINGER_MODE.normal)} />
        <Button title="Vibrate" onPress={() => setMode(RINGER_MODE.vibrate)} />
      </View>

      <View>
        <Text>{error?.message}</Text>
      </View>
    </View>
  );
}

API

The VolumeManager API provides an interface for controlling and observing volume settings on iOS and Android devices. The API is designed to offer a consistent experience across both platforms where possible, with some platform-specific functionality provided where necessary.

Cross-platform methods:

  • showNativeVolumeUI(config: { enabled: boolean }): Promise<void>: This asynchronous function allows you to control the visibility of the native volume UI when volume changes occur.

  • getVolume(): Promise<VolumeResult>: Asynchronously fetches the current volume level and returns a promise that resolves to an object, VolumeResult, containing the current volume information.

  • setVolume(value: number, config?: VolumeManagerSetVolumeConfig): Promise<void>: Allows you to programmatically adjust the device's volume level. The value parameter should be between 0 and 1, and config parameter is an optional object for additional configuration settings.

  • addVolumeListener(callback: (result: VolumeResult) => void): EmitterSubscription: Allows you to add a listener that will be called when the device's volume changes. The listener receives an object, VolumeResult, that contains the updated volume information.

iOS-only methods:

  • enable(enabled: boolean, async: boolean): Promise<void>: Enables or disables the audio session. Enabling the audio session sets the session's category to 'ambient', allowing it to mix with other audio.

  • setActive(value: boolean, async: boolean): Promise<void>: Activates or deactivates the audio session. Deactivating the session reactivates any sessions that were interrupted by this one.

  • setCategory(value: AVAudioSessionCategory, mixWithOthers?: boolean): Promise<void>: Sets the category for the AVAudioSession in your iOS app. mixWithOthers is an optional parameter that, if true, allows your audio to mix with audio from other apps.

  • setMode(mode: AVAudioSessionMode): Promise<void>: Sets the mode for the AVAudioSession in your iOS app.

  • enableInSilenceMode(value: boolean): Promise<void>: If value is true, this function allows your app to play audio even when the device is in silent mode. When value is false, audio will not play in silent mode.

  • setNativeSilenceCheckInterval(value: number): Sets the interval at which the native system checks the state of the silent switch.

  • addSilentListener(callback: RingMuteSwitchEventCallback): EmitterSubscription | EmitterSubscriptionNoop: Adds a listener that will be called when the silent switch state changes.

Android-only methods:

  • getRingerMode(): Promise<RingerModeType | undefined>: Asynchronously fetches the current ringer mode of the device (silent, vibrate, or normal).

  • setRingerMode(mode: RingerModeType): Promise<RingerModeType | undefined>: Sets the device's ringer mode.

  • isRingerListenerEnabled(): Promise<boolean>: Asynchronously checks whether a ringer mode listener is enabled.

  • addRingerListener(callback: RingerEventCallback): EmitterSubscription | EmitterSubscriptionNoop: Adds a listener that will be called when the ringer mode changes.

  • removeRingerListener(listener: EmitterSubscription | EmitterSubscriptionNoop): void: Removes a previously added ringer mode listener.

  • checkDndAccess(): Promise<boolean | undefined>: Asynchronously checks if 'Do Not Disturb' access has been granted.

  • requestDndAccess(): Promise<boolean | undefined>: Initiates a request for 'Do Not Disturb' access.

Please note that while this API tries to provide a consistent experience across both platforms, some methods are platform-specific due to the differences in how iOS and Android handle

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

Special thanks

I used parts, or even the full source code, of these libraries (with plenty of adjustments and rewrites to TypeScript) to make this library work on Android and iOS and to have a mostly unified API that handles everything related to volume. Since many of the packages I found were unmaintained or abandoned and only solved some of the issues, I decided to create my own. I hope you don't mind it and find it useful!

License

MIT

react-native-volume-manager's People

Contributors

barthap avatar bbarthec avatar emangulo avatar hirbod avatar nasseratic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

react-native-volume-manager's Issues

Seeking Assistance to Implement Notification Volume Adjustment Based on User Settings

Hi there,

I am currently working on a feature in my app that involves updating the notification volume according to user preferences. I'm seeking guidance and assistance on how to successfully implement this functionality.

The goal is to allow users to customize the notification volume within the app, ensuring a personalized and user-friendly experience. I would appreciate any insights, suggestions, or code snippets that could help me achieve this feature.

Thank you in advance for your support!

Screenshot_1702534584

Ability to use this while the app is unfocused or the screen is off

Hello, great library. It was very easy to get up and running with this in a new react-native project.

Does this library support accessing volume events while the App activity is unfocused (in another app, on the home screen) or when the screen is off entirely?

I want to get an event about volume button presses (Not volume changes, so android.media.VOLUME_CHANGED seems inappropriate as the base Intent). If this project isn't correct, can anyone point me in the right direction?

Setting volume on iOS in VoIP Video Call

Hello.

Has anyone tried to set the volume of the video call, with this library?
I tried doing it, but with no success. Sometimes it works for a certain amount of time, then stops working completely when the video call screen is in focus again. Sometimes it doesn't even work at all.

I am using react-native-callkeep and react-native-incall-manager to handle my calls, and to route the audio to the speakers, maybe react-native-volume-manager has a conflict when used with those libraries (maybe a specific library has the superior control over the audio session or more permission, overruling the others), i don't know.

When the video call screen is in focus, i call these:

await VolumeManager.setCategory('PlayAndRecord', false);
await VolumeManager.setMode('VideoChat'); // i tried it with VoiceChat and SpokenAudio too
await VolumeManager.setActive(true, true);

Then, when i set the volume of the call:

await VolumeManager.setVolume(volume * 0.2) // volume is [1, 5]

When the video call screen is out of focus/unmounted, i call this, to clean the audio session:

VolumeManager.setActive(false)

Am i doing something wrong? Did anyone implement this use case successfully before?

My environment is:

iPad (9th generation)
iPadOS Version: 16.3.1
Physical device

Dependencies:

"react-native": "0.70.5",
"expo": "~47.0.12",
"react-native-callkeep": "4.3.12",
"react-native-incall-manager": "4.0.1",
"react-native-volume-manager": "1.8.1",

Fabric

Whoever has the ability to add Fabric support: PRs welcome!

[bug][ios]: events getting swallowed

On iOS, events could get swallowed if fired too rapidly.

maybe instead of counting, try remembering last saved volume in setVolume and then if it's the same in event, skip emitting it

Why is getVolume typed as number | VolumeResult?

/**
 * Get the current device volume.
 * @param {AndroidVolumeTypes} type - The type of volume you want to retrieve. Defaults to 'music' (Android only, no-op on iOS).
 * @returns {Promise<VolumeResult>} - Returns a promise that resolves to an object with the volume value.
 *
 * @example
 * ```ts
 * const { volume } = await VolumeManager.getVolume('music'); // type is no-op on iOS
 * ```
 */
export async function getVolume(
  type: AndroidVolumeTypes = 'music'
): Promise<VolumeResult | number> {
  return await VolumeManagerNativeModule.getVolume(type);
}

With the return type of getVolume() being Promise<VolumeResult | number>, wouldn't the example code fail: const { volume } = await VolumeManager.getVolume('music');

Perhaps the number type may be removed as a return type?

iOS 16.4. showNativeVolumeUI - no effect

I applied some actions on the volume button press and used this library for it.
Before my iPhone has not been updated to 16.4 - everything worked well:

  • I turned off the system panel using await VolumeManager.showNativeVolumeUI({ enabled: false });
  • Subscribed to volume change and did actions
  • Turned on the system panel again in the end using await VolumeManager.showNativeVolumeUI({ enabled: true });

After iPhone has been updated to 16.4 await VolumeManager.showNativeVolumeUI({ enabled: false }); doesn't affect anymore and await VolumeManager.setVolume(0.5, { showUI: false }); too.

[bug][ios] event listener doesn't trigger

my case is use volume up/down event to control flatlist scroll prev/next, so i make a useVolumeUpDown hook based on addVolumeListener

and my problem is if the app get in background and switch to other app(i reproduce by use youtube), play video and back to app, the listener will never trigger

so is the volume listener have conflict with other app listener?

  • ios: 15.4.1
  • react-native: 0.72.5
  • react-native-volume-manager: 1.10.0

below is my code and use case:

import { useCallback, useRef, useState } from 'react';
import { useFocusEffect } from '@react-navigation/native';
import { VolumeManager } from 'react-native-volume-manager';
import { Volume } from '~/utils';

export const useVolumeUpDown = (callback: (type: Volume) => void) => {
  const volumeRef = useRef<number>();
  const [initVolume, setInitVolume] = useState<number>();

  const init = useCallback(() => {
    VolumeManager.getVolume().then((volume) => {
      let prev = typeof volume === 'number' ? volume : volume.volume;

      volumeRef.current = prev;
      if (prev <= 0) {
        prev = 0.025;
      } else if (prev >= 1) {
        prev = 0.975;
      }
      VolumeManager.setVolume(prev);
      setInitVolume(prev);
    });
  }, []);
  const listener = useCallback(() => {
    if (typeof initVolume !== 'number') {
      return;
    }

    VolumeManager.showNativeVolumeUI({ enabled: false });
    const volumeListener = VolumeManager.addVolumeListener((result) => {
      if (result.volume - initVolume > 0.0001) {
        setTimeout(
          () => VolumeManager.setVolume(initVolume).finally(() => callback(Volume.Up)),
          200
        );
      } else if (initVolume - result.volume > 0.0001) {
        setTimeout(
          () => VolumeManager.setVolume(initVolume).finally(() => callback(Volume.Down)),
          200
        );
      }
    });

    return () => {
      volumeListener && volumeListener.remove();
      if (typeof volumeRef.current === 'number') {
        VolumeManager.setVolume(volumeRef.current).finally(() => {
          VolumeManager.showNativeVolumeUI({ enabled: true });
        });
      }
    };
  }, [initVolume, callback]);

  useFocusEffect(init);
  useFocusEffect(listener);
};
const Component = () => {
  ...
  const callbackRef = useRef<(type: Volume) => void>();

  callbackRef.current = (type) => {
    if (type === Volume.Down) {
      handleNextPage();
    }
    if (type === Volume.Up) {
      handlePrevPage();
    }
  };

  useVolumeUpDown(
    useCallback((type) => {
      callbackRef.current && callbackRef.current(type);
    }, [])
  );
  ...
}

Volume listener doesn't fire if volume level doesn't change

My use case is using the hardware volume buttons to take a photo, so all I care about is knowing when the buttons have been pressed.

VolumeManager.addVolumeListener works for every case but two: volume is already 0 and the user presses volume down; volume is already 1 and the user presses volume up. In this case, the volume hasn't changed, so the listener doesn't fire. I still want to know that the button was pressed, though. Is there a way to accomplish this?

Android: VolumeManagerModule setupKeyListener NullPointerException error

We are getting a lot of error reports like this in our app which uses your library:

Exception java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window android.app.Activity.getWindow()' on a null object reference
  at com.reactnativevolumemanager.VolumeManagerModule.lambda$setupKeyListener$1$com-reactnativevolumemanager-VolumeManagerModule (VolumeManagerModule.java:90)
  at com.reactnativevolumemanager.VolumeManagerModule$$ExternalSyntheticLambda2.run
  at android.os.Handler.handleCallback (Handler.java:958)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loopOnce (Looper.java:205)
  at android.os.Looper.loop (Looper.java:294)
  at android.app.ActivityThread.main (ActivityThread.java:8248)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:552)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:971)

Could you please think about proper fix for this?
We are currently early returning in setupKeyListener method if mContext.getCurrentActivity() returns null, but this probably could be handled better
This happens on "react-native": "0.68.7", unfortunately im not able to reproduce this issue myself

The binary version of its metadata is 1.8.0, expected version is 1.6.0.

Hi 👋🏼

I am getting this error trying to build android with expo 49 ( react native 0.72 )

Maybe upgrade the Kotlin version again like this issue #11

> Task :react-native-volume-manager:compileDebugKotlin FAILED

[stderr] 
e: Incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors

[stderr] 
e: /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
e: /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
e: /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/META-INF/kotlin-stdlib.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
e: /home/expo/.gradle/caches/transforms-3/f8b9e1ac9c843d8dc990942237200df0/transformed/jetified-kotlin-stdlib-common-1.8.10.jar!/META-INF/kotlin-stdlib-common.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/Utils.kt: (7, 20): Unresolved reference: ln

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/Utils.kt: (22, 10): Not enough information to infer type variable T

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/Utils.kt: (22, 76): Unresolved reference: java

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/Utils.kt: (38, 30): Unresolved reference: ln

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/Utils.kt: (39, 13): Unresolved reference: ln

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (22, 12): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (23, 12): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (24, 13): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (45, 5): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (46, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (48, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (55, 12): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (56, 12): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

[stderr] 
e: /home/expo/workingdir/build/node_modules/react-native-volume-manager/android/src/main/java/com/reactnativevolumemanager/VolumeManagerSilentListenerModule.kt: (62, 29): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.8.0, expected version is 1.6.0.

[stderr] 
The class is loaded from /home/expo/.gradle/caches/transforms-3/0a487ac5fce194b44f47bee930b70ae9/transformed/jetified-kotlin-stdlib-1.8.10.jar!/kotlin/Unit.class

AirPlay Icon on Top Left of the Application

Hello,
when I execute the function setVolume on iOS, in the Top Left of my application show up an AirPlay Icon white that i can't remove. What can i do to fix this problem?
GitHub Issue

addVolumeListener is not triggered on iOS

Hello,
on iOS 15 addVolumeListener is NOT triggered when the volume is changed with a slider or when physical volume buttons are pressed on a device.

OS version:
15.6.1
"react-native": "0.67.5"

Volume manger is not working in the background mode

Related issue(Android)

Step to produce

  • Add the volume manage in background listener (React-Native-Ble-Manager, React-Native-Background-Timer).
  • I'm not able to change the volume in background mode
  • Issue is only detected in oxygen OS

Using oxygen OS - 13.1

I attached screen shot for the reference. Given permission is already granted.

Screenshot 2024-03-04 at 5 24 41 PM

Android: isRingerListenerEnabled() is returning silent mode status, not the ringer listener status

Hi,

And thanks for the library, highly useful!

From the docs:

isRingerListenerEnabled(): Promise<boolean>: Asynchronously checks whether a ringer mode listener is enabled.

I might be misinterpreting things here, but I think there's some confusion here. This method seems to return whether the device is set to silent or not, but the docs and name suggest that this would tell whether a ringer listener is enabled or not. Also, to me, the "silent status" and "silent listener status" are a bit mixed up in the codebase. Does this observation make sense or is it just me getting confused for no good reason?

I've been having some struggle with the event listener handling, as e.g. the volume listener and ringer mode listener are working differently, but I guess there's a valid reason for the ringer mode listener to be setup differently than the others. Anyway, considering the current way of how the ringer mode listening is happening, having a way to check whether ringer mode listener is enabled would be useful.

iOS: VolumeManager.addVolumeListener not responding to volume changing

Hi there,

I'm enjoying this library a lot, it works flawlessly on Android. However, as the title mentions, it doesn't seem to work as intended on an iOS device (iPhone 15 Pro simulator).

I haven't had the chance to test this on a physical device, but I assume it wouldn't change the outcome. This is my current code:

useEffect(() => {
  const volumeListener = VolumeManager.addVolumeListener(() => {
    console.log("Volume changed!");
    // doSomething();
  });
  return () => {
    volumeListener.remove();
  };
}, []);

I'm getting into the useEffect just fine, but I'm not seeing the Volume changed! at any point when pressing the volume buttons on the iOS device.

Thanks in advance for any recommendations!

iOS + Expo unexpected results

Hi, Sorry this is not a bug as such.

We're using Expo and want:

  • Audio from other apps to continue, e.g. spotify, twitch, youtube, etc.
  • Audio to play from our app even when in silent mode
  • To detect when silent mode is turned off/on

We used expo originally and had it working fine with:

import { Audio } from 'expo-av'

await Audio.setAudioModeAsync({
    allowsRecordingIOS: false,
    staysActiveInBackground: true,
    playsInSilentModeIOS: true,
    shouldDuckAndroid: true,
    interruptionModeIOS: InterruptionModeIOS.DuckOthers,
    interruptionModeAndroid: InterruptionModeAndroid.DuckOthers,
})

We then added the following after the above ^^

await VolumeManager.enable(true, false)
await VolumeManager.enableInSilenceMode(true)

VolumeManager.addSilentListener(({ isMuted }) => {
    setState(isMuted)
})

However this seems to pause all audio from other apps when our app boots.

What would be the correct usage to enable what's mentioned above?

Thanks

Android crash on foregrounding app with expo SDK 50

I've been using this library for awhile on iOS, where it works as expected. I recently built my app for Android and installed it on a Google Pixel 6a running Android 14. On Android, it crashes immediately every time the app is foregrounded after being backgrounded. This is the crash log:

07-07 18:08:42.559 E/AndroidRuntime( 9894): FATAL EXCEPTION: main
07-07 18:08:42.559 E/AndroidRuntime( 9894): Process: com.yungchomsky.phomo.dev, PID: 9894
07-07 18:08:42.559 E/AndroidRuntime( 9894): java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window android.app.Activity.getWindow()' on a null object reference
07-07 18:08:42.559 E/AndroidRuntime( 9894): at com.reactnativevolumemanager.VolumeManagerModule.lambda$setupKeyListener$1(VolumeManagerModule.java:90)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at com.reactnativevolumemanager.VolumeManagerModule.$r8$lambda$30rzJyV0GNOXEEl5yx7XsucmwSY(Unknown Source:0)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at com.reactnativevolumemanager.VolumeManagerModule$$ExternalSyntheticLambda2.run(Unknown Source:2)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at android.os.Handler.handleCallback(Handler.java:938)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at android.os.Handler.dispatchMessage(Handler.java:99)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at android.os.Looper.loopOnce(Looper.java:201)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at android.os.Looper.loop(Looper.java:288)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at android.app.ActivityThread.main(ActivityThread.java:7870)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at java.lang.reflect.Method.invoke(Native Method)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-07 18:08:42.559 E/AndroidRuntime( 9894): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

The crash always occurs when react-native-volume-manager is installed, even if it isn't imported anywhere in my JS. Uninstalling the package and rebuilding resolves the crash.

If I create a brand new expo app with SDK 50 and install nothing but react-native-volume-manager, the crash is reproducible. However, it's not reproducible with a brand new app using SDK 51. I'm not able to update my production app to SDK 51 yet, though.

Any ideas?

The package 'react-native-volume-manager' doesn't seem to be linked

Hi team,

My android app is using with following configuration:

  • react-native: "0.69.5"
  • react-native-volume-manager: "^1.10.0"
  • org.jetbrains.kotlin:kotlin-gradle-plugin: "1.6.0"

but when run on android, the error show:

Screenshot 2023-09-08 at 09 12 35

However, it works normally on iOS. How to resolve it ? Although, I tried to down-grade react-native-volume-manager to below version but didn't still work.

Crash on android : Receiver not registered

On firebase I am getting this error for some devices.
Implementation is working for almost all other users.

VolumeManagerModule.unregisterVolumeReceiver

Fatal Exception: java.lang.RuntimeException: Unable to pause activity {com.my.package/com.my.package.MainActivity}: java.lang.IllegalArgumentException: Receiver not registered: com.reactnativevolumemanager.VolumeManagerModule$b@8a8518c
       at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:5396)
       at android.app.ActivityThread.performPauseActivity(ActivityThread.java:5347)
       at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:5294)
       at android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:53)
       at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2466)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:240)
       at android.os.Looper.loop(Looper.java:351)
       at android.app.ActivityThread.main(ActivityThread.java:8380)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
useEffect(() => {
  const volumeListener = VolumeManager.addVolumeListener((result) => {
    console.log(result.volume);
  });

  return function () {
    volumeListener.remove();
  }
}, []);

Any suggestions?

Android: questions about ringerMode listener behavior

Hi,

It seems that the following are happening right now with the ringer mode listener:

  • Ringer mode listener reacts to both ringer mode changes and volume changes
  • Volume listener is unregistered/registered on onHostPause/onHostResume but the ringer listener is not

Just to confirm: are these by design or perhaps considered as bugs?

I personally consider these as somewhat nice features right now, as when I want to react to changes in either volume or ringer mode having just one event listener is enough (although it doesn't pass me e.g. the volume info as volume listener does). Also, when opening the device's full sound settings while my app is active, the ringer mode listener not being unregistered on onHostPause seems to keep events flowing to my app while adjusting the volumes, although I think one cannot really rely on this behavior, I'd assume this to work by luck only right after the app has been moved to the background.

If these are by design and something you want to keep in the library, might be worth mentioning about these in the docs. I can volunteer to tune the docs if need be.

Related to the previous issue I reported (#24), the behavior regarding removeRingerListener() is also a bit surprising, as that doesn't only remove the added event listener but also calls unregisterObserver(), which (as far as I understand correctly), kills the whole functionality and not just that one listener. If this behavior is something to keep, perhaps this would justify also a special mention in the docs.

Upgrade kotlin version for react-native-volume-manager to support kotlin-android-extensions plugin 1.6.20

Description

The Android Gradle plugin requires kotlin-android-extensions Gradle plugin version 1.6.20 or higher. However, the current version of the react-native-volume-manager dependency is using org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10, which does not satisfy the required version. As a result, building the project fails with the following error message:

The Android Gradle plugin supports only kotlin-android-extensions Gradle plugin version 1.6.20 and higher. The following dependencies do not satisfy the required version: project ':react-native-volume-manager' -> org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10.

Solution:

To resolve this issue, we need to upgrade the kotlin version to 1.6.20 or higher in the react-native-volume-manager dependency. This can be achieved by updating the version number of the kotlin-gradle-plugin in the build.gradle file of the react-native-volume-manager module to 1.6.20 or higher.

[Android]Hardware back button doesn't work and keyboard doesn't show on Expo

Thank you for your grate library!! I'm facing the problem on Android. It would be grateful for your assistance.

Symptoms

After adding react-native-volume-manager, the hardware back button doesn't work and keyboard doesn't show up when focusing on a TextInput on Android in the Expo environment. iOS is working fine.

Environment

package.json

"expo": "~48.0.15",
"expo-status-bar": "~1.4.4",
"react": "18.2.0",
"react-native": "0.71.7",
"react-native-volume-manager": "^1.5.0"

Node version

  • v16.16.0

Tested Android version

  • Android 11 (I tested two different devices. Symptoms is same)

How to reproduce

Procedure

# Create Expo project
yarn create expo-app AndroidTest1
cd AndroidTest1

# Add react-native-volume-manager
yarn add react-native-volume-manager

# Change code as below

# Build on EAS Expo (needs setup for Expo)
eas build --profile preview --platform android

Modified code

Modify App.js to add TextInput.

import { StatusBar } from 'expo-status-bar';
import { useState } from 'react';
import { StyleSheet, Text, View, TextInput } from 'react-native';

export default function App() {
  const [sampleText, setSampleText] = useState("This is sample text");
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <TextInput editable={true} value={sampleText} onChangeText={setSampleText} />
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Install and test

  • Download build APK by Expo EAS and install Android real device.
  • After launching App, hardware back button doesn't work.
  • When move focus to the TextInput, keyboard will NOT show up.

Volume listener doesn't work

I've installed the library, ran pod install and added the volume listener, but nothing gets logged out to the console when the system volume changes.
Im running the app on iOS 16.1 in XCode Simulator.

Below is the code for the volume listener.

  useEffect(() => {
    const volumeListener = VolumeManager.addVolumeListener((result) => {
      console.log(result.volume);
      setVolume(result.volume);
    });

    return () => volumeListener.remove();
  }, []);

Android: showNativeVolumeUI stops working after app goes in the background and comes back

I'm hiding the native UI on a section of my app but I found that if I lock the screen and then turn it on again, the native UI starts appearing. I tried hiding it when the app state is active but no luck. FYI, this is only happening on Android. Any ideas?

 useEffect(() => {
   // Hide it as soon as entering the section
    VolumeManager.showNativeVolumeUI({ enabled: false });
  }, []);

  useEffect(() => {
    const listener = AppState.addEventListener('change', (nextAppState) => {
      // Hide it as soon as entering the section
      VolumeManager.showNativeVolumeUI({ enabled: nextAppState !== 'active' });
    });

    return () => {
      listener.remove();
     // Show it when leaving the section
      VolumeManager.showNativeVolumeUI({ enabled: true });
    };
  }, []);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.