Android resource loading (icons and strings) at runtime - android

I'm stuck with the following scenario and appreciate any help/advice..
Requirement
I have number of categories and subcatergories in my application. Say for example, I have a category "Food" and under which I have subcategories: Mexican, Chinese, Italian etc.. I have around 20 categories and each category has around 30 subcategories.
Each subcategory/category has an Icon associated with it
User would be able to select one or more of these sub-categories, so the UI would be a seectable list view.
Questions:
What's the best way to store and retrieve this data (Strings and Icons), serverside or client side ?
Is there a way to load icons dynamically at runtime, when I show the subcategories? (using http?)
Thanks in advance !

Why would you fetch icon-data from a server? 20 * 30 = 600 icons.
You probably will save hard drive space with respect to the installation. But personally I wouldn't go for that solution.
If you're not in need of a client/server - approach then don't use it. What if the server for example breaks down, or you don't have an internet connection?. The application will then be useless :)

You can load images dynamically as:
BitmapFactory.Options options = new BitmapFactory.Options();
options.outWidth= IMAGE_WIDTH;
options.outHeight= IMAGE_HEIGHT;
Bitmap bm = BitmapFactory.decodeFile("icon image file path", options);
imageView.setImageBitmap(bm);
In your case, you can download all the required icons on mobile's sdcard. So in future,if sub categories increases then you can download new icons for that and can dynamically render on UI.

Related

Scanner android application

We are developing an android application for document scanner.
This application is having feature to edit the image like adding magic color, grey mode, Black white,etc. this application has the option to scan "N" number of pages and convert it into PDF at the end.
The flow of the application is First activity is taking photo of the image and the second activity for cropping the image and third activity for editing the image like applying magic color, grey mode and black/white conversion. And in the third activity we have add button,clicking on it will go back to first activty and the same process continues.Once all the images scanned, third activity is haivng done button, clicking on it will create pdf and close the application.
Now the problem is after scanning some 35 pages, it throws out of memory error because we are always keeping original and modified bitmaps as List in the code because its possible for the user to go back to previous images and edit it. At that time i need original version of the image also.
Could you please help me out on the below items.
1) where to keep the bitmaps in this scenario?
2) Is there any way to store the image in the external card and reading it everytime on need basis?
Thanks in advance.
Store the bitmap as cache.
out = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
It is prefetable to use cache directory to store such a file rather than storing it persistently. getCacheDir() will return the path to the directory.

second HttpURLConnection for image loading optimization

I have read that HttpUrlConnection sends GET request when connection is made. Also then I can retrieve an instance of InputStream to read that resource. Does this mean that whole resource file is downloaded as the connection is made?
What I want to achieve is to set an ImageView image to remote image from the web. However my idea is to do this in memory-friendly way and calculate inSampleSize for BitmapFactory. In order to calculate that size - I need view dimensions and remote image dimensions. Remote image dimensions may be retrieved this vay (basically it should not load an image into memory):
BitmapFactory.Options options = new BitmapFactory.Options ();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream (inputStream, null, options);
However once read inputStream can not be reused in this case (or can it?). Also HttpUrlConnection returns the same instance of InputStream which means that if I want to read an image again (and load only the size I need using inSampleSize option) - I have to re-connect.
I want to be able to load large images, however as I have heard - HTTP requests are slow so is it worth it to send a second request? Also I don't know if the whole image is downloaded anyway even if I am reading only image info for the first time and not loading the whole thing.
If it is not worth it I think the only way will be to copy whole image into memory, get it's dimensions, read only the size I need and finally clean up the memory. Witch would be pretty memory expensive for the short period of time.
For loading images from remote web use Android Smart Image View..
it Load Images from URLs in memory friendly way
http://loopj.com/android-smart-image-view/

Given a full path of an image file, how to get its thumbnail?

It seems the answers I searched online (including stackoverflow.com) get the image file id through gallery selection.
I have created my own file explorer.
Then how to do that?
I can create my own small size image; but I think it would be faster if we can make use of an exisiting thumbnail; and if it does not exist, I would prefer to create a thumbnail that is saved for later use.
[Update:]
OK, thanks for advice. So I will not create a thumbnail in the device, to avoid to use too much space.
Then is is better to do two steps:
Step 1: look for an exisiting thumbnail for the image file if it exists.
Step 2: if no thumbnail exists, then create my own small size bitmap (not save the it).
Then how to do Step 1, if I do not use the Gallery intent?
[Update 2:]
I also want to get the thumbnail of a video file.
I can use MediaMetadataRetriever to get a frame at any point of time, and rescale the image to a thumbnail. But I find it is very slow: I have 4 video files in the folder, and I can sense the delay.
So I think the better way to retrieve an existing thumbnail.
If I only know the file path and file name, how can I get it?
I think this question is the same as my original one, just it has more sense to do so.
You shouldn't be using specific files for tumbnail, especially not creating tumbnails. What if the user has a lot of images and you store a tumbnail of each picture which gets viewed in your explorer. That would generated a whole lot of duplicated and unwanted data. The calculations from resizing the images each time overweighs the amount of data that would need to be stored.
I would suggest you have a default icon on images in the explorer and then resizing the images in a diffrent thread, replacing your default tumbnail as they are resized.
You could downsize the existing images on the fly:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, opts);
int width = opts.outWidth;
int height = opts.outHeight;
then
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
opts.inDither = true;
opts.inJustDecodeBounds = false;
opts.inSampleSize = (int)Math.pow(2.0,Math.floor(Math.log(scale_factor)/Math.log(2)));//for example double scale_factor=(double)width/desired_dimension;
and finally:
Bitmap bm = BitmapFactory.decodeFile(image_path,opts);
You could load in a separate thread ranges of existing files and update only those ones when needed.
You can use ThumbnailUtils. Look up the this utility method. Probably fits your need without much hassles. Creating duplicate downsized images is a bad design as that it will end up unnecessary data.
Bitmap resizedImage = ThumbnailUtils.extractThumbnail(rescaledImage, imagePixel, imagePixel);

Google Drive Custom Thumbnail for Standard MIME Type

I have yet another pesky question for people who understand how Google Drive SDK works. On Android platform, I am creating my own custom thumbnails for JPEG image files ( thumbnail is a reduced JPG of the most important detail of the parent image ), The size is a bit non-standard - 384 x 128px, but well within limits stated in the documentation. So, the code goes like this:
// thumbnail
String myThumb = "test.tnl";
Thumbnail tn = new Thumbnail();
tn.setMimeType("image/jpeg");
tn.setImage(Base64.encodeBase64String(myThumb.getBytes()));
// define meta-data
File body = new File();
body.setTitle("test.jpg");
body.setDescription("bla bla");
body.setMimeType("image/jpeg");
body.setThumbnail(tn);
File gooFl = drvSvc.files()
.insert(body, new FileContent("image/jpeg", new java.io.File(test.jpg)))
.execute();
and executes flawlessly (there are more 'body' elements I don't list here) and everything works like a charm. But when I download the image, my thumbnail is gone, replaced by standard Google thumbnail - s220 type.
I did notice the documentation statement:
As with indexable text, Drive automatically generates thumbnails for many common file types. For shortcuts and other file types Drive can not render, you can provide a thumbnail image generated by your application.
Reading it ambiguously, I was hoping that by supplying my own thumbnail to a known MIME type, I will keep Google Drive from generating its standard one, but it probably is not the case. So the question remains. Is there a solution to my problem? Having custom thumbnails for standard "image/jpeg" MIME types? Or is there a work-around, perhaps another custom field I can stick some 10Kb of binary data in? I need the thumbnails in my Android viewer - another app.
Thank you, sean
Google Drive will only use custom thumbnails for non-standard MIME types, so you can't override the one for jpeg. Your app can use a custom file property to store and read proprietary data:
https://developers.google.com/drive/properties

Android: MediaStore.Images.Media.EXTERNAL_CONTENT_URI ... show pictures in full size?

I guess this question has been asked before, but I can't seem to find a proper answer/solution.
Have a note-taking app, which allows to take pictures. For that I start an intent, that starts up the built-in camera-app. So far so good.
But when I show that image in my app, it's in a much smaller format :(
The funny/weird thing is, that the camera-app did take a full-resolution picture! But for some reason I can't get the full version to show in my app???
So, when I use the standard Android Gallery app, and go to that picture, it is very obvious that it's full size (I can zoom in and see details I really can't see when I zoom in, in my own app). Also, the dimensions are really those of the original picture, taken with the 5MP camera.
In my app, they are very small. My phone has Android 2.2, but the same happens on my emulator (Android 2.1).
How should I retrieve the pictures in my app??? Tried a couple of ways, but none works :( Don't need a complete example (allthough that's very welcome), just a few clues are enough to search for myself.
Tx in advance!!
Greetingz,
Koen<
Very weird, I found the solution/answer by looking at the _ID-values that were being inserted in my own database. First I noticed that when I selected an existing image (via the build-in Android Gallery), I did get the full size image.
When I first took a picture, I got a scaled image. So where was the difference. Apparantly at the location where the _ID of the picture got stored in my database. In my case, and probably most cases, this happens in the onActivityResult procedure.
First take a look at what I initially had:
if(requestCode == REQUEST_CAMERA && resultCode == RESULT_OK){
String timestamp = Long.toString(System.currentTimeMillis());
// get the picture
mPicture = (Bitmap)result.getExtras().get("data");
//save image to gallery
String pictureUrl = MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, getResources().getString(R.string.app_name_short), timestamp);
insertPictureAttachment(mRowId.intValue(), Integer.parseInt(Uri.parse(pictureUrl).getLastPathSegment()));
The "insertPictureAttachment"-method does the actual inserting into the database.
Looking backwards, this was a bit weird anyway ... make a picture, so I could make an URI of it, and then get the last path segment (which is the _ID), so I could insert that into my database.
Eventually, it turns out that I can replace the above code with just one line:
insertPictureAttachment(mRowId.intValue(), Integer.parseInt(result.getData().getLastPathSegment()));
Much shorter, and actually makes more sense ... rather than getting the info from result.getExtras().get("data"), I get my info from result.getData(), which gives the _ID of the original, full-size image.
I will do some further research on this though, cause it's not clear to me yet why I actually don't have to call MediaStore.Images.Media.insertImage(...) ... maybe I will have to if I want specific features (like a custom file location or something like that).
Greetingz,
Koen<

Categories

Resources