如何在flutter中实现.aidl文件

问题描述

我正在尝试使用颤振与 SunMi 移动打印机进行通信。我想使用 AIDL 调用打印机作为与打印机通信的一种方式,但我不知道如何以及在何处将 AIDL 文件放置在颤振中,或者甚至可以在我的情况下使用颤振。我需要知道是否可以使用其 AIDL 与打印机进行通信。我选择在我的应用程序中使用带有 java 的 flutter 或 android studio。

问题来源:https://github.com/flutter/flutter/issues/49413#issue-554566892

我找不到正确的答案,所以把问题贴在这里。

解决方法

由于这是我们正在讨论的 AIDL 文件,因此可以安全地假设这是一项仅限 Android 的功能。

要做到这一点,就像任何其他 Android 特定的 const Example = ( props: { variant: "First"; height: number } | { variant: "Second"; width: number } ) => { /*...code...*/ }; 实现一样,您需要创建一个 MethodCallHandler 和/或一个 StreamHandler(取决于您是要执行流还是只是一个命令 -> 结果方法) ,将其注册到 Main FlutterActivity 上,并从 dart 通过 MethodChannels 调用它。

免责声明

  • 下面的代码未经测试,可能有一些语法错误,如果您发现问题,请告诉我,我会解决它们。
  • 为简洁起见,我已将所有内容合并到一个文件中,您可以将代码的某些部分移动到您认为合适的单独文件中。

创建 MethodCallHandler/StreamHandler

在 Flutter 应用程序的 MethodChannel 文件夹中,创建一个新的 java 文件并实现 android/app/src/main/com/some/pathServiceConnection 和/或 MethodChannel.MethodCallHandler

EventChannel.StreamHandler

将 PrinterPlugin 作为 MethodChannel 和 EventChannel 注册到 MainActivity

既然这样,您需要在 public class PrinterPlugin implements MethodChannel.MethodCallHandler,EventChannel.StreamHandler,ServiceConnection { public static final CHANNEL = "com.some.path/printer"; public static final EVENT_CHANNEL = "com.some.path/printer-events"; private Context context; private IPrinterService printerService = null; // where IPrinterService would be the AIDL's name public EventChannel.EventSink eventSink = null; public PrinterPlugin(Context context) { this.context = context; if (printerService == null) { // these strings should be in your documentation or you can find these values from the package manager Intent intent = new Intent("com.your.printer.service"); intent.setPackage("com.whatever.aidl"); context.bindService(intent,this,Context.BIND_AUTO_CREATE); } } public void disconnect() { context.unbindService(this); } // streamhandler implementation @Override public void onListen(Object arguments,EventChannel.EventSink events) { this.eventSink = events; } @Override public void onCancel(Object arguments) { this.eventSink = null; } // /streamhandler implementation // methodcallhandler implementation @Override public void onMethodCall(MethodCall call,MethodChannel.Result result) { try { switch (call.method) { case "initialize": printerService.printerInit(); break; case "print-text": printerService.printText(call.argument("data")); break; // implement other aidl methods } } catch (RemoteException e) { result.error("",ex.getMessage(),null); } } // /methodcallhandler implementation // serviceConnection implementation @Override public void onServiceConnected(ComponentName name,IBinder service) { printerService = IPrinterService .Stub.asInterface(service); if (eventSink != null) { eventSink.success("Printer Connected"); } } @Override public void onServiceDisconnected(ComponentName name) { printerService = null; if (eventSink != null) { eventSink.success("Printer Disconnected"); } } // /serviceConnection implementation } MainActivity 方法上注册此插件:

configureFlutterEngine

从 dart 调用方法

现在你需要做的最后一件事是从 dart 调用这些。

public class MainActivity extends FlutterActivity {
    private PrinterPlugin printerPlugin;

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        Context context = getContext();
        printerPlugin = new PrinterPlugin(context);

        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(),PrinterPlugin.CHANNEL)
            .setMethodCallHandler(printerPlugin);

        new EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(),PrinterPlugin.EVENT_CHANNEL)
            .setStreamHandler(printerPlugin);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        this.printerPlugin.unbindService();
    }
}

嗯,那是很多代码 - 但基本上我就是这样做的。只是一个带有 const MethodChannel _channel = MethodChannel('com.some.path/printer'); // should match the CHANNEL constant on the java side const EventChannel _evntChannel = EventChannel('com.some.path/printer-events'); // should match the EVENT_CHANNEL constant on the java side class PrinterPlugin { static Stream<dynamic> _printerStream = _eventChannel.receiveBroadcastStream(); Stream<String> status$; PrinterPlugin() { status$ = _printerStream; } static Future printText(String data) async { await _channel.invokeMethod('initialize'); await _channel.invokeMethod('print-text','Foo Bar'); } } 实现的 MethodCallHandler

您也可以对这个实现感到疯狂,例如实时打印进度,或获取流式打印机状态等。

让我知道它是否适合您的需求。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...