Flutter – Как сообщить службе переднего плана, открыто ли приложение или закрыто?IOS

Программируем под IOS
Ответить
Anonymous
 Flutter – Как сообщить службе переднего плана, открыто ли приложение или закрыто?

Сообщение Anonymous »

У меня есть приложение со службой переднего плана, созданной с использованием этого пакета: https://pub.dev/packages/flutter_background_service.
Служба выполняет задачу каждые 10 секунд, но задача должна различаться в зависимости от того, открыто ли приложение. Например: если приложение открыто, служба должна отображать всплывающее уведомление, а если приложение свернуто, закрыто или закрыто, вместо этого должно отображаться уведомление.
На данный момент это лучшее решение. Я обнаружил, что для отслеживания состояния приложения используется WidgetsBindingObserver, а затем вызывается метод вызова службы. Вот мой код:
Состояние виджета:

Код: Выделить всё

class _MyAppState extends State with WidgetsBindingObserver {

var service = FlutterBackgroundService();

@override
void initState() {
super.initState();
service.invoke("setAppOpen");
WidgetsBinding.instance.addObserver(this);
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if(state == AppLifecycleState.paused || state == AppLifecycleState.detached) {
service.invoke("setAppClosed");
} else {
service.invoke("setAppOpen");
}
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
service.invoke("setAppClosed");
super.dispose();
}

@override
Widget build(BuildContext context) {
...
}
}
Сервис:

Код: Выделить всё

Future initialiseService() async {
final service = FlutterBackgroundService();
await service.configure(
iosConfiguration: IosConfiguration(
autoStart: true,
onForeground: onStart,
onBackground: onIosBackground
),
androidConfiguration: AndroidConfiguration(
onStart: onStart,
isForegroundMode: true,
autoStart: true,
autoStartOnBoot: true
)
);
}

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
DartPluginRegistrant.ensureInitialized();

var appOpen = false;

if(service is AndroidServiceInstance) {
service.setForegroundNotificationInfo(title: "Test Service", content: "Test Service");
}

service.on('setAppOpen').listen((event) {
print("set app open");
appOpen = true;
});

service.on('setAppClosed').listen((event) {
print("set app closed");
appOpen = false;
});

Timer.periodic(const Duration(seconds: 10), (timer) async {
if(appOpen) {
Fluttertoast.showToast(
msg: "App Open",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 2,
backgroundColor: Colors.black,
textColor: Colors.white,
fontSize: 16.0,
);
} else {
NotificationManager.showNotification(
notificationId: 1234,
channelId: NotificationManager.channelID,
channelName: NotificationManager.channel,
title: "App Closed",
body: "App Closed",
payload: ""
);
}
});
}

@pragma('vm:entry-point')
Future onIosBackground(ServiceInstance service) async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
return true;
}
В основном это работает, за исключением случая на Android, где приложение очищается от недавних задач и выдает ошибку при вызове service.invoke() "invokeMethodUIThread: попыталась вызвать метод на закрытый канал: OnDetachedFromEngine". Служба продолжает считать, что приложение открыто, и пытается показать всплывающее уведомление, а не уведомление.
Есть ли другой способ вызвать сообщение вызова, когда приложение отключено? А если нет, есть ли лучший способ сообщить службе о закрытии приложения?

Подробнее здесь: https://stackoverflow.com/questions/793 ... -or-closed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»