I am currently working on a Flutter application that utilizes the flutter_background_service package for running background services. To implement the background service, I have integrated the flutter_background_service_android package. However, I am encountering an issue where the background service is not working as expected on Android devices.
The error message I am getting is:
flutter_background_service_android threw an error: Exception: This class should only be used in the main isolate (UI App). The app may not function as expected until you remove this plugin from pubspec.yaml
following is the code for my background service (my_background_service.dart)
// ignore_for_file: avoid_print
import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_background_service_android/flutter_background_service_android.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '/helper/my_helper/socket_io_helper.dart';
import '/helper/my_helper/my_get_di.dart' as my_di;
/// Initialization of the Background Service
Future<void> initializeBackgroundService() async {
final service = FlutterBackgroundService();
/// OPTIONAL, using custom notification channel id
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'my_foreground',
'MY FOREGROUND SERVICE',
description: 'This channel is used for important notifications.',
importance: Importance.low,
);
/// Object of the FlutterLocalNotificationsPlugin
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
/// Initialize settings
if (Platform.isIOS || Platform.isAndroid) {
await flutterLocalNotificationsPlugin.initialize(
const InitializationSettings(
iOS: DarwinInitializationSettings(),
android: AndroidInitializationSettings('ic_bg_service_small'),
),
);
}
/// Create android notification channel
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Configuration of the Background Service
await service.configure(
androidConfiguration: AndroidConfiguration(
onStart: onStart,
autoStart: true,
isForegroundMode: true,
notificationChannelId: 'my_foreground',
initialNotificationTitle: 'AWESOME SERVICE',
initialNotificationContent: 'Initializing',
foregroundServiceNotificationId: 888,
),
iosConfiguration: IosConfiguration(
autoStart: true,
onForeground: onStart,
onBackground: onIosBackground,
),
);
/// Starting the background service after doing the configurations
service.startService();
}
// DOLATER: Handle the iOS Background Task Here
@pragma('vm:entry-point')
Future<bool> onIosBackground(ServiceInstance service) async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
return true;
}
@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
DartPluginRegistrant.ensureInitialized();
/// OPTIONAL when use custom notification
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
if (service is AndroidServiceInstance) {
service.on('setAsForeground').listen((event) {
service.setAsForegroundService();
});
service.on('setAsBackground').listen((event) {
service.setAsBackgroundService();
});
}
service.on('stopService').listen((event) {
service.stopSelf();
});
/// My instances
SocketIoHelper socketIoHelper = SocketIoHelper();
/// Executed when the app is in the foreground
service.on('loginSuccess').listen((event) async {
/// Creating a socket.io client
await my_di.init();
await socketIoHelper.initializeAwesomeNotification();
await socketIoHelper.initializeMsgService();
await socketIoHelper.createTopics();
});
service.on('containsTheTopics').listen((event) async {
await socketIoHelper.joinCallInitializationTopic();
await socketIoHelper.listenCallInitializationTopic();
await socketIoHelper.listenCallRecieveTopic();
});
/// Executed when the app is in the background
final prefs = await SharedPreferences.getInstance();
final plusRemovedPhoneNumberFromLocal =
prefs.getString("plusRemovedPhoneNumber") ?? "";
/// Creating a socket.io client
if (plusRemovedPhoneNumberFromLocal != "") {
await my_di.init();
await socketIoHelper.initializeAwesomeNotification();
await socketIoHelper.initializeMsgService();
await socketIoHelper.joinCallInitializationTopic();
await socketIoHelper.listenCallInitializationTopic();
await socketIoHelper.listenCallRecieveTopic();
}
/// Update the background service timer
/// And show it as a foreground notification
Timer.periodic(const Duration(seconds: 1), (timer) async {
if (service is AndroidServiceInstance) {
if (await service.isForegroundService()) {
flutterLocalNotificationsPlugin.show(
888,
'COOL SERVICE',
'Awesome ${DateTime.now()}',
const NotificationDetails(
android: AndroidNotificationDetails(
'my_foreground',
'MY FOREGROUND SERVICE',
icon: 'ic_bg_service_small',
ongoing: true,
),
),
);
/// if you don't using custom notification, uncomment this
service.setForegroundNotificationInfo(
title: "My Service",
content: "",
);
}
}
/// Printing background service timer in the flutter terminal
print(
" Background Service ====> ${DateFormat('yyyy-MM-dd hh:mm:ss').format(DateTime.now())} ");
});
}