How should i configure about images in pubsec.yml for nested structure - flutter

I've set simply the pubsec.yaml and it has been worked successfully as follows;
images/logo1.png
images/logo2.png
//pubsec.yml
# To add assets to your application, add an assets section, like this:
assets:
- images/
//indents are set appropriately
However, it doesn't work when I restructure as following and with no changings is pubsecyml;
images/main/logo1.png
images/sub/logo2.png
image_provider throws errors like
Future<ui.Codec> _loadAsync(AssetBundleImageKey key, DecoderBufferCallback? decode, DecoderCallback? decodeDepreacted) async {
if (decode != null) {
ui.ImmutableBuffer? buffer;
// Hot reload/restart could change whether an asset bundle or key in a
// bundle are available, or if it is a network backed bundle.
try {
buffer = await key.bundle.loadBuffer(key.name);
} on FlutterError {
PaintingBinding.instance.imageCache.evict(key);
rethrow;//here
}
if (buffer == null) {
PaintingBinding.instance.imageCache.evict(key);
throw StateError('Unable to read data');
}
return decode(buffer);
}
ScreenShot for pubsec.yml

Related

Flutter can't seem to find a Json file from relative path

I apologise in advance if this is a silly question, but I have created a file and stored it in my "assets" sub-directory, which is at the same level as my lib directory and my pubspec.yaml file. I've set the relative path to "assets/ExerData.json" in my code (see below).
When I run the code saved as a scratch.dart file as shown below, hitched up to a Galaxy Nexus API 29 emulator, it can only tell me "Can't find file!"
import 'dart:io';
import 'package:flutter/services.dart';
String filePath = "assets/ExerData.json";
void main() {
performTasks();
}
void performTasks() {
if (checkFileExists(filePath)) {
readFile(filePath);
} else {
print("Can't find file");
}
}
bool checkFileExists(path) {
bool result = File(path).existsSync();
print(result.toString());
return result;
}
Future<String> readFile(path) async {
return await rootBundle.loadString(filePath);
}
I populated my pubspec.yaml file with this entry:
assets:
- assets/ExerData.json
I expected it to find my file, read it using rootbundle.loadstring(path), and print out the resulting string to the console.
As I say, all it did was print "Can't find file".
I'd very much appreciate you help on this one!
Thanks in advance!
The rootBundle contains the resources that were packaged with the app when it was built. All files specified under assets: in your pubspec are packaged with the app. You can check if file exists by wrapping rootBundle.loadString() inside try{} catch(){} block.
Future<bool> fileExists(String path) async {
try {
await rootBundle.loadString(path);
} catch (_) {
return false;
}
return true;
}
or
Future<String?> loadFile(String path) async {
try {
return await rootBundle.loadString(path);
} catch (_) {
// File not found Exception
return null;
}
}
File is a dart class. It needs absolute or relative path of the file being read.
You can use File with path_provider to get the absolute path from the current File System.
For example on Android:
Future<void> getPath() async {
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
print('PATH IS : $appDocPath');
}
prints
'/data/user/0/com.soliev.file_demo/app_flutter'
Use:
String data = await DefaultAssetBundle.of(context).loadString("assets/ExerData.json");
final jsonResult = jsonDecode(data);
Reference: How to load JSON assets into a Flutter App?
As it turns out, the program logic had not completed initializing the necessary binding.
I called the method WidgetsFlutterBinding.ensureInitialized() in the first line of the main class and everything started working as I expected.
Thanks to everyone who looked at my question!
Here's a similar question involving binding with XML files:
How to read XML files in flutter?

Load an image with either JPG extension or PNG one

In my Flutter app, I return asset (product image) name by:
class Product {
// ...
final int id;
// ...
String get assetName => '$id-0.jpg';
}
And later, I use the asset name like:
// ...
image: AssetImage(product.assetName),
// ...
Now, the problem is some of the images are *.jpg and some are *.png like:
Is there a way to tell the Flutter image loader to try to load '$id-0.jpg' and if the file doesn't exist, then try to load '$id-0.png'? Perhaps I can do that with regular expressions, but I cannot figure out how.
You can determine if an asset exists with rootBundle.load and a try-catch block. rootBundle.load will throw an exception if the asset is not found.
ByteData image;
try{
image = await rootBundle.load(assetNameHere.jpg);
}
catch(e) {
image = await rootBundle.load(assetNameHere.png);
}
I don't know the exception that this will throw on the asset not existing, so I can't tell you which error to catch on, but you can figure that out and modify your code to only do the png code on that exception type instead of everything.
With this method, since you're already forced to load the image into memory, you can store the ByteData and use MemoryImage instead of AssetImage.

How to record a video with Camera Plugin in flutter?

I have this page where the camera is initialized and ready with a button that will record and stop the video, so I tried this :
FlatButton(
onPressed: () => {
!isRecording
? {
setState(() {
isRecording = true;
}),
cameraController.prepareForVideoRecording(),
cameraController.startVideoRecording('assets/Videos/test.mp4')
}
: cameraController.stopVideoRecording(),
},
............
but throws this error : nhandled Exception: CameraException(videoRecordingFailed, assets/Videos/test.mp4: open failed: ENOENT (No such file or directory)).
I don't understand, I don't want to open this file I want to save it there, Is there sth wrong with my code ?
In the new version, static method startRecordingVideo doesn't take any string parameter.
When you want to start the recording just see whether a video is already getting recorded, if not start
if (!_controller.value.isRecordingVideo) {
_controller.startVideoRecording();
}
and when you want to finish the recording you can call the static method stopVideoRecording() and it will give you a object of the class XFile, it will have the path to your video.
if (_controller.value.isRecordingVideo) {
XFile videoFile = await _controller.stopVideoRecording();
print(videoFile.path);//and there is more in this XFile object
}
This thing has worked for me. I am new to flutter please improve my answer if you know more.
You are trying to save a video in your assets folder which is not possible ,
What you need to do is to save to device locally either common folders like downloads or app directory.
Here is an example of how to go about it
dependencies:
path_provider:
Flutter plugin for getting commonly used locations on host platform
file systems, such as the temp and app data directories.
We will be saving the video to app directory.
We need to get the path to the directory where the file is or will be. Usually a file is put in the application's document directory, in the application's cache directory, or in the external storage directory. To get the path easily and reduce the chance of type, we can use PathProvider
Future<String> _startVideoRecording() async {
if (!controller.value.isInitialized) {
return null;
}
// Do nothing if a recording is on progress
if (controller.value.isRecordingVideo) {
return null;
}
//get storage path
final Directory appDirectory = await getApplicationDocumentsDirectory();
final String videoDirectory = '${appDirectory.path}/Videos';
await Directory(videoDirectory).create(recursive: true);
final String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
final String filePath = '$videoDirectory/${currentTime}.mp4';
try {
await controller.startVideoRecording(filePath);
videoPath = filePath;
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
//gives you path of where the video was stored
return filePath;
}

How can I display the splash screen, getSpashScreen always returns null

In my small standalone JavaFX app I try to display the splash screen from the initialize method in my controller class:
SplashScreen splash = null;
try {
splash = SplashScreen.getSplashScreen();
if (splash == null) {
System.out.println("Splash is null");
} else if (!splash.isVisible()) {
System.out.println("Splash is NOT visible");
} else {
System.out.println("Splash is visible");
Thread.sleep(3500l);
}
} catch (UnsupportedOperationException ue) {
System.out.println("Spash not supported.");
} catch (InterruptedException ie) {
System.out.println("Spash sleep interrupted.");
} finally {
if (splash != null) {
splash.close();
}
}
It always returns null.
The manifest.mf file:
Manifest-Version: 1.0 X-COMMENT: Main-Class will be added
automatically by build SplashScreen-Image: Images/Splash.png
Images/Splash.png
When clean and build produces this information:
Adding splash image reference: src/firemappermetadatatool/Images/Splash.png
I've also edited, following other's recommendations I found when using Google, the project's configuration file adding the path to the Splash.png.
But splash is always null. What am I doing wrong or not doing?
Under Set Configuration->Customize->Run->VM Options I used the wrong base folder for the path to Splash.png. The correct option is
-splash:src/firemappermetadatatool/Splash.png

What path format should I use with bitmapfactory.decodeFile(string pathname)?

I want to use the function bitmapfactory.decodeFile(string pathname).
But on using it, NULL is being returned.
Please specify what or how to WRITE the PATHNAME, with an example.
for(int j=0;j<3;j++)
{
img_but[count].setImageBitmap(BitmapFactory.decodeFile("/LogoQuiz/res/drawable-hdpi/logo0.bmp"));
linear[i].addView(img_but[count]);
count++;
}
Instead of such a pathname, what should be used?
If you want to use filenames, then you can not put them inside the drawable folder. The only way you can do this is by putting the images inside the assets folder. If you do not have an assets/ folder, then you must create one inside your main project. It should be in the same branch as your gen/, res/, and src/ folders.
You can have any file structure in your assets folder you want. So for example, you can put your images in the assets/images/ folder. Sound files can go in a assets/sounds/ folder. You access an image like so:
public Bitmap getBitmap(Context ctx, String pathNameRelativeToAssetsFolder) {
InputStream bitmapIs = null;
Bitmap bmp = null;
try {
bitmapIs = ctx.getAssets().open(pathNameRelativeToAssetsFolder);
bmp = BitmapFactory.decodeStream(bitmapIs);
} catch (IOException e) {
// Error reading the file
e.printStackTrace();
if(bmp != null) {
bmp.recycle();
bmp = null
}
} finally {
if(bitmapIs != null) {
bitmapIs.close();
}
}
return bmp;
}
The path name, as the variable name suggests, should be relative to the assets/ folder. So if you have the images straight in the folder, then it's simply imageName.png. If it's in a subfolder, then it's subfolder/imageName.png.
Note: Android will not choose from density folders in the assets folder. It decodes the images as-is. Any further adjustments for screen density and resolution will have to be done by you.
Opening a File from assets folder in android