mirror of
https://github.com/Iconica-Development/flutter_image_picker.git
synced 2025-05-18 19:53:45 +02:00
Merge 7458b06fc0
into d8e824191a
This commit is contained in:
commit
77faf267ae
5 changed files with 110 additions and 29 deletions
|
@ -1,6 +1,8 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.flutter_image_picker_example">
|
package="com.example.flutter_image_picker_example">
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="flutter_image_picker_example"
|
android:label="flutter_image_picker_example"
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: 2022 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_image_picker/flutter_image_picker.dart';
|
import 'package:flutter_image_picker/flutter_image_picker.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const ImagePickerExample());
|
runApp(const ImagePickerExample());
|
||||||
|
@ -103,6 +100,40 @@ class ImagePickerExampleHomePageState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> _requestPermission(Permission permission) async {
|
||||||
|
if (await permission.isGranted) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
var result = await permission.request();
|
||||||
|
if (result == PermissionStatus.granted) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showPermissionDeniedDialog() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Permission Denied'),
|
||||||
|
content: const Text(
|
||||||
|
'We need permission to access your media to use this feature.'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text('OK'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// The [pickImage] function is used to show the usage of the Image Picker Package.
|
/// The [pickImage] function is used to show the usage of the Image Picker Package.
|
||||||
/// The most important part is the [ImagePicker] call.
|
/// The most important part is the [ImagePicker] call.
|
||||||
/// You can add a custom [ImagePickerTheme] to the [ImagePicker] if you want to change some of the UI.
|
/// You can add a custom [ImagePickerTheme] to the [ImagePicker] if you want to change some of the UI.
|
||||||
|
@ -113,28 +144,33 @@ class ImagePickerExampleHomePageState
|
||||||
/// This function saves the image in a variable and if it's different than the current image it will get displayed in the application.
|
/// This function saves the image in a variable and if it's different than the current image it will get displayed in the application.
|
||||||
/// When the same image is chosen there will be a snackbar popping up to let you know it's already being displayed.
|
/// When the same image is chosen there will be a snackbar popping up to let you know it's already being displayed.
|
||||||
void pickImage() async {
|
void pickImage() async {
|
||||||
Uint8List? imageInBytes = await showModalBottomSheet<Uint8List?>(
|
if (await _requestPermission(Permission.storage)) {
|
||||||
context: context,
|
Uint8List? imageInBytes = await showModalBottomSheet<Uint8List?>(
|
||||||
backgroundColor: Colors.white,
|
context: context,
|
||||||
builder: (BuildContext context) => ImagePicker(
|
backgroundColor: Colors.white,
|
||||||
onError: (error) {
|
builder: (BuildContext context) => ImagePicker(
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
onError: (error) {
|
||||||
SnackBar(content: Text(error.message ?? "An error occurred")),
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
);
|
SnackBar(
|
||||||
},
|
content: Text(error.message ?? "An error occurred")),
|
||||||
));
|
);
|
||||||
if (imageInBytes != null) {
|
},
|
||||||
if (!listEquals(uploadedImage, imageInBytes)) {
|
));
|
||||||
setState(() {
|
if (imageInBytes != null) {
|
||||||
uploadedImage = imageInBytes;
|
if (!listEquals(uploadedImage, imageInBytes)) {
|
||||||
});
|
setState(() {
|
||||||
} else {
|
uploadedImage = imageInBytes;
|
||||||
if (!mounted) return;
|
});
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
} else {
|
||||||
SnackBar(content: Text(imageAlreadyDisplayedMessage)),
|
if (!mounted) return;
|
||||||
);
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(imageAlreadyDisplayedMessage)),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
imageInBytes = null;
|
||||||
|
} else {
|
||||||
|
_showPermissionDeniedDialog();
|
||||||
}
|
}
|
||||||
imageInBytes = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
lib/src/services/permission_service.dart
Normal file
16
lib/src/services/permission_service.dart
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
class PermissionService {
|
||||||
|
Future<bool> checkAndRequestPermission(Permission permission) async {
|
||||||
|
if (await permission.isGranted) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
var result = await permission.request();
|
||||||
|
if (result == PermissionStatus.granted) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: 2022 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter/services.dart";
|
import "package:flutter/services.dart";
|
||||||
import "package:flutter_image_picker/flutter_image_picker.dart";
|
import "package:flutter_image_picker/flutter_image_picker.dart";
|
||||||
import "package:image_picker/image_picker.dart";
|
import "package:image_picker/image_picker.dart";
|
||||||
|
import 'package:flutter_image_picker/src/services/permission_service.dart';
|
||||||
|
|
||||||
/// The Image Picker class generates the Image Picker Widget which can be
|
/// The Image Picker class generates the Image Picker Widget which can be
|
||||||
/// displayed in your application. If you call the class you can give it 4
|
/// displayed in your application. If you call the class you can give it 4
|
||||||
|
@ -141,6 +138,14 @@ class ImagePicker extends StatelessWidget {
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
var navigator = Navigator.of(context);
|
var navigator = Navigator.of(context);
|
||||||
Uint8List? image;
|
Uint8List? image;
|
||||||
|
var permissionService = PermissionService();
|
||||||
|
bool hasPermission = await permissionService.checkAndRequestPermission(
|
||||||
|
imageSource == ImageSource.camera ? Permission.camera : Permission.photos,
|
||||||
|
);
|
||||||
|
if (!hasPermission) {
|
||||||
|
_showPermissionDeniedDialog(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
image = await (service ?? ImagePickerServiceDefault())
|
image = await (service ?? ImagePickerServiceDefault())
|
||||||
.pickImage(imageSource, config: config);
|
.pickImage(imageSource, config: config);
|
||||||
|
@ -163,4 +168,25 @@ class ImagePicker extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void _showPermissionDeniedDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Permission Denied'),
|
||||||
|
content: const Text(
|
||||||
|
'We need permission to access your media to use this feature.'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text('OK'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
|
permission_handler: ^10.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in a new issue