How to access the picture in SDCARD with phonegap on Android system - java

I have created a canvas(html5) element to let the user draw on it, after the drawing, they can save(a button) it: canvas.toDataURL("image/png"); will be
executed and the encoded base64 dataURL string will be stored to a file. But I need to let the user view his paintings.
Here is the question: As the user save many story strings in a text file and the filesystem read the it, the memory will leak.
PhoneGap complains: java.lang.OutOfMemoryError, because the user saved too much dataURL strings. As all of them have to be reloaded to an array, error happens.
I suppose that if I save the user's drawing in image format(.jpg) instead of base64 dataURL, will it work?
Will it solve the memory leak issue?
How can I retrieve the images which are stored in the path like: sdcard/story/pics/ ?
If I just want to access a recorded file, I can write:
var record= new Media(src,onSuccess, onError); where the src could just be: story/rec/something.mp3
But the I can't access the image like this way.
The solution should also work on iOS, because I have to deploy the app to iPad.
Develop Environment:
PhoneGap 1.8.0
Android 4.0.3

I ran into a similar problem with binary files, and the bad news is that you cannot write binary data to the file system, as binary data cannot be transferred across the bridge into the native code.
I ended up writing a plugin to do the binary manipulation (or rather three plugins, one for iOS, another for Android and a third for BlackBerry).
I'm not sure what is causing you memory leak, but I would suggest only having one drawing in memory at once, unless you allow copy and paste between images, in which case I'd limit the app to two images in memory at once.
Whatever the leak is, it would have to be severe to use up all available memory, as most modern Android devices have quite a bit of memory on them.

Related

How to identify in which storage device a file is

I'm developing a Java software that reads lots of possibly big files.
I'll try to parallelize it, so it reads in parallel files from different devices (HDD, SSD, flash drive, SMB, etc) and only 1 file at a time from each device. But for that I'd need to know in which device a given file is.
On Windows I guess I could just use substring its path for the drive letter, but for Linux I have no idea how that could be done. Is there a standardized way to do it?
The sun.nio.fs.UnixFileAttributes class, which is used for PosixFileAttributes, contains a st_dev field. Unfortunately, it is not public accessible, you might have to use reflection to get the value.
A different approach would be to call stat on the file and read the device id that way. Then you can use the device id to find out which device the file is on.
Also you might want to check the output of mount to check the paths you are using and where they are mounted on.

Static images in webpage from Google App Engine

I'm porting an old Java project to GAE. It has some servlets, which generate html pages with static images in them. In the original project these images are stored on the filesystem next to the servlets.
I'm trying to use GCS in the first place, I've uploaded my files and gave permissions on public read. In this case I can reach the files with their public link, I can embed these links into the HTML output. But I have a feeling that this isn't the right solution. The load time seems quite slow, like the images don't "travel internally", and I have to provide permission for every single image.
So my question is, how to get an "internal" URL for a file located on GCS in your GAE application?
I've found some Java examples, but in my case I don't think I need the image object in the source, I just need an URL to pass it on to the HTML source.
As far as I know I could just simple deploy the images with the source as resources, but there are quite many of them.
If there are other soultions, like Datastore, I'm open for that too, but I thought GCS would be the easiest.
Google Cloud Storage is as fast an option for loading images as any other. A browser reads a link and asks the server (in this case GCS) to deliver an image. There is no "internal" URL that can work faster - the speed reflects the bandwidth/distance between GCS and the browser which asked for an image.
You can speed it up by using a CDN, where your image is stored on local servers throughout the world. It only makes sense if you serve content to a very large number of users, and it is a critical part of how fast a page loads.
Another way to speed up page load time is to use image sprites instead of images. This way you cut the number of requests from a browser to a server (i.e. GCS). If you images do not change frequently, and most pages need the same "collection" of images (i.e. not shown dynamically), this is a very good solution.

where on android to save files downloaded from server

I am downloading a number of images from the server. That happens once in a while (i.e. as needed). I need to know which is more efficient to the operation of my app: do I download the images to a HashMap of images or do I download them and save them as resources in the asset or drawable directory and then access them by id? Please do explain, at least a little, why whichever option is better.
Ideally you need to download all the images to sdcard and store them.
Access them through the file apis and load them using lazy loading to your image views.
If you are going to load all the images in the app resource folders, then it is going to eat up lot of memory. And keep in mind do not cache all the images on to the memory. I would suggest you to use, UniversalImageLoader from my experience. It gives you a bunch of options to play with.

is this the best storage option for me?

I want to save downloaded images from a server. I want these images to be accessible only from within the application itself. I don't want the images accessible from anywhere else, i.e. someone can just delete/modify it like if it was on the SD card or from another different application. I'm thinking it would be best if I were to use internal storage, as it is private to my app.
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
are there better options out there?
Internal storage is the best option if you want to keep your files private.
However, on most devices, internal storage is very limited and the users might uninstall your app if you use too much of it (images can be pretty big).
You should look into using the external storage to save images, and possibly encrypting them if you really want to keep them private.
As already mentioned by Raghav this would be a good option, and as said the internal storage is very limited (mostly on older devices), however if you are on a rooted device it will be possible to delete your files anyway. Take into account the limited storage, as people is also making "swap partitions" on their SD cards because internal storage is very limited.
This is is the simplest solution. The other typical solution is to store the image as a blob in the application's database. This will make it completely inaccessable outside of your application. You can do it using the method shown here:
How to store and retrieve a byte array (image data) to and from a SQLite database?
The draw back to this is the relatively small memory space you will be given for your DB (<60MB), so this only works if you have a small number of images.

Saving/loading document state quickly and robustly for image editor

I'm looking for some critique on my approach for storing the state of a bitmap editor for Android and iPhone mobile phones. Even a "Looks fine to me!" response would be great!
In the application, the current user document contains several bitmap layers (each maybe 1024 by 768 pixels) that can each be painted on. The basic requirements for the application are:
I need to be able to save and restore the document state.
When the user quits the application or gets a phone call, I need to be able to save the document state quickly (within about 2 seconds).
If the application crashes, I need to be able to restore the document state (it's OK if the user loses maybe 30 seconds of work though).
For 1, I cannot find any open file formats that support layers. I was going to go with the following file structure for storing my document:
document_folder/
layer1.png
layer2.png
...
metadata.xml
The layers are just stored as .png files and the .xml file contains data such as which layers are currently visible. The document folder can either be opened as is by the application or the folder can be stored in a .zip file. This seems like a nice simple format for other applications to work with too.
In addition to .png files, I will also allow layers to be saved in a custom .raw file format which contain unprocessed raw pixel data from bitmaps. I can save these very quickly on the phone (<0.5s) whereas .png files take a second or two.
My plan for quick-saving the document was, on start-up, to create a folder called /autosave, and save .raw versions of all the layers there. After a few editing commands on one layer, I would then update the .raw file for that layer in a background thread. For robustness when saving, I would save the layer as e.g. layer1_tmp.raw and when I've confirmed the file has been fully written, replace layer1.raw with this file.
Should the application crash during use, I would just reopen the /autosave folder. When the application is closed or the user gets a phone call, I just have to update the last modified layer to autosave. When the user wants to save, I just convert all the .raw files to .png files and then zip the folder.
What do you think? Are there any obvious flaws? Is there a simpler way? Am I reinventing the wheel somehow? Thanks.
Your idea souds good to me: save the layers in the background, as you go. Any layer that the user isn't currently editing should be queued to be saved as soon as they switch away from it to a different layer. If the app is interrupted, you just have to save the current working layer, which as you say can be done in 0.5s.
Why bother with the png format anyway? You only need it if exporting data to another machine/system, right?
I think you have a great plan there. I would probably go the same way (but that itself doesn't mean anything :-)
What I was thinking is if you could have not only a worker thread saving the file but a complete background service (with a worker thread of course, since a service itself also runs in the main thread).
This way you would have guaranteed that there is always something alive that can handle your layer deltas, regardless if the drawing activity has crashed or someone is calling you. Suddenly you don't have the same timing constraints (the write operation can take 10 seconds if it wants to, your activity is neither blocked, nor dependent of the write operation). Of course your service would then commit suicide when it has emptied its save queue (to save system resources).
What I don't know in order to further promote this idea is how much data you're writing to the raw-file? Do you write the complete 1024x768 layer every time or do you only rewrite the changed parts? I'm also unsure of how the data would actually be transmitted to the service (from the Activity). I don't know if there is a maximum size of a byte-array-extra an Intent can handle.
Hope this gives you further ideas.
Cheers!

Categories

Resources