Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create method channel after upgrading flutter- can not resolve method getFlutterView()

i was using native android method in my flutter app using documentation which said use

MethodChannel(flutterView, CHANNEL).setMethodCallHandler...

but after upgrading flutter the MethodChannel function does not require flutterView and there is no flutterView anymore.

can not resolve method getFlutterView()

i think there should be a new tutorial for creating channel

instead it needs some BinaryMessenger which i don't know what to give instead.

this is the old code which is not working anymore:

import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.dev/battery";

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);

    new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
            new MethodCallHandler() {
                @Override
                public void onMethodCall(MethodCall call, Result result) {
                    // Note: this method is invoked on the main thread.
                    // TODO
                }
            });
}
like image 431
Mahmood Bkh Avatar asked Dec 07 '19 16:12

Mahmood Bkh


4 Answers

Replace getFlutterView() with getFlutterEngine().getDartExecutor().getBinaryMessenger().

You don't actually need the .getBinaryMessenger() as DartExecutor implements BinaryMessenger itself (by just forwarding), but I think it's more correct to specify the messenger.

like image 175
Richard Heap Avatar answered Sep 28 '22 01:09

Richard Heap


Simply add this method to your class:

BinaryMessenger getFlutterView(){
    return getFlutterEngine().getDartExecutor().getBinaryMessenger();
}

And then optionally replace all ( Refactor > Rename ) "getFlutterView" to "getBinaryMessenger" to have a more readable code:

BinaryMessenger getBinaryMessenger(){
    return getFlutterEngine().getDartExecutor().getBinaryMessenger();
}
like image 26
mehrdad seyrafi Avatar answered Sep 27 '22 23:09

mehrdad seyrafi


Remove this import io.flutter.embedding.android.FlutterActivity;

Add this import io.flutter.app.FlutterActivity;

Worked for Me

like image 40
Sanskar Tiwari Avatar answered Sep 28 '22 01:09

Sanskar Tiwari


I spent days trying to figure out how to add a Flutter UI to my existing Android App. The biggest challenge was getting the MethodChannel to work with FlutterActivity being called from MainActivity. I know this is a little different than the question asked here, but this post was returned when I did searches for 'Android FlutterActivity MethodChannel'. After going though many resources on how to do this, I finally found my solution here: https://github.com/flutter/samples/tree/master/add_to_app/android_using_plugin/app/src/main/java/dev/flutter/example/androidusingplugin

Initially, in Android Studio, with the existing app opened, I tapped File, New, New Module, Flutter Module. I received an error and had to perform manual steps.

My objective is to launch FlutterActivity (opens main.dart in the flutter_module) in MainActivity - onCreate, then develop Flutter 'screens' leveraging as much native Flutter code as possible, with limited Platform calls using the MethodChannel. As I develop replacement Flutter code, I will continue to comment out the existing Android Code.

Here is what finally worked for me:

../App_Project/Android/Existing_Android_App/settings.gradle

include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir.parentFile, '../flutter_module/.android/include_flutter.groovy'))
include ':flutter_module’
project(':flutter_module’).projectDir = new File('../../flutter_module’)
rootProject.name=‘existing_android_app’

../App_Project/Android/Existing_Android_App/app/build.gradle

dependencies {
…
    implementation project(':flutter')
}

../App_Project/Android/Existing_Android_App/app/src/main/AndroidManifest.xml

<activity
    android:name="io.flutter.embedding.android.FlutterActivity"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:windowSoftInputMode="adjustResize" />

../App_Project/Android/Existing_Android_App/app/src/main/java/com/existing_android_app/MainActivity.java

package com.existing_android_app;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

public class MainActivity extends AppCompatActivity {

    final String ENGINE_ID = "1";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        FlutterEngine flutterEngine = new FlutterEngine(this);
        flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());

        FlutterEngineCache.getInstance().put(ENGINE_ID, flutterEngine);

        MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "com.existing_android_app/myMethodChannel");

        channel.setMethodCallHandler(
                new MethodChannel.MethodCallHandler() {
                    @Override
                    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
                        String url = call.argument("url");
                        if (call.method.equals("openBrowser")) {
                            openBrowser(url);
                        } 
                          else {
                            result.notImplemented();
                        }
                    }
                });

        startActivity(FlutterActivity.withCachedEngine(ENGINE_ID).build(this));
    }

    void openBrowser(String url) {

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse(url));

        this.startActivity(intent);
    }
}

../App_Project/flutter_module/lib/home_page.dart

class AppHomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<AppHomePage> {

  static const platform = const MethodChannel(‘com.existing_android_app/myMethodChannel’);

  Future<void> _openBrowser() async {
    try {
      final int result = await platform.invokeMethod('openBrowser', <String, String> { 'url': "http://bing.com” });
    }
    catch (e) {
      print('***** _openBrowser error: ' + e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: CustomAppBar(),
        body: Column(
          children: <Widget>[
            RaisedButton(
              label: Text('Search',
                style: TextStyle(fontSize: 18.0),
              ),
              onPressed: () {  _openBrowser(); },
            ) // RaisedButton.icon
          ], // Widget
        ) // Column
      ) // Scaffold
    ); // SafeArea
  }
like image 32
AndyW58 Avatar answered Sep 28 '22 01:09

AndyW58