无法在Flutter Web上使用图像选择器选择图像(MissingPluginException)



下面我分享我的flutter代码,只需选择图像并在获得所需权限后将其显示在屏幕上。代码,然而,在Android上运行良好,但当我尝试在web上上传图像时,给出了MissingPluginException(No implementation found for method requestPermissions on channel flutter.baseflow.com/permissions/methods)异常。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Project2',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File _file = File("zz");
uploadImage() async {
final ImagePicker _picker = ImagePicker();
final XFile? image;
var permissionStatus = requestPermissions();
if (await permissionStatus.isGranted) {
image = await _picker.pickImage(source: ImageSource.gallery);
var selected = File(image!.path);
setState(() {
_file = selected;
});
} else {
showToast("Permission not granted");
}
}
Future<PermissionStatus> requestPermissions() async {
await Permission.photos.request();
return Permission.photos.status;
}
void showToast(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Upload Image"),
),
body: Column(
children: [
(_file.path != "zz")
? Image.file(_file)
: Image.asset("assets/img/images.jpeg"),
SizedBox(
height: 20,
width: double.infinity,
),
ElevatedButton(
onPressed: () => uploadImage(),
child: Text("Upload"),
)
],
),
);
}
}

下面是按下上传按钮生成的堆栈轨迹:

Error: MissingPluginException(No implementation found for method requestPermissions on channel flutter.baseflow.com/permissions/methods)
at Object.throw_ [as throw] (http://localhost:64931/dart_sdk.js:5041:11)
at MethodChannel._invokeMethod (http://localhost:64931/packages/flutter/src/services/system_channels.dart.lib.js:943:21)
at _invokeMethod.next (<anonymous>)
at http://localhost:64931/dart_sdk.js:37403:33
at _RootZone.runUnary (http://localhost:64931/dart_sdk.js:37274:59)
at _FutureListener.thenAwait.handleValue (http://localhost:64931/dart_sdk.js:32530:29)
at handleValueCallback (http://localhost:64931/dart_sdk.js:33057:49)
at Function._propagateToListeners (http://localhost:64931/dart_sdk.js:33095:17)
at _Future.new.[_completeWithValue] (http://localhost:64931/dart_sdk.js:32943:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:64931/dart_sdk.js:32964:35)
at Object._microtaskLoop (http://localhost:64931/dart_sdk.js:37526:13)
at _startMicrotaskLoop (http://localhost:64931/dart_sdk.js:37532:13)
at http://localhost:64931/dart_sdk.js:33303:9

pubspec.yamlfile:

environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
image_picker: ^0.8.3+3
permission_handler: ^8.1.4+2
fluttertoast: ^8.0.8
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter

flutter:
uses-material-design: true
assets:
- assets/img/images.jpeg

PS:flutter cleanflutter run不支持Web版本

问题在于Web中的权限处理程序包。权限处理程序包仅为Android和IOS构建,并且在Web平台上上传图像不需要权限,因此在Web上使用它会给MissingPluginException

通过为Web和移动平台添加条件语句和单独实现解决了这个问题。

要检查平台是否为web,您首先需要添加:

import 'package:flutter/foundation.dart' show kIsWeb;

uploadImage()方法更改为:

uploadImage() async {
var permissionStatus = requestPermissions();
// MOBILE
if (!kIsWeb && await permissionStatus.isGranted) {
final ImagePicker _picker = ImagePicker();
XFile? image = await _picker.pickImage(source: ImageSource.gallery);
if (image != null) {
var selected = File(image.path);
setState(() {
_file = selected;
});
} else {
showToast("No file selected");
}
}
// WEB
else if (kIsWeb) {
final ImagePicker _picker = ImagePicker();
XFile? image = await _picker.pickImage(source: ImageSource.gallery);
if (image != null) {
var f = await image.readAsBytes();
setState(() {
_file = File("a");
webImage = f;
});
} else {
showToast("No file selected");
}
} else {
showToast("Permission not granted");
}
}

然后最后在build()方法中添加Web和Android Image的单独实现:

File _file = File("zz");
Uint8List webImage = Uint8List(10);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Upload Image"),
),
body: Column(
children: [
(_file.path == "zz")
? Image.asset("assets/img/images.jpeg")
: (kIsWeb)
? Image.memory(webImage)
: Image.file(_file),
SizedBox(
height: 20,
width: double.infinity,
),
ElevatedButton(
onPressed: () => uploadImage(),
child: Text("Upload"),
)
],
),
);
}

相关内容

  • 没有找到相关文章

最新更新