【问题标题】:How to implement .aidl file in flutter如何在flutter中实现.aidl文件
【发布时间】:2021-04-03 11:05:38
【问题描述】:

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

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

我找不到正确的答案,所以在这里发布了这个问题。

【问题讨论】:

  • 我不知道你是否还需要它,但是我已经这样做了,确实可以,而且好消息是它非常容易。您只需要编写绑定到aidl 的android 部分。如果您仍然需要它,我可以稍后为您提供一些代码的答案,以及最终可能会找到这个问题的人。我现在离我的电脑很远。
  • @arvil 那太好了

标签: java android flutter dart printers


【解决方案1】:

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

为此,与任何其他特定于 Android 的 MethodChannel 实现一样,您需要创建 MethodCallHandler 和/或 StreamHandler(取决于您是想做流还是只做命令 -> 结果方法),注册它在 Main FlutterActivity 上,并通过 MethodChannels 从 dart 中调用它。

免责声明

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

创建 MethodCallHandler/StreamHandler

在您的 Flutter 应用程序的 android/app/src/main/com/some/path 文件夹中,创建一个新的 java 文件并实现 ServiceConnectionMethodChannel.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 作为 MethodChannel 和 EventChannel 注册到 MainActivity

现在已经不碍事了,您需要在 MainActivityconfigureFlutterEngine 方法上注册此插件:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-01
    • 2020-09-07
    • 2023-04-03
    • 2020-07-19
    • 2019-03-19
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    相关资源
    最近更新 更多