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');
}
});
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With