使用 file_picker 使用 snapcraft 构建的 Flutter 应用程序不显示对话框

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

我构建了一个可以在 Windows、Linux 和 Android 上完美运行的 Flutter 应用程序。但是,当我将代码编译并作为快照包运行时,文件对话框窗口不会出现。

对话框使用 file_picker 插件 (v8.1.2)。

我花了几个小时按照互联网上的不同说明进行操作,并询问了多个不同的人工智能,但似乎没有任何效果。

这是我的 snapcraft.yaml 文件:

name: jpl
version: 0.6.0.0
summary: TBC
description: TBC.

confinement: strict
base: core22
grade: devel

apps:
  jpl:
    command: jpl
    extensions: [gnome]
    plugs:
      - dbus
      - desktop
      - home
      - system-observe

parts:
  jpl:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart

plugs:
  dbus:
    bus: session
    name: "org.gtk.Actions"

我没有从编译中得到任何错误,但当我运行应用程序时,我确实收到以下错误:

AppArmor =
Time: Sep  7 12:12:51
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/au/com/jpl/window/1" interface="org.gtk.Actions" member="DescribeAll" name=":1.26" mask="receive" pid=142250 label="snap.jpl.jpl" peer_pid=1663 peer_label="unconfined"
DBus access

任何帮助将不胜感激。

谢谢。


编辑1:

我将以下内容添加到我的 snapcraft.yaml 文件中,当我运行我的应用程序时,该文件不再显示我上面提到的错误,但对话框窗口仍然不显示。

apps:
  ...
  jpl:
    ...
    slots:
      dbus-gtk
...
slots:
  dbus-gtk:
    interface: dbus
    bus: session
    name: au.com.jpl

我也尝试过桌面遗留,但没有效果。

flutter yaml dbus snapcraft snap
1个回答
0
投票

我最终使用了多个库 - 一个用于桌面,一个用于移动,一个用于网络。这是因为 file_picker 不适用于 snap,但 file_selector 不适用于移动设备,并且在网络上运行时也不适用于保存文件。

我已经在下面为遇到此问题的其他人概述了它(为了示例,以下内容是根据我自己的代码进行更改的,以使其更简单/更清晰)。

pubspec.yaml

dependencies:
  file_picker: ^8.1.2
  file_selector: ^1.0.3

导入数据.dart

import "package:file_picker/file_picker.dart";
import "package:file_selector/file_selector.dart";

Future<void> _openDesktop() async {
  XTypeGroup types = const XTypeGroup(
    label: "JSON",
    extensions: ["json"],
  );

  XFile? file = await openFile(
    acceptedTypeGroups: [types],
  );

  if (file != null) {
    String contents = await file.readAsString();
  }
}

Future<void> _openMobile() async {
  FilePickerResult? path = await FilePicker.platform.pickFiles(
    dialogTitle: "Open File",
    type: FileType.custom,
    allowedExtensions: ["json"],
    withReadStream: true,
    lockParentWindow: true,
  );

  if (result != null) {
    Stream<List<int>> stream = result.files.first.readStream!
    StringBuffer buffer = StringBuffer();

    stream.transform(utf8.decoder).listen((data) {
      buffer.write(data);
    },
    onError: (exception) {
      // Show an error message
    },
    onDone: () {
      String contents = buffer.toString();
    }
  }
}

Future<void> _openWeb() async {
  XTypeGroup types = const XTypeGroup(
    label: "JSON",
    extensions: ["json"],
  );

  FilePickerResult? result = openFile(
    acceptedTypeGroups: [types],
  );

  if (result != null) {
    String contents = await result.readAsString();
  }
}

export_data.dart(显然内容不是有效的 JSON,仅提供示例)

import "package:file_picker/file_picker.dart";
import "package:file_selector/file_selector.dart";
import "package:ledger/web_empty.dart"
    if(dart.library.web) "package:web/web.dart";

Future<void> _saveDesktop() async {
  XTypeGroup types = const XTypeGroup(
    label: "JSON",
    extensions: ["json"],
  );

  FileSaveLocation? result = await getSaveLocation(
    acceptedTypeGroups: [types],
    suggestedName: "Data.json",
  );

  if (result != null) {
    await File(result.path).writeAsString("contents");
  }
}

Future<void> _saveMobile() async {
  await FilePicker.platform.saveFile(
    dialogTitle: "Save File",
    fileName: "Data.json",
    type: FileType.custom,
    allowedExtensions: ["json"],
    bytes: utf8.encode("contents"),
    lockParentWindow: true,
  );
}

Future<void> _saveWeb() async {
  String data = Uri.encodeComponent("contents");
  HTMLAnchorElement()
    ..href = "data:text/plain;charset=utf-8,$data"
    ..download = "Data.json"
    ..click();
}

web_empty.dart(我必须创建它,否则它将无法编译为快照 - 请参阅export_data.dart中的条件导入)

class HTMLAnchorElement {
  String download = "";
  String href = "";

  void click() {}
}

希望这有帮助!

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