自定义 Facebook 登录以与 MethodChannel 一起使用

Custom Facebook Login to use with MethodChannel

我正在尝试使用一些本机代码为 Flutter 创建一个 Facebook 身份验证插件。我的代码在一个完全原生的测试项目中运行,但无法在 android 插件项目中运行。我不是 Android 人,所以我对此的了解非常有限。但这就是我得到的:

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();
  }
}

我想使用最后两个功能:登录、注销。但是在方法 "onActivityResult" 中,我遇到了一个问题,它无法解析 onActivityResult,在 "login" 中,我遇到了与 loginWithReadPermissions 相同的问题。 一切都应该正确导入。 有 android 经验的人可以帮忙吗?

为了在 Flutter 插件中使用 onActivityResult,你必须做两件事:

  1. 实现PluginRegistry.ActivityResultListener接口
  2. 将插件添加到 registerWith 静态方法中的 ActivityResultListeners 列表。

删除 MethodCall 位的简化示例:

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;
  }
}

如果你在 2020 年编写了自己的 Flutter 插件并尝试实现调用 onActivitResult 试试这个。插件 API 同时发生了变化,除了只在 registerWith 中注册侦听器外,您还必须实现 ActivityAware 接口并在 [=] 中注册 ActivityResultListner 14=]方法:

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()
        }
    }

}