如何在flutter中实现.aidl文件

问题描述 投票:0回答:2

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

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

我找不到正确的答案,因此将问题发布在这里。

java android flutter dart printers
2个回答
2
投票

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

为此,与任何其他特定于 Android 的

MethodChannel
实现一样,您需要创建一个 MethodCallHandler 和/或一个 StreamHandler (取决于您是否想要执行流或只是一个命令 -> 结果方法),将其注册到Main FlutterActivity,并通过 MethodChannels 从 dart 调用它。

免责声明

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

创建MethodCallHandler/StreamHandler

在 flutter 应用程序的

android/app/src/main/com/some/path
文件夹中,创建一个新的 java 文件并实现
ServiceConnection
MethodChannel.MethodCallHandler
和/或
EventChannel.StreamHandler
:

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
}

将 PrinterPlugin 注册到 MainActivity 作为 MethodChannel 和 EventChannel

既然已经解决了,您需要在

MainActivity
configureFlutterEngine
方法上注册此插件:

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

从 dart 调用方法

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


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
ServiceConnection
实现。

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

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


0
投票

如果您的打印机使用 BT 或 USB 接口(有时即使设备有内置打印机,它们仍然通过带状电缆使用 USB 接口),您可以放弃供应商的 SDK 并使用 flutter 包POS 打印,如 flutter_esc_pos_utils

要检查正在使用哪个接口,请首先安装上述软件包并运行以下命令:

final profiles = await CapabilityProfile.getAvailableProfiles();

我已经使用这种方法在自助点餐机的内置打印机上进行打印。减少开发时间并让您 应用程序兼容更多硬件。

© www.soinside.com 2019 - 2024. All rights reserved.