web-dev-qa-db-ja.com

ネイティブからFlutter(Dart)コードを呼び出すAndroidホーム画面ウィジェット

ネイティブのAndroidホーム画面ウィジェットをFlutterアプリケーションに追加しました。

私のAppWidgetProvider実装では、プラットフォームチャネルを使用してonUpdate()メソッドでDartコードを呼び出したいのですが。

これは可能ですか?もしそうなら、これはどのように達成できますか?

私の現在のAndroid(Java)コード:

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!");
        }
    }
}

ダーツコード:

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) {
    // ...
  }
}

ウィジェットをホーム画面に追加すると、次のようになります。

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

ただし、私のDartコードは呼び出しを受け取っていないようです。

14
Westy92

まず、Dartコードを実行する前に、FlutterMain.startInitialization()を呼び出し、次にFlutterMain.ensureInitializationComplete()を呼び出していることを確認してください。これらの呼び出しは、bootstrap Flutterに必要です。

次に、新しい実験的なAndroid埋め込みを使用して、同じ目標を試すことができますか?

これは、新しい埋め込みを使用してDartコードを実行するためのガイドです。 https://github.com/flutter/flutter/wiki/Experimental:-Reuse-FlutterEngine-across-screens

新しいAndroid=埋め込みを使用してもコードが期待どおりに機能しない場合は、問題をデバッグする方が簡単です。正常にポストバックするか、新しいエラー情報を投稿してください。

2
Fluttery

多分あなたはinvokeMethod(String method, @Nullable Object arguments, MethodChannel.Result callback)を使用し、コールバックを使用して失敗の理由を取得できます。

0
Liu Tom