react-native-audio-streaming
react-native-audio-streaming copied to clipboard
[ANDROID] App Crashing In Combination with React Native Navigation
I am getting an error on Android (Google Pixel SDK25 8.0.0) when I run an app app that has React Native Navigation in combination with React Native Audio Streaming.
I get the following error:
09-30 16:41:40.535 3828-3828/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.xm, PID: 3828 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference at com.audioStreaming.ReactNativeAudioStreamingModule.getClassActivity(ReactNativeAudioStreamingModule.java:43) at com.audioStreaming.Signal.setData(Signal.java:66) at com.audioStreaming.ReactNativeAudioStreamingModule.onServiceConnected(ReactNativeAudioStreamingModule.java:78) at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1453) at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1481) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
The MainApplication.java is build up like this:
` package com.xm;
import android.app.Application;
import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; import com.facebook.soloader.SoLoader; import com.reactnativenavigation.NavigationApplication; import com.audioStreaming.ReactNativeAudioStreamingPackage;
import java.util.Arrays; import java.util.List;
public class MainApplication extends NavigationApplication {
@Override
public boolean isDebug() {
// Make sure you are using BuildConfig from your own application
return BuildConfig.DEBUG;
}
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new ReactNativeAudioStreamingPackage()
);
}
@Override
public List<ReactPackage> createAdditionalReactPackages() {
return getPackages();
}
} `
When I remove the line new ReactNativeAudioStreamingPackage()
the app will work. What am i doing wrong here or how can i fix it?
I am getting this issue too. :( Is there any fixes for this?
i also get the same problem. I have solve it by
android/src/main/java/com/audioStreaming/ReactNativeAudioStreamingModule.java
public Class<?> getClassActivity() {
- if (this.clsActivity == null) {
- this.clsActivity = getCurrentActivity().getClass();
+ Activity activity = getCurrentActivity();
+ if (this.clsActivity == null && activity != null) {
+ this.clsActivity = activity.getClass();
}
return this.clsActivity;
}
I have same issue , anyone solved it ?
@JayricMok: I solved my problem by applying the fixed code from from @BunHouth in;
android/src/main/java/com/audioStreaming/ReactNativeAudioStreamingModule.java
public Class<?> getClassActivity() {
- if (this.clsActivity == null) {
- this.clsActivity = getCurrentActivity().getClass();
+ Activity activity = getCurrentActivity();
+ if (this.clsActivity == null && activity != null) {
+ this.clsActivity = activity.getClass();
}
return this.clsActivity;
}
But this breaks control panel on notification.
@mrsydster @BunHouth I applied , still having same issue
@JayricMok can you show me your issue.
@BunHouth i facing this issue https://github.com/tlenclos/react-native-audio-streaming/issues/122
@JayricMok Are you also using wix-react-native-navigation ? if you not using react-native-navigation it should be work without any error. is your project is available on github?.
@BunHouth i using react-navigation https://reactnavigation.org/docs/intro/
@JayricMok it should not problem with that navigation. can you show me your error?
@bdavid68 @JayricMok: Ahh the reason I am not getting that issue is because I disabled the notification from Audio Streaming. I am using Music Control instead for the notification control.
@mrsydster can you explain more about how you mix the music control with audio streaming ?
I use Audio Streaming for steaming the audio (obviously) and than I replaced the notifications control with Music Control. This is my code for the player:
/** @flow */
import React from 'react';
import Reflux from 'reflux';
import {
Image,
StyleSheet,
ActivityIndicator,
View,
Text,
DeviceEventEmitter,
TouchableOpacity,
Platform,
} from 'react-native';
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
import { ReactNativeAudioStreaming } from 'react-native-audio-streaming';
import MusicControl from 'react-native-music-control';
export default class Player extends Reflux.Component {
_onPress: Function;
_initializeMusicControl: Function;
_updateMusicControlTitle: Function;
_updateMusicControlState: Function;
_playerStop: Function;
_playerStart: Function;
subscription: Object;
constructor(props: Object) {
super(props);
this.state = {
streamUrl: "[INSERT YOUR STREAMING URL HERE]",
status: "STOPPED",
artist: "",
song: "",
onair: "",
};
this._onPress = this._onPress.bind(this);
}
componentDidMount() {
this.subscription = DeviceEventEmitter.addListener(
'AudioBridgeEvent', (evt) => {
// We just want meta update for song name
if (evt.status === "METADATA_UPDATED" && evt.key === 'StreamTitle') {
this.setState({
onair: evt.value,
artist: evt.value.split(' - ')[0],
song: evt.value.split(' - ')[1],
});
} else if (evt.status != "METADATA_UPDATED") {
this.setState(evt);
}
}
);
ReactNativeAudioStreaming.getStatus((error, msg) => {
(error) ? console.log(error) : this.setState({status: msg.status})
});
this._initializeMusicControl();
}
_initializeMusicControl() {
MusicControl.enableBackgroundMode(true)
MusicControl.enableControl('closeNotification', true, {when: 'never'})
MusicControl.on('play', this._playerStart.bind(this))
MusicControl.on('pause', this._playerStop.bind(this))
this._updateMusicControlTitle(true)
this._updateMusicControlState()
}
_updateMusicControlTitle(initial) {
// Android does not support changing title via MusicControl.updatePlayback,
// so we need to send all information via setNowPlaying every time.
if (Platform.OS === 'android' || initial) {
MusicControl.setNowPlaying({
artist: this.state.artist,
title: this.state.song,
artwork: Platform.select({
// https://github.com/tanguyantoine/react-native-music-control/issues/46
ios: resolveAssetSource(require('../images/artwork.png')).uri,
android: require('../images/artwork.png'),
}),
// iOS determines playback state depending on 'speed', so we need to set
// it in the initial setNowPlaying for correct initial state to be set.
speed: this._musicControlState() == MusicControl.STATE_STOPPED ? 0 : 1,
});
} else {
MusicControl.updatePlayback({
artist: this.state.artist,
title: this.state.song,
});
}
}
_musicControlState() {
switch (this.state.status) {
case "PLAYING":
case "STREAMING":
return MusicControl.STATE_PLAYING;
case "BUFFERING":
return MusicControl.STATE_BUFFERING;
}
return MusicControl.STATE_STOPPED;
}
_updateMusicControlState() {
state = this._musicControlState();
if (state == MusicControl.STATE_STOPPED) {
MusicControl.enableControl('play', true);
MusicControl.enableControl('pause', false);
} else {
MusicControl.enableControl('play', false);
MusicControl.enableControl('pause', true);
}
MusicControl.updatePlayback({state: state});
}
componentDidUpdate(prevProps: Object, prevState: Object) {
if (prevState.song != this.state.song) {
this._updateMusicControlTitle(false);
}
if (prevState.status != this.state.status) {
this._updateMusicControlState();
}
}
componentWillUnmount() {
this.subscription.remove();
MusicControl.resetNowPlaying();
ReactNativeAudioStreaming.stop();
}
_playerStart() {
ReactNativeAudioStreaming.play(this.state.streamUrl, { showIniOSMediaCenter: false, showInAndroidNotifications: false});
}
_playerStop() {
ReactNativeAudioStreaming.stop();
}
_onPress() {
switch (this.state.status) {
case "PAUSED":
ReactNativeAudioStreaming.resume();
break;
case "STOPPED":
case "ERROR":
this._playerStart();
break;
case "PLAYING":
case "STREAMING":
case "BUFFERING":
this._playerStop();
break;
}
}
render() {
return (
<View style={styles.controlElements}>
<PlayingBlock styleBlock={styles.nowBlock}
styleTitle={styles.nowTitle}
styleSubTitle={styles.nowSubTitle}
title="Now playing:"
text={this.state.onair}/>
<TouchableOpacity onPress={this._onPress}>
<PlayButton status={this.state.status}/>
</TouchableOpacity>
</View>
)
}
}
class PlayingBlock extends React.Component {
render() {
var title = " ";
var text = " ";
if (this.props.text) {
title = this.props.title;
text = this.props.text;
}
return (
<View style={this.props.styleBlock}>
<Text style={this.props.styleTitle} numberOfLines={2}>
{title}
</Text>
<Text style={this.props.styleSubTitle} numberOfLines={2}>
{text}
</Text>
</View>
);
}
}
class PlayButton extends React.Component {
render() {
var button;
switch (this.props.status) {
case "PLAYING":
case "STREAMING":
button = <Image style={styles.playButton}
source={require('../images/pause.png')}/>;
break;
case "PAUSED":
case "STOPPED":
case "ERROR":
button = <Image style={styles.playButton}
source={require('../images/play.png')}/>;
break;
case "BUFFERING":
case "BUFFERING_START":
case "START_PREPARING":
button = <ActivityIndicator
animating={true} style={styles.playButton}/>;
break;
}
return button
}
}
const styles = StyleSheet.create({
controlElements: {
alignItems: 'center',
justifyContent: 'space-between',
flexDirection: 'column',
},
playButton: {
width: 22,
height: 29,
margin: 40,
},
nowBlock: {
alignItems: 'center',
},
nowTitle: {
fontSize: 15,
paddingBottom: 5,
color: '#00418c',
fontFamily: 'FiraSans-BoldItalic'
},
nowSubTitle: {
fontSize: 24,
color: '#00418c',
textAlign: 'center',
fontFamily: 'FiraSans-BoldItalic'
},
});
@SydneyTR where to put your code ? put it inside react-native-audio-streaming
folder ?
@JayricMok: No this is just a component I wrote for the app, this can go into one of your screens, on which you want to display your player
@SydneyTR now im using this modules Player
, maybe i should try your Player
, will let you know how, thanks btw.
@SydneyTR in your _playerStart
function i have to set the showIniOSMediaCenter
and showInAndroidNotifications
to true, if not when i click play app will crash
@SydneyTR how you disabled the notification from Audio Streaming ?