EDIT: This question is about using AssetBundle, while that question (List of files in flutter) was about using Directory. They are different because of different classes. ALSO: I removed one section, that can be similar to previous question.
I don't understand how to use AssetBundle for accessing files...
For example, my assets in pubspec.yaml
assets:
- assets/images/
- assets/texts/
AssetBundle has methods: loadString(key, ...) and loadStructuredData(key, ...) - what is a key and how to use this methods?
I need to load data from text files and others files. I know that there is a rootBundle (or DefaultAssetBundle.of(context))... But how to use it to load files?!
Thanks!
Let's assume that you have an image clock.png in assets/images and a UTF-8 encoded text file distances.json in assets/texts.
The key is really just the path to the asset, so you might load the whole file as a String and decode the json like this:
String distancesText = await rootBundle.loadString('assets/texts/distances.json');
Map distances = json.decode(distancesText);
loadString takes care of the UTF-8 decode for you, and also caches the String for faster access next time.
loadStructuredData takes loadString one step further - it loads the String then calls your provided callback to parse the String and returns the result. This time it caches the decoded result - now saving the reading and decoding step the next time.
Map distances2 = await rootBundle
.loadStructuredData('assets/texts/distances.json', (String s) async {
return json.decode(s);
});
So, this is great for text files; what about binary files? You can read the whole asset as a byte array.
ByteData clockData = await rootBundle.load('assets/images/clock.png');
Uint8List clockBytes = clockData.buffer.asUint8List());
Now you can do whatever you need to do with the binary contents of the file. Note that unlike Strings, binary data isn't cached.
Of course, for a PNG, you would most likely not read it as bytes, but instead load it as an Image Widget with AssetImage. (Also asset images should have multiple resolutions for different DPI devices.) See Assets and Images.
I think that earlier you wanted to obtain a complete list of all the assets available. In some ways this makes no sense. You know which assets you provided at build time, so you could keep the list of assets somewhere yourself - in code or in your own manifest. If you really want to enumerate them at runtime, I think you can load an asset called AssetManifest.json, but this seems to be an implementation detail, so possibly subject to change.
Related
I'm trying to get all the Annotations eg: INK and save to the db from Android.
I have looked thru the PDFTron examples particularly ElementReaderAdvTest. I can follow where it process Element.e_path and prints out the path.
https://www.pdftron.com/documentation/samples/kt/ElementReaderAdvTest?platforms=android
How do I save each path data and later on I want to convert the path data to svg.
The PDF ISO standard defines an annotation data interchange format called FDF. FDF is a PDF file with no pages, and just annotations and/or form field values.
To just extract the annotations use the following
pdfviewctrl.docLockRead();
FDFDoc fdf = pdfviewctrl.getDoc().fdfExtract(PDFDoc.e_annots_only);
pdfviewctrl.docUnlockRead();
You can then save the FDF file as binary/pdf data in whatever storage you want. You do not have to save the annotated PDF, you can at anytime later on merge back.
doc.fdfMerge(fdf);
You would not go into the ElementReader sample code, that is too low level for what you want, and just FDFMerge and FDFExtract are probably all you need.
Business Purpose :
1) Want to add large string(data) of length 1200 to the .jpg / .mp4 file in android mobile
2) Later the file can be uploaded to server from mobile
3) In server we retrieve the added data from the file
What i have tried in .jpg file :
Used the below code for adding data
ExifInterface exif = new ExifInterface(photoPath);
exif.setAttribute("UserComment", "String having length of 1000");
exif.saveAttributes();
This code is working. After i set the attribute, i can able to read it by
String userComment=exif.getAttribute("UserComment");
In low end mobile it showed error "stack corruption detected: aborted" while saving attribute.Later i found it taken up to 663 characters alone.
In high end mobile the string of length saved up to 1999 after saveAttribute().
Is there any other way to add some tag/meta data/string to .jpg,.mp4 and .mp3 file ?
So that the added data can be retrieved later.
please share your views. Is it possible ?
It sounds as if it's certainly is possible using your approach, but you're running into various implementation limits in how long attribute values are supported.
One solution to at least investigate is of course to split your 1200-byte string into multiple shorter strings, say four 300-byte ones, and add those as UserComment0, UserComment1 and so on. That should be trivial to extract and concatenate to get back your original longer string, and might work around the limitations.
Praveen,
take a look at Steganography project
https://github.com/johnkil/Steganography
Thanks,
Jey.
In my Android project, I have a 2M-bytes raw data file. Since my application is a long-life app, I don't want it to always seize 2M memory. The data file has been formatted, once I need to some data from the data file, I just need to seek to some position and read several bytes.
The Resource class can only return an InputStream on raw file, but InputStream cannot do random read.
Is there a way on Android to random read some bytes from the raw data file? Or I have to read the entire file into memory when I only need a few bytes.
InputStream can skip bytes with skip() can also mark an offset with mark(), on reset() it can go back to marked position. All that can be used to do random IO.
You can store byte offsets in a separate lookup file as well.
Android is built upon Java so take a look at this tutorial:
http://docs.oracle.com/javase/tutorial/essential/io/rafs.html
Currently I can pass the path to an image in the sdcard. Now I want to pass a path to a folder(to the same function BitmapFactory.decodeFile(path)) so that all the images in the folder can be displayed using
image.setImageBitmap(img);
Basically, I want to display all the images in the selected folder as a slideshow, one after the other. Any help / pointers on this?
It's hard to tell exactly what you're asking for here. You've asked a very general question. I think what would be best for you is to use a Gallery widget.
The first step is getting URLs or paths to all the images. I can think of two alternatives.
1) List all files in whatever folder you are looking for and get the ones of the right type. You can use listFiles to get all the files in a folder:
File files[] = Environment.getExternalStorageDirectory().listFiles();
and string split or substring to get the extension
string filename = file[i].getName();
int pos = filename.lastIndexOf(".");
string ext = filename.substring(pos);
2) You can use a content resolver and get the images straight from the Android MediaStore. This solution would be more robust. Search for how to use the MediaStore if you want to use this.
Second step is to use BitmapFactory to get all the bitmaps you need. Yes, you will need to call decodeResource once for each bitmap you get from a file.
What I'm trying to accomplish is the following: Suppose I have a function that writes an image to a File directory (either SD or internal cache). After writing out the File, I perform a check to see if my image directory is within a certain total file size (right now, I'm using this function to recursively calculate the directory's file size). If the file that I just added makes that directory too big, then what I want to do is keep deleting older files until we are just below that max file size.
I was thinking of first sorting the File directory members from oldest first (via comparator, ascending order using this example), then convert the array into an ArrayList to get its Iterator, then while our directory file size is still above the max file size, and I still have files to iterate to, I delete the older files until I break out of that while loop. Is there a more efficient way of accomplishing this?
Your bottleneck is most likely going to be file system operations (ie: reading the directory contents and deleting the files), not the in-memory manipulation, so you probably shouldn't worry too much about the efficiency of the latter so long as you don't do something grossly inefficient.
The rough algorithm you describe sounds fine. You can avoid the ArrayList conversion by simply doing something like:
for (Pair pair : pairs) {
if (totalSize <= maxSize) {
break;
}
totalSize -= pair.f.length();
pair.f.delete();
}