react-native-track-player: Issues with Samsung Galaxy devices (NullPointerException in MusicBinder, MusicModule IllegaStatelException)
Describe the bug
Dear,
I can’t very much describe the bug, I just see a lot of crashes happening with mostly Samsung Galaxy (around 70% of the devices are Samsung Galaxy) and some Xiaomi’s. I noticed two crashes that are very common in my app.
Mainly:
java.lang.NullPointerException:
at com.guichaguri.trackplayer.service.MusicBinder.post (MusicBinder.java:22)
at com.guichaguri.trackplayer.module.MusicModule.waitForConnection (MusicModule.java:94)
at com.guichaguri.trackplayer.module.MusicModule.stop (MusicModule.java:334)
at java.lang.reflect.Method.invoke (Native Method)
at com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
at com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:151)
at com.facebook.react.bridge.queue.NativeRunnable.run (Native Method)
at android.os.Handler.handleCallback (Handler.java:938)
at android.os.Handler.dispatchMessage (Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
at android.os.Looper.loop (Looper.java:246)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:226)
at java.lang.Thread.run (Thread.java:923)
This is the most common crash. The other one that is most common is:
java.lang.IllegalStateException:
at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1795)
at android.app.ContextImpl.startService (ContextImpl.java:1740)
at android.content.ContextWrapper.startService (ContextWrapper.java:738)
at android.content.ContextWrapper.startService (ContextWrapper.java:738)
at com.guichaguri.trackplayer.module.MusicModule.waitForConnection (MusicModule.java:106)
at com.guichaguri.trackplayer.module.MusicModule.add (MusicModule.java:195)
at java.lang.reflect.Method.invoke (Native Method)
at com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
at com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:151)
at com.facebook.react.bridge.queue.NativeRunnable.run (Native Method)
at android.os.Handler.handleCallback (Handler.java:938)
at android.os.Handler.dispatchMessage (Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
at android.os.Looper.loop (Looper.java:246)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:226)
at java.lang.Thread.run (Thread.java:923)
To Reproduce I have no clue how to reproduce it. I never experienced the problem myself.
Environment (please complete the following information):
Run react-native info in your project and share the content.
What react-native-track-player version are you using?
Version 1.2.7
Are you testing on a real device or in the simulator? Which OS version are you running? Real devices. I see these crashes in Play Console, mostly reported on Android 11 and Android 10.
Code In Home.js (mainscreen)
const setup = async () => {
await TrackPlayer.setupPlayer({});
await TrackPlayer.updateOptions({
stopWithApp: true,
capabilities: [
TrackPlayer.CAPABILITY_PLAY,
TrackPlayer.CAPABILITY_PAUSE,
TrackPlayer.CAPABILITY_STOP
],
compactCapabilities: [
TrackPlayer.CAPABILITY_PLAY,
TrackPlayer.CAPABILITY_PAUSE,
TrackPlayer.CAPABILITY_STOP
],
})};
setup();
The Player.js (player)
async InitTrackPlayer() {
this.setState({paused: false});
const { navigation } = this.props;
const streamID = navigation.getParam('streamID', 'NO-ID');
fetch(`https://xxx.xxx.xxx/getinfoviajson.php?streamID=${streamID}`, {
method: "POST",
})
.then(response => response.json())
.then(responseJson => {
this.setState({
streamName: responseJson.streamName,
desc: responseJson.streamDesc_app,
mountpoint: responseJson.mountpoint,
fullStreamURL: responseJson.fullStreamURL,
imageURL: responseJson.imageURL,
phone_app: responseJson.phone_app,
phone_app_plus: responseJson.phone_app_plus,
streamURLJSON: responseJson.streamURL,
});
var streambyJSON = this.state.streamURLJSON
const start = async () => {
// Add a track to the queue
await TrackPlayer.add({
id: `${streamID}`,
url: streambyJSON,
artist: '',
title: '',
artwork: '',
});
};
start();
});
};
The snippet to update the metadata
async trackupdate() {
const trackId = await TrackPlayer.getCurrentTrack();
await TrackPlayer.updateMetadataForTrack(trackId, {
title: this.state.nowPlaying,
artist: this.state.streamName,
artwork: this.state.imageURL,
});
}
The snippet that actions to certain statusses (set the correct button or reset the stream when the new stream mountpoint is not the same as the stream of a previous mountpoint)
async getPlayerStatus() {
const { navigation } = this.props;
const streamID = navigation.getParam('streamID', 'NO-ID');
let state = await TrackPlayer.getState();
let thisIsPlaying = await TrackPlayer.getCurrentTrack();
if (state == 'playing') {
this.setState({DoesPlay: true});
}
if (state == 'idle') {
this.setState({DoesPlay: false});
}
if (state == 'ready') {
this.setState({DoesPlay: false});
}
if (state == '1') {
this.setState({DoesPlay: false});
}
if (state == '2') {
this.setState({DoesPlay: false});
}
if (state == '3') {
this.setState({DoesPlay: true});
}
if (thisIsPlaying != streamID) {
var statePlayer = this.state.DoesPlay;
this.setState({DoesPlay: false});
// alert(statePlayer);
// alert (state);
if (Platform.OS === 'ios') {
await TrackPlayer.stop();
}
else {
const { navigation } = this.props;
const streamID = navigation.getParam('streamID', 'NO-ID');
await TrackPlayer.reset();
}
}
}
componentDidMount and componentWillUnmount
componentDidMount() {
this.getPlayerStatus();
this.setState({paused: false});
const { navigation } = this.props;
this.InitTrackPlayer();
this.trackupdate();
TrackPlayer.addEventListener('remote-play', () => {
TrackPlayer.play();
});
TrackPlayer.addEventListener('remote-pause', () => {
this.PauseClick();
});
TrackPlayer.addEventListener('remote-duck', () => {
TrackPlayer.stop();
this.setState({DoesPlay: false});
this.InitTrackPlayer();
});
TrackPlayer.addEventListener('remote-stop', () => {
TrackPlayer.stop();
});
}
componentWillUnmount() {
}
Any idea’s what causes this problem? Thanks guys!
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 22 (6 by maintainers)
I’ve migrated an app from 1.x to 2.0.3 and this happens every time the app starts on Andriod.
We’re rewriting our Android module and making the binder/service/notification parts more stable and robust as part of https://github.com/DoubleSymmetry/react-native-track-player/discussions/1264
We expect this issue to be fixed as part of that effort. We’re aiming to have the first pre-release soon.