我要添加创建自己的平台频道(特别是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');
答案 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();
}
}
});
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),
],
)),
),