Flutter pick image dynamically for web and mobile - flutter

I'm working on an editor which needs to work on both web and mobile. So the core functionalities will remain same but the UI part will change.
Within that core part I have a portion which works with images. As the File object comes from both dart:io and dart:html I am facing some issues with getter setters.
Where I want to show the image:
Widget buildImage() {
return Image.file(
widget.item!.imageFile,
fit: widget.item!.imageFit,
color: widget.item!.color,
colorBlendMode: widget.item!.blendMode,
alignment: widget.item!.alignment,
gaplessPlayback: true,
excludeFromSemantics: true,
);
}
widget.item!.imageFile is a getter setter that I worked on the mobile counter part:
io.File get imageFile => io.File(_image!.image.filename);
set imageFile(io.File value) => _image!.image.filename = value.path;
But as now I will have to make the code work on the web version as well I tried:
if (isWeb) {
await _pickImageWeb();
} else {
// some code for mobile
}
And the _pickImageWeb() is as below:
_pickImageWeb() async {
final ImagePicker _picker = ImagePicker();
XFile? image = await _picker.pickImage(source: ImageSource.gallery);
if (image != null) {
var imageBytes = await image.readAsBytes();
setState(() {});
}
}
At this point I'm completely lost and I think I went the wrong way. Since till now I was my images from the path using getter setter and now in web the image picking is completely different.
Should I have multiple getter setters for both mobile and web i.e: imageFileMobile and imageFileWeb?
Or how to solve the issue in general. I have seen file_picker but couldn't figure out how to integrate the package in this case.

dart:io doesn't work with web, and vice versa for dart:html, I would suggest using cross_file and store the result in XFile and use it as file.readAsBytes(), because flutter web gives fake paths when selecting files, so going with bytes seems to be the best option IMO.

Related

Why won't my image show up after picking from image_picker in Flutter?

I have been using image_picker: ^0.8.4+9 for the past couple of months with no problems. Today whenever I try to pick an image the gallery opens and I am able to pick an image, however once thats done the image doesn't appear on the screen. No errors and I update my github with it everyday and checked to see if something was changed but nothing was. I've tried using other versions only to have the same problem. I understand that this is an issue with M1 Macs sometimes, however why would it suddenly stop working using the same version? I have seen other questions similar like this. I have the correct permissions and there hasn't been a thing changed since it was last working. This could be a problem I cannot fix due to it being an iOS issue or something else but I wanted to see if anyone else is having this issue. Can't test on a physical device since I am on iOS beta but still it was working on the sim so that shouldn't matter.
Here is the basic function of getting am image and storing it:
File? pickedImage;
Future pickImage() async {
final _imagePicker = ImagePicker();
final pickedImage =
await _imagePicker.pickImage(source: ImageSource.gallery);
final imageTemp = File(pickedImage!.path);
setState(() => this.pickedImage = imageTemp);
}
Here is the button to initiate the gallery and pick the image:
ElevatedButton(
onPressed: () async {
final _imagePicker = ImagePicker();
final pickedImage = await _imagePicker.pickImage(
source: ImageSource.gallery);
final imageTemp = File(pickedImage!.path);
setState(() => this.pickedImage = imageTemp);
},
child: const Text('Add Image')),
const SizedBox(height: 20),
// The image should show here if not null else the 'No image' text
pickedImage != null
? Image.file(pickedImage!, height: 200, width: 200)
: Text('No Image'),
EDIT: As Vandad linked in the comment below, it seems this is a newer issue. Here is the discussion. github.com/flutter/flutter/issues/98569

Flutter + Google Maps: how to remove system markers?

I am developing a flutter app, trying to add Google Maps using the official plugin, however, there are tons of system markers that I don't know how to remove.
The markers are from Google's own database, but we really don't need that extra information, they are causing issues with our users because users thought the markers are from our own app! Big user experience issue.
I couldn't find a switch or something like that from the class GoogleMap.
Any ideas? thanks!
This can be achieved by applying custom google map styles to your google map.
To create custom google map styling. Use this tool to generate a map_style.json and save it in your assets folder. (Make sure it is referenced in pubspec.yaml aswell).
//this is the function to load custom map style json
void changeMapMode(GoogleMapController mapController) {
getJsonFile("assets/map_style.json")
.then((value) => setMapStyle(value, mapController));
}
//helper function
void setMapStyle(String mapStyle, GoogleMapController mapController) {
mapController.setMapStyle(mapStyle);
}
//helper function
Future<String> getJsonFile(String path) async {
ByteData byte = await rootBundle.load(path);
var list = byte.buffer.asUint8List(byte.offsetInBytes,byte.lengthInBytes);
return utf8.decode(list);
}
Implement it like this in your google map widget:
GoogleMap(
...
onMapCreated: (GoogleMapController c) {
yourMapController = c;
changeMapMode(yourMapController);
},
),

Flutter remove image after upload using image_picker package

I have managed to upload an image using the image picker package as shown below:
final picker = ImagePicker();
Future selectPhoto() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
}
The image has been displayed on the device where I have a remove button which I can use to remove the image and upload another before saving it.
child: Container(
height: height * 0.2,
width: width * 0.2,
child: Image.file(
_image,
fit: BoxFit.fill,
),
),
My question is how can I remove the image from cache as this piece is not working
onTap: () {
setState(() {
imageCache.clear();
print('removes $_image');
});
},
You have a misunderstanding of what the cache is compared to explicitly storing a file in memory with your code. Flutter may store images that you use in widgets in a cache so that they may load faster in the future. imageCache.clear(); does clear the cache and is likely doing it's work in your code. However, your method of checking if the image is still cached is flawed.
imageCache.clear(); only clears the cache, it does not delete the file that you're passing to the Image.file widget. This means that _image(the file variable you have stored in memory) will persist even over the cache clearing. To truly delete this image you could use the delete method or if you just want to stop showing the image, deference the file by setting the file reference to null:
_image = null;
Solved it by calling a method within the button which had set state method where the path was returned back to null
clearimage() {
setState(() {
_image = null;
});
}

Flutter - How to check is the app has a new version?

I create an app with Flutter. I need to force users to update the app when I upload a new version. I try this package, but I think that it doesn´t work. In the documentation, we can read that we can verify the version with this code.
Container(
margin: EdgeInsets.fromLTRB(12.0, 0.0, 12.0, 0.0),
child: UpgradeCard();
)
The problem is: I need to check the version in *'initState', not in Scaffold. So what is the right way to check the version on the app start?
I recommend trying out the Firebase Remote Config and update the minimum required version there. It's not a good practice to force update app on every update in the store. Also, some users can see the updated version in given store later than others. This is just how Google Play and AppStore work.
Thus, when you really need to force update the application you can increment the parameter on Firebase e.g. a day after update in the store.
Simple code to trigger the dialog can look as following:
Future<bool> checkUpdates() async {
await remoteConfig.fetch();
await remoteConfig.activateFetched();
final requiredBuildNumber = remoteConfig.getInt(Platform.isAndroid
? 'requiredBuildNumberAndroid'
: 'requiredBuildNumberIOS');
final currentBuildNumber = int.parse(packageInfo.buildNumber);
return currentBuildNumber < requiredBuildNumber;
}
This requires package_info package to be added as well as firebase_remote_config.
To open the app in the store you need to use url_launcher package and just pass URL to your app.
you can call https://itunes.apple.com/lookup?bundleId=$id or https://play.google.com/store/apps/details?id=$id to receive the newest app version available on the stores.
i can recommend this package to do this: https://pub.dev/packages/new_version
You can check your app version like
#override
void initState() {
super.initState();
Timer(
Duration(seconds: 3), // put your stuff here
() => Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => LoginScreen())));}
and presume one thing this code must be in spalsh screen or home screen
and there you can check app version forcefully stop any app which is belonged old version
Try out the in app update package- https://pub.dev/packages/in_app_update which works on Android and for iOS, try- https://pub.dev/packages/upgrader.
Use this package -> new_version
It's awesome & easy :)
///initialize your variable
final newVersion = NewVersion(
iOSId: 'com.google.Vespa',
androidId: 'com.google.android.apps.cloudconsole',
);
//and use this inside of your widget or controller
#override
Widget build(BuildContext context) {
newVersion.showAlertIfNecessary(context: context);
return Container();
}
If you just want the current version number from the App Store and Play Store. You can use the upgrader package API like this:
import 'dart:developer';
import 'dart:io';
import 'package:html/dom.dart';
import 'package:upgrader/upgrader.dart';
Future<String?> getStoreVersion(String myAppBundleId) async {
String? storeVersion;
if (Platform.isAndroid) {
PlayStoreSearchAPI playStoreSearchAPI = PlayStoreSearchAPI();
Document? result = await playStoreSearchAPI.lookupById(myAppBundleId, country: 'US');
if (result != null) storeVersion = PlayStoreResults.version(result);
log('PlayStore version: $storeVersion}');
} else if (Platform.isIOS) {
ITunesSearchAPI iTunesSearchAPI = ITunesSearchAPI();
Map<dynamic, dynamic>? result =
await iTunesSearchAPI.lookupByBundleId(myAppBundleId, country: 'US');
if (result != null) storeVersion = ITunesResults.version(result);
log('AppStore version: $storeVersion}');
} else {
storeVersion = null;
}
return storeVersion;
}
EDIT: If your app is NOT available on the US App Store or Play Store, you need to change the country code.

How to avoid app crash when picking a image with flutter and image_picker package? [duplicate]

This question already has answers here:
How to solve the image picker crash app error?
(6 answers)
Closed 3 years ago.
I'm building a application for taking photos and send them into firestore, i'm using image_picker :0.5.0+8 when I'm trying to pick a image from camera or from gallery the app crash. it open gallery very well or the camera very well but if a choose a picture the app crash.
this is my code:
File image_state; AppState state;
bool isLoading; bool isShowSticker; String _imageUrl;
Future getImage() async {
var tempImage = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
image_state = tempImage;
state = AppState.picked;
});
File croppedFile = await ImageCropper.cropImage(
sourcePath: image_state.path,
ratioX: 1.0,
ratioY: 1.0,
toolbarTitle: 'Cropper',
toolbarColor: Colors.blue,
);
if (croppedFile != null) {
image_state = croppedFile;
setState(() {
state = AppState.cropped;
});
} }
is there some one who work with this librairy? can you show me an example that work please?
issue
There are example of usages inside the plugin's repo.
It may be related to AndroidX compability. You have to avoid AndroidX or migrate your project to AndroidX.
There were a breaking change after version 0.5.0