Custom Facebook Login to use with MethodChannel

689

Solution 1

In order to use onActivityResult in Flutter plugins, you must do two things:

  1. Implement the PluginRegistry.ActivityResultListener interface
  2. Add the plugin to list of ActivityResultListeners in the registerWith static method.

Simplified example that strips out the MethodCall bits:

public class FacebookSignInPlugin implements MethodCallHandler,
      // Implement PluginRegistry.ActivityResultListener
      PluginRegistry.ActivityResultListener {

  public static void registerWith(Registrar registrar) {
      final MethodChannel channel = new MethodChannel(registrar.messenger(), "my_plugin");
      final FacebookSignInPlugin instance = new MyPlugin();

      // Register your plugin as an ActivityResultListener
      registrar.addActivityResultListener(instance);
      channel.setMethodCallHandler(instance);
  }

  private CallbackManager callbackManager = CallbackManager.Factory.create();

  @Override
  public void onMethodCall(MethodCall call, final Result result) {
  }

  @Override
  public boolean onActivityResult(int i, int i1, Intent intent) {
      // Forward the activity result to the Facebook CallbackManager
      callbackManager.onActivityResult(i, i1, intent);
      return false;
  }
}

Solution 2

If you write your own Flutter plugin in 2020 and try achieve calling onActivitResult try this. The plugin API has changed in the meantime, besides registering the listener only in registerWith you'll also have to implement the ActivityAware interface and register the ActivityResultListner in the onAttachedToActivity method:

class PayFlutterPlugin() : FlutterPlugin, MethodCallHandler, ActivityAware,
    ActivityResultListener {
   
    private var activityPluginBinding: ActivityPluginBinding? = null
    private var result: Result? = null

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        activityPluginBinding = binding
        binding.addActivityResultListener(this)
    }

    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {}

    override fun onDetachedFromActivityForConfigChanges() {}

    override fun onDetachedFromActivity() {
        activityPluginBinding?.removeActivityResultListener(this)
        activityPluginBinding = null
    }

    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent
    ): Boolean {
        // React to activity result and if request code == ResultActivity.REQUEST_CODE
        return when (resultCode) {
            Activity.RESULT_OK -> {
                result?.success("success") // pass your result data
                true
            }
            else -> false
        }
    }

    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
        this.result = result
        val activity = activityPluginBinding?.activity ?: return
        when (call.method) {
            "yourMethod" -> {
                val intent = Intent(activity, ResultActivity::class.java)

                activity.startActivityForResult(
                    intent,
                    ResultActivity.REQUEST_CODE
                )
            }
            else -> result.notImplemented()
        }
    }

}
Share:
689
Bram  Vanbilsen
Author by

Bram Vanbilsen

A developer I guess

Updated on December 02, 2022

Comments

  • Bram  Vanbilsen
    Bram Vanbilsen 12 months

    I'm trying to create a Facebook authentication plugin for Flutter by using some native code. I've got the code working on a completely native test project but can't get it to work in the android plugin project. I'm not an Android guy so my knowledge about this is very limited. But this is what I've got:

    public class FacebookSignInPlugin implements MethodCallHandler {
    
      CallbackManager callbackManager;
      AccessToken token;
    
      /**
       * Plugin registration.
       */
      public static void registerWith(Registrar registrar) {
        final MethodChannel channel = new MethodChannel(registrar.messenger(), "facebook_sign_in");
        channel.setMethodCallHandler(new FacebookSignInPlugin());
      }
    
    
      @Override
      public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("signInUser")) {
          callbackManager = CallbackManager.Factory.create();
          LoginManager.getInstance().registerCallback(callbackManager, new     FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
    
              token = loginResult.getAccessToken();
              Log.d("Facebook", token.toString());
            }
    
            @Override
            public void onCancel() {
              System.out.println("cancel");
              Log.d("Facebook", "Cancel");
            }
    
            @Override
            public void onError(FacebookException error) {
    
            }
          });
          login();
          result.success("It works on Android");
        } else {
          result.notImplemented();
        }
      }
    
      @Override
      protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
      }
    
      public void login() {
        LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "user_friends"));
      }
    
      public void logout() {
        LoginManager.getInstance().logOut();
      }
    }
    

    I'd like to use those last two functions: login, logout. But in the method "onActivityResult" I'm getting a problem that it cannot resolve onActivityResult and in "login" I'm getting this same problem with loginWithReadPermissions. Everything should be imported correct. Any one with some android experience that could help out?