Flutter平台频道的频道名称应采用哪种格式?

时间:2018-12-21 17:09:56

标签: android flutter platform

我要添加创建自己的平台频道(特别是Android的方法频道)并关注https://flutter.io/docs/development/platform-integration/platform-channels#step-1-create-a-new-app-project

我知道:

  

单个应用程序中使用的所有频道名称必须唯一;我们推荐   在频道名称前添加唯一的“域名前缀”,例如   samples.flutter.io/电池。

名称是否必须为特定格式?例如。我可以仅用battery来命名我的频道吗?还是格式my_company.flutter.io/battery周围有东西?或者是其他东西?我尝试过各种Strings,但是每次我得到一个:

MissingPluginException(No implementation found for method getBattery on channel battery)

所以我想知道我的频道名称格式是否不正确。 我认为我的方法名称getBattery是正确的。但是要澄清一下,我想做:

final result = await platform.invokeMethod('getBattery');

不带插件前缀,对吗?

final result = await platform.invokeMethod('battery.getBattery'); 

1 个答案:

答案 0 :(得分:2)

我有一个现场例子here,我已经做过几次了。

  

名称是否必须为特定格式?例如。我可以为频道命名吗   只是普通的电池?还是格式周围有些东西   my_company.flutter.io/电池?还是其他?

由于频道名称必须唯一,因此最佳做法是在频道名称前加上bundle(iOS)/package(Android) id

例如:

static const platform =
      const MethodChannel('it.versionestabile.flutterapp000001/pdfViewer');

无论如何,您都可以称它为Wath,但它应该是唯一的,并且在Dart和Android / iOS端都相同。

private static final String CHANNEL = "it.versionestabile.flutterapp000001/pdfViewer";

但是“调用”它就像在通道中放东西一样。

因为该频道是一个频道(想象一个管道),并且您将其放置在从侧面(飞镖)传递到另一个(Android / iOS)的内容完全是另一个故事^ _ ^。

放在里面的东西,应该与另一端相等。

platform.invokeMethod('viewPdf', args);

因此,您通过渠道发送的只是消息

您将带有字母的瓶子放在管道中^ _ ^

现在,您必须像'viewPdf'这样在本机代码端捕获此消息。

new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
            new MethodChannel.MethodCallHandler() {
              @Override
              public void onMethodCall(MethodCall call, MethodChannel.Result result) {
                if (call.method.equals("viewPdf")) {
                  if (call.hasArgument("url")) {
                    String url = call.argument("url");
                    File file = new File(url);
                    //*
                    Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
                            BuildConfig.APPLICATION_ID + ".provider",
                            file);
                            //*/
                    Intent target = new Intent(Intent.ACTION_VIEW);
                    target.setDataAndType(photoURI,"application/pdf");
                    target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                    target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    startActivity(target);
                    result.success(null);
                  }
                } else {
                  result.notImplemented();
                }
              }
            });
  }

否则,您将被困在

} else {
   result.notImplemented();
}

如果您已按照示例操作,则应在Android本机代码端使用它:

@Override
public void onMethodCall(MethodCall call, Result result) {
    if (call.method.equals("getBatteryLevel")) {
        int batteryLevel = getBatteryLevel();

        if (batteryLevel != -1) {
            result.success(batteryLevel);
        } else {
            result.error("UNAVAILABLE", "Battery level not available.", null);
        }
    } else {
        result.notImplemented();
    }
}

因此您应该致电:

platform.invokeMethod('getBatteryLevel');

因为该示例的代码期望通过该通道传递消息'getBatteryLevel'

加强概念

因此,为了牢记所有这些概念,我将进一步告诉您,您可以决定使用渠道来为单个手术服务还是为多个手术服务。选择取决于您。

所以你可以拥有

飞镖面:

  static const singleChannel =
      const MethodChannel('it.versionestabile.flutterapp000001/single');
  static const multiChannel =
      const MethodChannel('it.versionestabile.flutterapp000001/multi');

本地(Android):

  private static final String SINGLE_CHANNEL = "it.versionestabile.flutterapp000001/single";
  private static final String MULTI_CHANNEL = "it.versionestabile.flutterapp000001/multi";

还有一些玩具处理程序:

new MethodChannel(getFlutterView(), MULTI_CHANNEL).setMethodCallHandler(
        new MethodChannel.MethodCallHandler() {
          @Override
          public void onMethodCall(MethodCall call, MethodChannel.Result result) {
            if (call.method.equals("op1")) {
              new AlertDialog.Builder(MainActivity.this)
                      .setTitle(call.method)
                      .setMessage("I'm the " + call.method + " of the by design multi operation channel!")
                      .create()
                      .show();
            } else if (call.method.equals("op2")) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle(call.method)
                        .setMessage("I'm the " + call.method + " of the by design multi operation channel!")
                        .create()
                        .show();
            } else {
              result.notImplemented();
            }
          }
        });

new MethodChannel(getFlutterView(), SINGLE_CHANNEL).setMethodCallHandler(
        new MethodChannel.MethodCallHandler() {
          @Override
          public void onMethodCall(MethodCall call, MethodChannel.Result result) {
            if (call.method.equals("hello")) {
              new AlertDialog.Builder(MainActivity.this)
                      .setTitle("hello!")
                      .setMessage("I'm the by design single operation channel!")
                      .create()
                      .show();
            } else {
              result.notImplemented();
            }
          }
        });

enter image description here

  void _invokeMultiChannelOp2() {
    multiChannel.invokeMethod('op2');
  }

  void _invokeMultiChannelOp1() {
    multiChannel.invokeMethod('op1');
  }

  void _invokeSingleChannel() {
    singleChannel.invokeMethod('hello');
  }

floatingActionButton: SafeArea(
    child: Padding(
        padding: EdgeInsets.only(left: 8.0),
        child: Row(
          children: <Widget>[
            new IconButton(
                icon: new Icon(Icons.library_music),
                onPressed: _invokeMultiChannelOp1),
            new IconButton(
                icon: new Icon(Icons.note),
                onPressed: _invokeMultiChannelOp2),
            new IconButton(
                icon: new Icon(Icons.plus_one),
                onPressed: _invokeSingleChannel),
          ],
        )),
  ),