Taslim A. Khan
Taslim A. Khan

Reputation: 526

How to efficiently manage image resources, both local and networked, in Android?

I am working on an app, which requires-

  1. Pull contact details and images from the local contact book.
  2. Some interval apart sync this contact data (all of it) to a server.
  3. Pull contact data (images as well) from the server whenever needed.

I basically know how to implement them individually. For example, I have already managed to pull local contacts, I am yet to achieve 2 and 3. I have few questions regarding them.

  1. Where do I save the images (both local and networked)? Do I need to save them in any particular folder? If yes then what is the recommended way of doing that?
  2. I have used volley library in another project, and I am hoping to use it again here. AFAIK, volley caches networked images in the memory. But I believe that in my app, there can be users who will have more than 2000 contact data. My intuition is that not all the images will remain in the cache for ever, so if I want my app to work offline, I will need to images to be stored locally. I am confused about where to store the images and how to achieve that. Point to note, this app will be accessed frequently.
  3. What is the recommended way of sending image data over the network to a server.

The questions may seem broad, but I feel that they are tightly coupled, considering a single app. I am expecting expert opinion on the recommended ways of achieving these features.

Thanks!

Upvotes: 0

Views: 128

Answers (3)

VinceStyling
VinceStyling

Reputation: 3827

About third question, if you're going to keep using Volley, you can try to override the getBody() to return the image's bytes, rest of other parameters should be encoding within the URL, this way would use both of GET and POST method.

public class ContactRequest extends StringRequest {

    public static String buildRequestUrl(String url,
        Map<String, String> params, String paramsEncoding) {
        StringBuilder urlBud = new StringBuilder(url).append('?');
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                urlBud.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
                urlBud.append('=');
                urlBud.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
                urlBud.append('&');
            }
            return urlBud.toString();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Encoding not supported: " + paramsEncoding);
        }
    }

    private String imageFilePath;

    public ContactRequest(String url, String imageFilePath,
        Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(Method.POST, url, listener, errorListener);
        this.imageFilePath = imageFilePath;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        return getBytesFromFile(new File(imageFilePath));
    }
}

build the ContactRequest and serve to RequestQueue like this :

String originUrl = "http://.../contact_push.do";
String imageFilePath = "/sdcard/.../contact_avatar_path";
Map<String, String> params = new HashMap<String, String>();
params.put("firstName", "Vince");
params.put("lastName", "Styling");
new ContactRequest(
    ContactRequest.buildRequestUrl(originUrl, params, HTTP.UTF_8),
    imageFilePath, null, null);

'cause I never faced this problem before, so I don't sure this Request can reach to the server correctly, it's an un-test solution for me, hope can help.

Upvotes: 0

Gabe Sechan
Gabe Sechan

Reputation: 93668

You typically save them either to your internal folder or to the SD card in your directory. The internal data folder will be locked to your app (unless the phone is rooted) and inacessible by other apps, the sd card will be only on 4.3 and higher. Either way you should manage the amount of data cached, set a limit and not allow it to go higher than that (kicking them out in some matter, most likely LRU or LFU). YOu'll need to do that by hand or find a library to do it for you, its not built into Android.

As for downloading them from the server- typically its just an HTTP request, with a webservice that will do any necessary privacy checking before sending down either an image result or an error. You don't want to do anything like JSON or the like here, it will just waste bandwidth.

Upvotes: 1

eleven
eleven

Reputation: 6857

  1. There is no "recommended directory for images". The decision is up to you. But you must always remember that memory on user's device is finite and on some handsets even extra few megabytes are inappropriate expenditure. The docs are pretty clear.
  2. Saving ~2000 photos on user's device is not a good idea. But again it's up to you. The Volley library is for general https interaction but not for images downloading, encoding and caching. Picasso is aimed to work with images: loads images from network or by Uri, has cache size settings and many other features.
  3. It depends on your server. The most common way is just POST http request or multipart request if you need to send some additional data.

Upvotes: 0

Related Questions