Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke Flutter (Dart) code from native Android home screen widget

Tags:

People also ask

Does Flutter use native widgets?

Flutter doesn't use native system components. Instead, it offers a set of its own custom widget catalog, rendered and managed by the framework's graphics engine.

How Flutter and Dart code get compiled to native apps?

Using the Dart language allows Flutter to compile the source code ahead-of-time to native code. The engine's C/C++code is compiled with Android's NDK or iOS' LLVM. Both pieces are wrapped in a “runner” Android and iOS project, resulting in an apk or ipa file respectively.


I added a native Android home screen widget to my Flutter application.

In my AppWidgetProvider implementation, I'd like to call dart code in my onUpdate() method using a platform channel.

Is this possible? If so, how can this be achieved?

My current Android (Java) code:

package com.westy92.checkiday;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.util.Log;

import io.flutter.plugin.common.MethodChannel;
import io.flutter.view.FlutterNativeView;

public class HomeScreenWidget extends AppWidgetProvider {

    private static final String TAG = "HomeScreenWidget";
    private static final String CHANNEL = "com.westy92.checkiday/widget";

    private static FlutterNativeView backgroundFlutterView = null;
    private static MethodChannel channel = null;

    @Override
    public void onEnabled(Context context) {
        Log.i(TAG, "onEnabled!");
        backgroundFlutterView = new FlutterNativeView(context, true);
        channel = new MethodChannel(backgroundFlutterView, CHANNEL);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        Log.i(TAG, "onUpdate!");
        if (channel != null) {
            Log.i(TAG, "channel not null, invoking dart method!");
            channel.invokeMethod("foo", "extraJunk");
            Log.i(TAG, "after invoke dart method!");
        }
    }
}

Dart code:

void main() {
  runApp(Checkiday());
}

class Checkiday extends StatefulWidget {
  @override
  _CheckidayState createState() => _CheckidayState();
}

class _CheckidayState extends State<Checkiday> {
  static const MethodChannel platform = MethodChannel('com.westy92.checkiday/widget');

  @override
  void initState() {
    super.initState();
    platform.setMethodCallHandler(nativeMethodCallHandler);
  }

  Future<dynamic> nativeMethodCallHandler(MethodCall methodCall) async {
    print('Native call!');
    switch (methodCall.method) {
      case 'foo':
        return 'some string';
      default:
      // todo - throw not implemented
    }
  }

  @override
  Widget build(BuildContext context) {
    // ...
  }
}

When I add the widget to my home screen, I see:

I/HomeScreenWidget(10999): onEnabled!
I/HomeScreenWidget(10999): onUpdate!
I/HomeScreenWidget(10999): channel not null, invoking dart method!
I/HomeScreenWidget(10999): after invoke dart method!

However, my dart code does not seem to be receiving the invocation.