When I login the app then clear the app from the background it occurs a problem and show me that "APPNAME keeps crashing". When i try it on my phone it doesn't happen just on some of phones and in emulators.
I tried detect the exact problem with firebase crashlytics but unfortunately i can't see anything. How can i fix the problem?
xmpp_service.dart
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:app/config.dart';
import 'package:app/services/rest.dart';
import 'package:app/view-models/command_controller.dart';
import 'package:xmpp_plugin/ennums/xmpp_connection_state.dart';
import 'package:xmpp_plugin/error_response_event.dart';
import 'package:xmpp_plugin/models/chat_state_model.dart';
import 'package:xmpp_plugin/models/connection_event.dart';
import 'package:xmpp_plugin/models/message_model.dart';
import 'package:xmpp_plugin/models/present_mode.dart';
import 'package:xmpp_plugin/success_response_event.dart';
import 'package:xmpp_plugin/xmpp_plugin.dart';
extension ConnectionStateToString on XmppConnectionState {
String toConnectionName() {
return toString().split('.').last;
}
}
class XmppHelper implements DataChangeEvents {
late XmppConnection flutterXmpp;
late Timer timer;
AppLifecycleState appLifecycleState = AppLifecycleState.resumed;
bool isLogged = false;
final CommandController _commandController = Get.find();
String host = host;
String appBotJid = BOT_JID;
String connectionStatus = "disconnected";
String userJid = "";
String password = "";
XmppHelper() {
timer = Timer.periodic(const Duration(seconds: 10), (Timer t) async {
if (connectionStatus == "authenticated" &&
appLifecycleState == AppLifecycleState.resumed) {
await ping();
}
});
}
Future<void> connect(String userJid, String password) async {
final Map auth = {
"user_jid":
"$userJid/${Platform.isAndroid ? "Android" : "iOS"}${DateTime.now().millisecondsSinceEpoch}",
"password": password,
"host": host,
"port": '5222',
"requireSSLConnection": true,
"autoDeliveryReceipt": true,
"useStreamManagement": true,
"automaticReconnection": true,
};
this.userJid = userJid;
this.password = password;
flutterXmpp = XmppConnection(auth);
await flutterXmpp.start(_onError);
await flutterXmpp.login();
}
void createRoster(String roster) {
flutterXmpp.createRoster(roster);
}
void _onError(Object error) {}
@override
void onChatMessage(MessageChat messageChat) {}
@override
void onNormalMessage(MessageChat messageChat) {
if (messageChat.body == "") {
return;
}
_commandController.messageHandler(messageChat.body!);
}
@override
void onChatStateChange(ChatState chatState) {}
@override
void onConnectionEvents(ConnectionEvent connectionEvent) {
connectionStatus = connectionEvent.type!.toConnectionName();
debugPrint("connStatus: $connectionStatus");
if (connectionStatus == "authenticated") {
isLogged = true;
login();
} else if (connectionStatus == "failed") {
} else if (connectionStatus == "disconnected") {
} else if (connectionStatus == "connected") {}
}
@override
void onGroupMessage(MessageChat messageChat) {}
@override
void onPresenceChange(PresentModel message) {}
@override
void onSuccessEvent(SuccessResponseEvent successResponseEvent) {}
@override
void onXmppError(ErrorResponseEvent errorResponseEvent) {}
void sendMessage(Map commandData) {
int time = DateTime.now().millisecondsSinceEpoch;
commandData["gonderen"] = userJid.toString().split("@")[0];
debugPrint("commandData: $commandData");
flutterXmpp.sendMessageWithType(
appBotJid, jsonEncode(commandData), "$time", time);
}
Future<void> stop() async => await flutterXmpp.stop();
Future<void> xmppLogout() async => await flutterXmpp.logout();
}
layout.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:app/view-models/command_controller.dart';
import 'package:app/widgets/side_menu.dart';
import 'package:xmpp_plugin/xmpp_plugin.dart';
import 'package:app/globals.dart' as globals;
class Layout extends StatefulWidget implements PreferredSizeWidget {
const Layout({super.key});
@override
State<Layout> createState() => _LayoutState();
@override
Size get preferredSize => const Size.fromHeight(100);
}
class _LayoutState extends State<Layout> with WidgetsBindingObserver {
final CommandController _controller = Get.put(CommandController());
List pages = [
PatientInfoPage(),
const Page1(),
const Page2(),
const Page3(),
const Page4(),
const Page5(),
const Page6(),
const Page7()
];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
XmppConnection.addListener(globals.xmppHelper);
_controller.selectedPage.value = 7;
}
@override
void dispose() {
super.dispose();
XmppConnection.removeListener(globals.xmppHelper);
}
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
globals.xmppHelper.appLifecycleState = state;
debugPrint("state: ${state.toString()}");
if (state == AppLifecycleState.resumed) {
debugPrint("state: resumed");
} else if (state == AppLifecycleState.detached) {
debugPrint("state: detached");
}
}
@override
Widget build(BuildContext context) {
List<AppBar> appbars = [
AppBar(title: Text(''.tr)),
AppBar(),
AppBar(),
AppBar(title: Text(''.tr)),
AppBar(title: Text(''.tr)),
AppBar(),
AppBar(title: Text(''.tr), actions: const [
Padding(
padding: EdgeInsets.only(right: 16.0),
child: Icon(Icons.telegram, size: 50, color: Colors.blue)),
]),
AppBar(
automaticallyImplyLeading: false,
title: const Text(''),
)
];
return PopScope(
canPop: false,
child: Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(50),
child: Obx(() => appbars[_controller.selectedPage.value]),
),
drawer: const SideNavigationMenu(),
body: Obx(() => pages[_controller.selectedPage.value]),
),
);
}
}
Also the connection breaks when the app is background or no actions in 10 minutes.
I tried to handle it in many ways but i failed.