Turning String into File or vice versa in Flutter - flutter

I have a little question I have been banging my head on for a few days.
void _loadImage() async {
SharedPreferences saveImage = await SharedPreferences.getInstance();
setState(() {
if (_imagepath == null) {
_imagepath = MemoryImage(kTransparentImage);
}else{
_imagepath = saveImage.getString('imagepath');
}
});
}
So I have this function to save the image to shared preferences, but would like for if else check before it executes that if the path (which is a string) is null, it turns to transparent, and if not, to just regular path. This syntax obviously doesn't work since the String doesn't equal to File:
_imagepath = MemoryImage(kTransparentImage);
Where the _imagepath is a String (a path) and the MemoryImage is a File.
Is there a simple solution to make this work within a function?

If you have to do it in this function then you can do it like this:
ImageProvider _image;
void _loadImage() async {
SharedPreferences saveImage = await SharedPreferences.getInstance();
setState(() {
if (_image == null) {
_image = MemoryImage(kTransparentImage);
} else {
var path = saveImage.getString('imagepath');
var file = File(path);
_image = FileImage(file);
}
});
}
#override
Widget build(BuildContext context) {
return Image(image: _image);
}

Related

'file.absolute.existsSync()': is not true on uploading multiple files to storage flutter firebase

I'm trying for so long to upload multiple selected files to firebase storage but getting the same error again and again.
I'm picking up multiple files, they are getting picked just fine I've printed files they are going to the List just fine but when it comes to uploading it gives this error
Unhandled Exception: 'package:firebase_storage/src/reference.dart': Failed assertion: line 127 pos 12: 'file.absolute.existsSync()': is not true.
This error is coming on my uploadTask which is
UploadTask uploadTask = storageReference.putFile(File(fileNames![i]));
I've tried so much but couldn't do so. If anyone knows what I'm doing wrong please let me know.
Here's the complete of the code
List<String>? fileNames;
List<String> downloadUrls = [];
bool isUploading = false;
#override
Widget build(BuildContext context) {
Future<void> filePicker() async {
FilePickerResult? result =
await FilePicker.platform.pickFiles(allowMultiple: true);
if (result != null) {
setState(() {
fileNames =
result.paths.map((path) => path!.split('/').last).toList();
});
}
}
Future<void> uploadFiles() async {
setState(() {
isUploading = true;
});
for (int i = 0; i < fileNames!.length; i++) {
String fileName = fileNames![i];
String filePath = 'files/$fileName';
final storageReference =
FirebaseStorage.instance.ref().child('reports/$filePath');
UploadTask uploadTask = storageReference.putFile(File(fileNames![i]));
await uploadTask.whenComplete(() {
storageReference.getDownloadURL().then((fileURL) {
downloadUrls.add(fileURL);
});
});
}
setState(() {
isUploading = false;
});
}

Image Picker does not work properly with google_mlkit_object_detector only on IOS Simlutor

Once i added the google_mlkit_object_detector then the image_picker stopped working. i can access the gallery but there's no image will return when added this package.
void _incrementCounter() async {
print('start');
image = await ImagePicker().pickImage(source: ImageSource.gallery); // IT WILL STOP HERE AND CAN"T PROCESS THE EXECUTION
print('succeed');
setState(() {});
}
void processing() async {
final inputImage = InputImage.fromFile(File(image!.path));
final objectDetector = ObjectDetector(
options: ObjectDetectorOptions(mode: DetectionMode.singleImage));
final List<DetectedObject> objects =
await objectDetector.processImage(inputImage);
for (DetectedObject detectedObject in objects) {
final rect = detectedObject.boundingBox;
final trackingId = detectedObject.trackingId;
for (Label label in detectedObject.labels) {
print('${label.text} ${label.confidence}');
}
}
}

Why is this List returning null?

I have this code here in my provider, whenever I call getSongs the returned mp3s is null. I have it coded this way so that I can memoize mp3s.
class Songs with ChangeNotifier {
final tagger = Audiotagger();
List<Tag?>? mp3s;
Future<Tag?> getTags(String path) async {
final Tag? tag = await tagger.readTags(path: path);
return tag;
}
Future<Uint8List?> getArtwork(String path) async {
final Uint8List? artwork = await tagger.readArtwork(path: path);
return artwork;
}
Future<List<Tag?>> getSongs() async {
if (mp3s == null) {
final directory = Directory('/storage/emulated/0/Download');
List<FileSystemEntity> _files;
List<Tag?> _songs = [];
_files = directory.listSync(recursive: true, followLinks: false);
for (FileSystemEntity entity in _files) {
String path = entity.path;
if (path.endsWith('.mp3')) {
_songs.add(await getTags(path));
}
}
mp3s = _songs;
} else {
return mp3s!;
}
return mp3s!;
}
}
Actually, the problem to this is that there's a mp3 file that threw an error, because of this, it caused _songs to be null and therefore mp3s to be null.

Change bool in initState flutter

I have a page with this code:
class _HomeScreenState extends State<HomeScreen> {
bool isFirstLoading = true;
#override
void initState() {
super.initState();
if (isFirstLoading) {
getInfo();
setState(() {
isFirstLoading = false;
});
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Loader.show(context,
isAppbarOverlay: true,
isBottomBarOverlay: true,
progressIndicator: CircularProgressIndicator());
var url = kLinkAPI + "/getInfo";
var response =
await http.post(url, headers: {"Content-Type": "application/json"});
var resObj = jsonDecode(response.body);
if (response != null) {
setState(() {
if (resObj.length > 0) {
address = resObj[0]['address'];
countryInfo = resObj[0]['country_info'];
phone = resObj[0]['phone'];
latitude = resObj[0]['latitude'];
longitude = resObj[0]['longitude'];
isFirstLoading = false;
prefs.setString('address', address);
prefs.setString('countryInfo', countryInfo);
prefs.setString('phone', phone);
prefs.setString('latitude', latitude);
prefs.setString('longitude', longitude);
}
});
}
Loader.hide();
}
void getInfoFromSharedPref() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
address = prefs.getString('address');
countryInfo = prefs.getString('countryInfo');
phone = prefs.getString('phone');
latitude = prefs.getString('latitude');
longitude = prefs.getString('longitude');
});
}
}
I would like to make sure that the first time I enter the page, the isFirstLoading variable is set to false and then calls the getInfo function with the http call while if it is false it takes from the shared preferences.
isFirstLoading is now always true
how could I solve?
I think you're overcomplicating your code. Let me know if this solves your issue.:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs;
#override
void initState() {
super.initState();
getInfo();
}
// ...
}
Now, the first time this widget is inserted into the tree:
initState() will be called once.
Therefore, getInfo() will be called. getInfo() will make the http call and update the prefs variable using setState, which you have already done.
Whenever the widget is reloaded, the prefs variable will not be lost since it is a stateful widget.
Next, if you would like to save the preference settings locally instead of making an http call every time the user opens the app, you should handle that inside of getInfo() itself. Something like this:
getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (prefs.getBool("isFirstLoading") == false) {
// setState to update prefs variable
} else {
// make http call
// save prefs (optional)
// setState to update prefs variable
}
}
If I undestand correctly, you are trying to only call the getInfo method on the first load, and the getInfoFromSharedPref all the other time.
My suggestion is to save the isFirstLoading bool as a preference like so:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLoading = prefs.getBool("isFirstLoading") ?? true;
#override
void initState() async {
super.initState();
if (isFirstLoading) {
await getInfo();
await prefs.setBool("isFirstLoading", false);
isFirstLoading = false;
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
// …
}
void getInfoFromSharedPref() async {
// …
}
}

How to save a list with SharedPreferences?

I tried to save a List (which is called test)with two variables with SharedPreferences. I tried the code below, but I get some errors. Does anybody see the mistake i made? (I think it´s kind of an easy to fix mistake, but I´m a beginner and can´t find it ;)
int counter1 = 0;
int counter2 = 20;
String nameKey = "eins";
var test = [counter1, counter2];
#override
void initState() {
super.initState();
}
Future<bool> save() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return await preferences.setIntList(nameKey, test);
}
Future<List<int>> load() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getIntList(nameKey);
}
set() {
load().then((value) {
setState(() {
test = value;
});
});
}
Thanks in advance :)
Future<List<String>> load() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getStringList(nameKey);
}