doublesymmetry / react-native-track-player

A fully fledged audio module created for music apps. Provides audio playback, external media controls, background mode and more!
https://rntp.dev/
Apache License 2.0
3.3k stars 1.01k forks source link

Android users complaining the the app start on its own #635

Closed The0racle closed 3 years ago

The0racle commented 5 years ago

Configuration

Run react-native info in your project and share the content.

Environment:
  OS: macOS 10.14.5
  Node: 6.9.4
  Yarn: 1.6.0
  npm: 6.1.0
  Watchman: 4.7.0
  Xcode: Xcode 10.1 Build version 10B61
  Android Studio: 3.1 AI-173.4907809

Packages: (wanted => installed)
  react: ^16.3.0-alpha.1 => 16.3.0
  react-native: 0.54.4 => 0.54.4

What react-native-track-player version are you using? 1.1.4

This issue is happening on Android (we only have an Android app) to users running Android 6 -7.0. They complain that even after closing the app, it is launched again in the future when they're doing something else on their phones. See below:

1. I use a Droid Turbo 2 running on version 7. (I know it's pretty old in tech years)
2. I used the back button and swipe to close, the app popped back up after both. Force stop stopped the app from opening but any time I re-opened the app I would have to force stop it afterward.
3. I closed it on both the home page and in the player. The Player was paused when the app was closed.
Yes, I'm sorry I didn't respond earlier. I am very busy with school. It is still not closing. I have an 
Android Blu R1HD. The version is 6.0 (I guess it's old :). I have tried closing it by swiping it out. I
 have even uninstalled it and reinstalled it. I can close it while on the home page or taking my 
daily quiz and it still opens back up on its own. It looks like it will not reopen on its own if I go into
 settings and force stop it but obviously I'm not going to do that every time, I'll just leave it open.
I have am LG style...at first i would be in the middle of using the app amd i would 
answer a call or exit out to go do something and it would pop up so I would stop 
the video and then use the back button but then it would pop up again so 
i would exit out...it would happen again so I would clear the history and 
make sure it wasnt still up on the dash board but nothing has worked....
this morning u said to log out and so I did but now its popping up with the log in page

Code

LockScreenControls gets called multiple times, every time Player component is rendered.

export default class LockScreenControls extends Component<Props> {
  static defaultProps = {
    currentFactTitle: null,
    currentItemTitle: '',
    imagePath: '',
    track: null,
    playing: false,
    currentTime: 0,
    duration: 0,
    audioLoading: false,
  }

  listeners: Array<Object>;

  componentDidMount() {
    const controls = this._remoteControls(this.props.track !== null);
    TrackPlayer.updateOptions({
      stopWithApp: true,
      capabilities: controls,
      notificationCapabilities: controls,
      compactCapabilities: controls,
    });
    this._registerForRemoteControlEvents();
    const trackId = this.props.audioMode;
    if (trackId) {
      this._updateMetadata({ trackId });
    }
  }

  componentWillUnmount() {
    this.listeners.map(listener => listener.remove());
    TrackPlayer.destroy();
  }

  componentDidUpdate(prevProps: Props) {
    if ((prevProps.currentItemTitle !== this.props.currentItemTitle) || (prevProps.currentFactTitle !== this.props.currentFactTitle)) {
      const trackId = this.props.audioMode;
      if (trackId) {
        this._updateMetadata({ trackId });
      }
    }
  }

  _updateMetadata = async (options: { trackId: string }) => {
    try {
      const track = await TrackPlayer.getTrack(options.trackId);
      if (track) {
        TrackPlayer.updateMetadataForTrack(options.trackId, {
          title: this.props.currentItemTitle,
          artwork: this.props.imagePath,
          artist: this.props.currentFactTitle,
          duration: this.props.duration,
          track: this.props.track,
        });
      }
    } catch (_) {}
  }

  shouldComponentUpdate(nextProps: Props) {
    return (nextProps.currentItemTitle !== this.props.currentItemTitle) || (nextProps.currentFactTitle !== this.props.currentFactTitle);
  }

  _remoteControls = (hasTrack) => {
    const controls = [
      TrackPlayer.CAPABILITY_PLAY,
      TrackPlayer.CAPABILITY_PAUSE,
      TrackPlayer.CAPABILITY_JUMP_FORWARD,
      TrackPlayer.CAPABILITY_JUMP_BACKWARD,
    ];
    if (hasTrack) {
      return [
        ...controls,
        TrackPlayer.CAPABILITY_SKIP_TO_NEXT,
        TrackPlayer.CAPABILITY_SKIP_TO_PREVIOUS,
      ];
    }

    return controls;
  }

  _registerForRemoteControlEvents() {
    this.listeners = [
      TrackPlayer.addEventListener('remote-jump-forward', () => this.props.onPressSkipForward(skipTime)),
      TrackPlayer.addEventListener('remote-jump-backward', () => this.props.onPressSkipBackward(skipTime)),
      TrackPlayer.addEventListener('remote-next', this.props.onPressNextTrack),
      TrackPlayer.addEventListener('remote-previous', this.props.onPressPreviousTrack),
    ];
  }

  render() {
    return null;
  }
}

TrackService

// @flow
import TrackPlayer from 'react-native-track-player';

module.exports = async function () {
  // This service needs to be registered for the module to work
  // but it will be used later in the "Receiving Events" section
  TrackPlayer.addEventListener('remote-play', () => {
    TrackPlayer.play();
  });

  TrackPlayer.addEventListener('remote-pause', () => {
    TrackPlayer.pause();
  });

  TrackPlayer.addEventListener('remote-next', () => {
    TrackPlayer.skipToNext();
  });

  TrackPlayer.addEventListener('remote-previous', () => {
    TrackPlayer.skipToPrevious();
  });

  TrackPlayer.addEventListener('remote-stop', () => {
    TrackPlayer.destroy();
  });
};

and in index.js

TrackPlayer.setupPlayer();
TrackPlayer.registerPlaybackService(() => require('./app/includes/TrackService.js'));

Can anyone point me in the right direction if I'm doing something wrong? I suspect it might have something to do with #433.

mimamuh commented 5 years ago

I got a similar behaviour on the android simulator (Nexus_5X - API_24) on version 1.1.4. It does not open the app but stopWithApp: true does not work: When I swipe out the app it still plays the show. Not always: For example when I rebuild the app freshly, it works the first time. But when I reopen the app and play the show again and swipe the app out again, it keeps on playing.

Am I understand right that stopWithApp: true means the player will stop when I swipe it out? That is the actual behaviour? Or does it mean it should stop when the app goes to the background?

Anyway: I can't stop the player with a swipe-out after I swiped it out the first – it keeps on playing and only one way stops the player then: Going via settings -> apps -> MyApp -> force stop.

The0racle commented 5 years ago

Your issue seems related to #433.

mimamuh commented 5 years ago

@The0racle Thx for the hint. I tried the workaround of this issue but it doesn't change anything. But you are right: After testing it the #433 issue is also happending in my app but it seems to be independent of the issue of not stopping playing.