我正在尝试将 Excel 文件保存到本地存储,但在创建文件时遇到此错误。我正在使用物理设备进行调试。仅当设备具有外部 SD 卡并配置为内部存储时才有效。但是,当我使用 SD 卡(配置为便携式存储)在不同的设备(物理设备)上运行该应用程序时,它不起作用,并且出现以下错误。
错误
[ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: FileSystemException: Creation failed, path = '/storage/emulated/0/Traders' (OS Error: Operation not permitted, errno = 1)
E/flutter (15532): #0 _Directory.create.<anonymous closure> (dart:io/directory_impl.dart:117:11)
E/flutter (15532): #1 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (15532): #2 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (15532): #3 _FutureListener.handleValue (dart:async/future_impl.dart:152:18)
E/flutter (15532): #4 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:704:45)
E/flutter (15532): #5 Future._propagateToListeners (dart:async/future_impl.dart:733:32)
E/flutter (15532): #6 Future._completeWithValue (dart:async/future_impl.dart:539:5)
E/flutter (15532): #7 Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:577:7)
E/flutter (15532): #8 _rootRun (dart:async/zone.dart:1354:13)
E/flutter (15532): #9 _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter (15532): #10 _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter (15532): #11 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter (15532): #12 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (15532): #13 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
E/flutter (15532):
Run Code Online (Sandbox Code Playgroud)
我的代码
import 'dart:io' as IO;
IO.Directory dir = await getExternalStorageDirectory();
String outputFile = "report"+DateFormat('dd-MM-yyyy hh:mm:ss').format(DateTime.now())+".xls";
if (await Permission.storage.request().isGranted) {
if (!IO.Directory('${dir.parent.parent.parent.parent.parent.path}/Traders/Reports').existsSync())
await IO.Directory('${dir.parent.parent.parent.parent.path}/Traders/Reports').create(recursive: true);
final file = IO.File(join('${dir.parent.parent.parent.parent.path}/Traders/Reports',outputFile));
await file.writeAsBytes(excel.encode()).then((value) {
if(IO.Platform.isAndroid||IO.Platform.isIOS)
OpenFile.open('${dir.parent.parent.parent.parent.path}/Traders/Reports/$outputFile');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("File Saved !")));
}).catchError((e){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Error Saving File !")));
});
}else{
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Error:Permission denied.Grant storage permission to save file."),action: SnackBarAction(label: 'Grant',onPressed: ()async{
await Permission.storage.request();
},),));
}
Run Code Online (Sandbox Code Playgroud)
AndroidMalifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)
(注:这个包 ext_storage 1.0.3 与当前版本的 Flutter 不兼容。(2023 年 5 月)
上面代码比较乱,可以使用这个包直接获取 Home 路径。( /storage/emulated/0)
然后你可以简单地这样做
var path = await ExtStorage.getExternalStorageDirectory();
final file = await File(path+'/Traders/Report').create(recursive: true);
file.writeAsStringSync("Hello I'm writting a stackoverflow answer into you");
Run Code Online (Sandbox Code Playgroud)
或者
我知道这个包不是 null 安全的。所以在这种情况下我提供本机代码。
一些 dart 文件,您需要路径
exportPath = await channel.invokeMethod('getExternalStorageDirectory'); // Call native code like this in your dart file
Run Code Online (Sandbox Code Playgroud)
然后实施这个
转到“android->app->src->main->kotlin->....你的应用程序名称->MainActivity.kt”。
Add this
class MainActivity : FlutterFragmentActivity() {
private val channel = "externalStorage";
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channel).setMethodCallHandler { call, result ->
when (call.method) {
"getExternalStorageDirectory" ->
result.success(Environment.getExternalStorageDirectory().toString())
"getExternalStoragePublicDirectory" -> {
val type = call.argument<String>("type")
result.success(Environment.getExternalStoragePublicDirectory(type).toString())
}
else -> result.notImplemented()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18134 次 |
| 最近记录: |