How to use Flutter Method Channel in background (app minimised/closed)
I am collecting information/discussion that redirects us to run flutter engine in background.
void callbackDispatcher() {
WidgetsFlutterBinding.ensureInitialized();
print("Our background job ran!");
}
void main() {
static const MethodChannel _channel = const MethodChannel("channel-name");
Future<void> initialize(final Function callbackDispatcher) async {
final callback = PluginUtilities.getCallbackHandle(callbackDispatcher);
await _channel.invokeMethod('initialize', callback.toRawHandle());
}
}
As stated here How to run Flutter in the background?
When a background job is started by native the Flutter engine is not active. So we are unable to run Dart. Can Android/iOS starts the Flutter engine in the background? Yes! We’ll first need to register a Dart callback function which will only be invoked whenever a background job is started by the native code. This callback function is referred to as a callbackDispatcher.
Also please check out these stackoverflow discussions.
Flutter : Run an app as a background service
How to create a service in Flutter to make an app to run always in background?
How to create a Flutter background service that works also when app closed
Executing Dart in the Background with Flutter Plugins and Geofencing
Shahbaz Hashmi
Updated on December 23, 2022Comments
-
Shahbaz Hashmi over 1 year
I am working on a native Android widget in a Flutter App. In which there is refresh button, on click of that I have to call a method in the Flutter code. I am using Flutter Method Channel for the communication and it is working fine when app is in foreground. But it does not work when app is minimised or closed. I get error PlatformException(NO_ACTIVITY, null, null). Below is my code.
Android (AppWidgetProvider)
if (methodChannel == null && context != null) { FlutterMain.startInitialization(context) FlutterMain.ensureInitializationComplete(context, arrayOf()) // Instantiate a FlutterEngine. val engine = FlutterEngine(context.applicationContext) // Define a DartEntrypoint val entrypoint: DartEntrypoint = DartEntrypoint.createDefault() // Execute the DartEntrypoint within the FlutterEngine. engine.dartExecutor.executeDartEntrypoint(entrypoint) // Register Plugins when in background. When there // is already an engine running, this will be ignored (although there will be some // warnings in the log). //GeneratedPluginRegistrant.registerWith(engine) methodChannel = MethodChannel(engine.dartExecutor.binaryMessenger, MainActivity.CHANNEL) } methodChannel!!.invokeMethod("fetchNewData", "", object : MethodChannel.Result { override fun notImplemented() { Toast.makeText(context, "method not implemented", Toast.LENGTH_SHORT).show() } override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT).show() } override fun success(result: Any?) { Toast.makeText(context, "success", Toast.LENGTH_SHORT).show() } })
Flutter
/// calling in main static Future<void> attachListeners() async { WidgetsFlutterBinding.ensureInitialized(); var bloc = new AqiCnDashboardBloc(); _channel.setMethodCallHandler((call) { switch (call.method) { case 'fetchNewData': bloc.getAqiCn(false); return null; default: throw MissingPluginException('notImplemented'); } }); }
-
Shahbaz Hashmi over 3 yearsI have already gone through these articles. Can you post the code ?