我构建了一个可以在 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
我也尝试过桌面遗留,但没有效果。
我最终使用了多个库 - 一个用于桌面,一个用于移动,一个用于网络。这是因为 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() {}
}
希望这有帮助!