Reputation: 2557
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)
?
Upvotes: 14
Views: 15186
Reputation: 385
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
// ...
}
}
Upvotes: -1
Reputation: 3330
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
Upvotes: 0
Reputation: 67
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;
}
}
Upvotes: -2
Reputation: 3872
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
}
Upvotes: 8