hirbod / react-native-volume-manager

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)
MIT License
216 stars 14 forks source link

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

Open matiastucci opened 3 months ago

matiastucci commented 3 months ago

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 });
    };
  }, []);
matiastucci commented 3 months ago

Another thing I noticed is that after setting showNativeVolumeUI to true, setting it to false doesn't work anymore.

E.g:

useEffect(() => {
  VolumeManager.showNativeVolumeUI({ enabled: true });

  setTimeout(() => {
    // doesn't work :(
    VolumeManager.showNativeVolumeUI({ enabled: false });
  }, 10000);
}, []);

but setting it to false and then true works fine.

Any ideas? Thanks!

Kieraano commented 3 months ago

I'm getting the same issue on iOS.

Once I call: VolumeManager.showNativeVolumeUI({ enabled: true });

Calling this doesn't work as you would expect: VolumeManager.showNativeVolumeUI({ enabled: false });

Basically once you hide the native volume UI you can't bring it back.

hirbod commented 3 months ago

There might be a logic issue here

I have to check this once I have a bit more time.

if (!flag && [strongSelf->customVolumeView superview]) {
  [strongSelf->customVolumeView removeFromSuperview];
} else if (flag && ![strongSelf->customVolumeView superview]) {
  // Potentially adjust the frame as needed, not necessarily CGRectZero
  strongSelf->customVolumeView.frame = CGRectMake(0, 0, 0, 0);
  UIViewController *topViewController = [strongSelf topMostViewController];
  [topViewController.view addSubview:strongSelf->customVolumeView];
}

might do the trick but I am not 100% sure yet.

Kieraano commented 3 months ago

The below code change fixed the issue for me on iOS.

On reflection, this is likely a different issue to what matiastucci experienced.


    if (flag) {
      // To show the native volume UI, ensure our customVolumeView is removed from its superview
      if ([strongSelf->customVolumeView superview]) {
        [strongSelf->customVolumeView removeFromSuperview];
      }
    } else {
      // To hide the native volume UI, add our customVolumeView offscreen if it's not already added
      if (![strongSelf->customVolumeView superview]) {
        // Ensure the customVolumeView is offscreen and not interfering visually
        strongSelf->customVolumeView.frame = CGRectMake(0, 0, 0, 0); // Set the frame to CGRectZero

        // Find the topMostViewController to add the customVolumeView to its view hierarchy
        UIViewController *topViewController = [strongSelf topMostViewController];
        if (topViewController) {
          [topViewController.view addSubview:strongSelf->customVolumeView];
        }
      }
    }`
hirbod commented 3 months ago

@Kieraano yes, @matiastucci issue is related to Android. I have some ideas. I will also verify your suggestion and create some more test cases and release a new version pretty soon

rajdivergenceneuro commented 2 months ago

Related issue(iOS)

Step to produce

hirbod commented 2 months ago

I don't think its possible to hide the volume toast when the app is backgrounded.

rajdivergenceneuro commented 2 months ago

I don't think its possible to hide the volume toast when the app is backgrounded.

Ok, Thanks for quick reply!