Reputation: 960
AudioService.play();
throws an error :
java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object, io.flutter.plugin.common.MethodChannel$Result)' on a null object reference, null, null, null)
Debug stop :
onPressed: () async {
if (playing) {
// AudioService.pause();
} else {
AudioService.play();
}
},
background_audio.dart
import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
import 'package:neodiom/api/_queue.dart' as player;
import 'package:neodiom/models/_Track.dart';
// Must be a top-level function
// void _entrypoint() => AudioServiceBackground.run(() => AudioPlayerTask());
class AudioPlayerTask extends BackgroundAudioTask {
// the Audio player works fine itself and the problem is not related to it
final _player = player.queue.player; // just_audio player
// Implement callbacks here. e.g. onStart, onStop, onPlay, onPause
onPlay() => _player.play();
onPause() => _player.pause();
onSeekTo(Duration duration) => _player.seek(duration);
onSetSpeed(double speed) => _player.setSpeed(speed);
onStop() async {
// Stop and dispose of the player.
await _player.dispose();
// Shut down the background task.
await super.onStop();
}
onStart(Map<String, dynamic> params) async {
print(" **** Starting AudioPlayerTask ...");
// Tell the UI and media notification what we're playing.
Track t = player.Samples.tracks[0];
MediaItem m =
MediaItem(id: t.getTrack, album: t.album['title'], title: t.title);
AudioServiceBackground.setMediaItem(m);
_player.currentIndexStream.listen((index) {
AudioServiceBackground.setMediaItem(player.queue.currentTrackMediaItem);
});
// Listen to state changes on the player...
_player.playerStateStream.listen((playerState) {
// ... and forward them to all audio_service clients.
AudioServiceBackground.setState(
playing: playerState.playing,
// Every state from the audio player gets mapped onto an audio_service state.
processingState: {
ProcessingState.loading: AudioProcessingState.connecting,
ProcessingState.buffering: AudioProcessingState.buffering,
ProcessingState.ready: AudioProcessingState.ready,
ProcessingState.completed: AudioProcessingState.completed,
}[playerState.processingState],
// Tell clients what buttons/controls should be enabled in the
// current state.
controls: [
playerState.playing ? MediaControl.pause : MediaControl.play,
MediaControl.stop,
],
);
});
}
}
entrypoint
void _entrypoint() => AudioServiceBackground.run(() => AudioPlayerTask());
main.dart / Service initializer (during App initState)
void initBackgroundAudioService() async {
try {
await AudioService.connect();
await AudioService.start(
backgroundTaskEntrypoint: _entrypoint,
androidNotificationChannelName: 'Audio Service Demo',
// Enable this if you want the Android service to exit the foreground state on pause.
//androidStopForegroundOnPause: true,
androidNotificationColor: 0xFF2196f3,
androidNotificationIcon: 'mipmap/ic_launcher',
androidEnableQueue: true,
);
} catch (e) {
print("** Error on start : $e");
}
}
Upvotes: 0
Views: 1106
Reputation: 960
I just had to follow the OS Setups (Android setup instruction in my case) according to the bellow recipe from the documentation
- Edit your project's
AndroidManifest.xml
file to declare the permission to create a wake lock, and add component entries for the<service>
and<receiver>
:
<manifest ...>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application ...>
...
<service android:name="com.ryanheise.audioservice.AudioService">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
</manifest>
- Starting from Flutter 1.12, you will need to disable the shrinkResources setting in your android/app/build.gradle file, otherwise the icon resources used in the Android notification will be removed during the build:
android {
compileSdkVersion 28
...
buildTypes {
release {
signingConfig ...
shrinkResources false // ADD THIS LINE
}
}
}
Upvotes: 1