Get activity reference in flutter plugin
Asked Answered
E

5

13

When I created a flutter plugin, there are two methods in the plugin class by default:

override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)

and

fun registerWith(registrar: Registrar)

The comment on the file says : It is encouraged to share logic between onAttachedToEngine and registerWith to keep them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called depending on the user's project. onAttachedToEngine or registerWith must both be defined in the same class.

Now, I need to start another activity from here, with activity.startActivityForResult(). It is possible to get a reference to the activity in registerWith(registrar: Registrar) using registrar.activity(). How can I do this in the method onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) ?

Eberta answered 23/1, 2020 at 22:22 Comment(0)
E
20

Found the solution here.
Implement ActivityAware and one of its methods is

 override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    this.activity = binding.activity;
  }
Eberta answered 25/1, 2020 at 18:27 Comment(4)
@Neeraj, I tried above solution, but surprisingly on method call the activity is null. I assigned activity in AttachedToActivity callback and after immediate onMethodCall, the this.activity is null. Any suggestions?Klausenburg
Read more in the documentationAppulse
@Satya Attili I have exactly the same problem. Have you found a solution?Gadgeteer
Under what conditions are you trying @SatyaAttili? If you are using a background message handler in a Service or static broadcast receiver, then the Activity is not yet created, so onAttachedToActivity was never called. So this.activity would be null.Drumhead
P
6

Note:

you can get reference to activity by implementing ActivityAware interface but if you setMethodCallHandler(...) in onAttachToEngine() method onAttachToActivity() will never be called and you can never get access to activity

take a look at below examples

WHAT DOES NOT WORK : in below examples onAttachToActivity() is never called

class AndroidLongTaskPlugin : FlutterPlugin, ActivityAware {
  private var activity: FlutterActivity? = null

  

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    //activity is null here 
    //also onAttachToActivity will never be called because we are calling setMethodHandler here
    channel = MethodChannel(binaryMessenger, CHANNEL_NAME)
    channel.setMethodCallHandler { call, result ->
        //our code
    }

  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel?.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    activity = binding.activity as FlutterActivity
  }

  //rest of the methods
}

HERE IS A WORKING EXAMPLE :

class MyPlugin : FlutterPlugin, ActivityAware {
  private var activity: FlutterActivity? = null
  private var binaryMessenger: BinaryMessenger? = null

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    binaryMessenger = flutterPluginBinding.binaryMessenger
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    Log.d("DART/NATIVE", "onDetachedFromEngine")
    channel?.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    Log.d("DART/NATIVE", "onAttachedToActivity")
    activity = binding.activity as FlutterActivity
    //here we have access to activity
    //also make sure to setMethodCallHandler here
    channel.setMethodCallHandler { call, result ->
        //our code
    }
  }

  //rest of the methods
}


Polish answered 18/2, 2021 at 21:57 Comment(4)
@Alexufo. check this library out pub.dev/packages/android_long_taskPolish
Do you know where I can attach startActivityForResult? I want open new activity.Wharfage
I found solution bitbucket.org/prathap_kumar/mvbarcodescan/raw/…Wharfage
In my case in onAttachedToEngine this code work MethodChannel channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), channelName); channel.setMethodCallHandler(this); And on onAttachedToActivity I use activity = activityPluginBinding.getActivity(); activityPluginBinding.addActivityResultListener(this);Wharfage
H
0

In the latest versions Flutter 3.0.5+ this is what worked for me:

Make sure to add ActivityAware in the class implements


import io.flutter.embedding.engine.plugins.FlutterPlugin;
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;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;

public class FlutterCustomPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {

    private MethodChannel channel;
    private Activity activity;


 @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_custom_plugin");
        channel.setMethodCallHandler(this);
//        channel.setMethodCallHandler(new FlutterBlufiPlugin(flutterPluginBinding.activity()));
    }

  @Override
    public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
        // TODO: your plugin is now attached to an Activity
        this.activity = activityPluginBinding.getActivity();
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {
        // TODO: the Activity your plugin was attached to was destroyed to change configuration.
        // This call will be followed by onReattachedToActivityForConfigChanges().
    }

    @Override
    public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
        // TODO: your plugin is now attached to a new Activity after a configuration change.
    }

    @Override
    public void onDetachedFromActivity() {
        // TODO: your plugin is no longer associated with an Activity. Clean up references.
    }

}

remember to add all 4 override methods

Hesitant answered 25/10, 2022 at 9:1 Comment(0)
N
-1

In 2023, you can do it like this:

Kotlin code:

class MainActivity: FlutterActivity() {
     override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        Global_Variable.current_activity = this.activity;
        Global_Variable.application_content = this.applicationContext;

        ...
    }
}

Java code:

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;

public class MainActivity extends FlutterActivity {

    @Override
    public void configureFlutterEngine(FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        // Get a reference to the Activity
        FlutterActivity mainActivity = (FlutterActivity) this;

        // Do something with the Activity
        // ...
    }
}

Neon answered 4/6, 2023 at 7:44 Comment(0)
M
-2

In my case the resolution of alireza-easazade did not work. I removed MethodChannel creation from onAttachedToEngine but ActivityAware notifications still did not come. What worked for me was to replace flutterPluginBinding.getBinaryMessenger() with flutterPluginBinding.getFlutterEngine().getDartExecutor() as a parameter in MethodChannel constructor. Once I did this onAttachedToActivity​ was called immediately after onAttachedToEngine.

Here is my working example:

public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {

  private ActivityPluginBinding _activityBinding;
  private FlutterPluginBinding _flutterBinding;
  private MethodChannel _channel;

  // FlutterPlugin  overrides

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    _flutterBinding = flutterPluginBinding;
    _channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "com.example.test/myplugin");
    _channel.setMethodCallHandler(this);
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    _channel.setMethodCallHandler(null);
    _channel = null;
    _flutterBinding = null;
  }

  // ActivityAware  overrides

  @Override
  public void onAttachedToActivity​(ActivityPluginBinding binding) {
    _activityBinding = binding;
  }

  @Override
  public void   onDetachedFromActivity() {
    _activityBinding = null;
  }

  @Override
  public void   onReattachedToActivityForConfigChanges​(ActivityPluginBinding binding) {
    _activityBinding = binding;
  }

  @Override
  public void   onDetachedFromActivityForConfigChanges() {
    _activityBinding = null;
  }

  // MethodCallHandler overrides
  
  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    // Handle calls
  }

  // Implementation

  public Context getApplicationContext() {
    return (_flutterBinding != null) ? _flutterBinding.getApplicationContext() : null;
  }

  public Activity getActivity() {
    return (_activityBinding != null) ? _activityBinding.getActivity() : null;
  }
}
Meehan answered 1/2, 2022 at 7:54 Comment(1)
You are using a deprecated API.Conditional

© 2022 - 2025 — McMap. All rights reserved.