1

I want to implement a behavior similar to Whatsapp, where when the user can upload an image. I tried opening the images in my app, but if the image is too large, I will have an out of memory error.

To solve this, I'm opening forwarding the images to be open in the phone's native image viewer using the platformRequest() method.

However, I want to know how is it Whatsapp modifies the phone's native image viewer to add a "Select" button, with which the user selects the image he wants to upload. How is that information sent back to the J2ME application and how is the image resized?


Edit: I tried this in two different ways, both of which gave me the OOME.

At first, I tried the more direct method:

FileConnection fc = (FileConnection) Connector.open("file://localhost/" + currDirName + fileName);
if (!fc.exists()) {
    throw new IOException("File does not exists");
}
InputStream fis = fc.openInputStream();
Image im = Image.createImage(fis);
fis.close();

When that didn't work, I tried a more "manual" approach, but that gave me an error as well.

FileConnection fc = (FileConnection) Connector.open("file://localhost/" + currDirName + fileName);
if (!fc.exists()) {
    throw new IOException("File does not exists");
}
InputStream fis = fc.openInputStream();

ByteArrayOutputStream file = new ByteArrayOutputStream();
int c;

byte[] data = new byte[1024];

while ((c = fis.read(data)) != -1) {
    file.write(data, 0, c);

}

byte[] fileData = null;
fileData = file.toByteArray();

fis.close();
fc.close();
file.close();
Image im = Image.createImage(fileData, 0, fileData.length);

When I call the createImage method, the out of memory error occurs in both cases. This varies with the devices. An E72 gives me the error with 3MB images, while a newer device will give me the error with images larger than 10MBs.

  • 1
    have you tested how [WhatsApp](http://en.wikipedia.org/wiki/WhatsApp) handles large images? Also, did you consider an option to resize images at server, _before_ sending to phone? – gnat Sep 28 '12 at 11:31
  • 1
    I am already doing the resizing at the server side, but the problem is that if the sending user tries to open a large image, so that he can send it to the server, the app crashes from lack of memory. I tested the same image in WhatsApp, and larger ones as well, and none of them gave that problem. – Midori Ryuu Sep 28 '12 at 13:20
  • interesting. Please edit the answer to show the code you use when user opens the image - the code from where you are getting OOME. from what I read at wikipedia it looks possible that they may use Symbian specific API, not a generic Java ME MIDP – gnat Sep 28 '12 at 15:09
  • Ok I added the code! Unfortunately I can't implement a Symbian specific API, as the app needs to support BB as well. I'm trying to make it work for Nokia atm, and amend the code to support RIM later. – Midori Ryuu Sep 28 '12 at 16:31

1 Answers1

1

MIDP 2 (JSR 118) does not have API for that, you need to find another way to handle big images.

As for WhatsApp, it looks like they do not rely on MIDP in supporting this functionality. If you check the Wikipedia page you'll note that they don't claim general Java ME as supported platform, but instead, list narrower platforms like Symbian, S40, Blackberry etc.

This most likely means that they implement "problematic features" like one you're asking about using platform-specific API of particular target devices, having essentially separate projects / releases for every platform listed.

If this feature is really necessary in your application, you likely will have to do something like this.

In this case, consider also encapsulating problematic features in a way to make it easier to switch just part of your source code when building it for different platforms. For example, Class.forName(String) can be used to load platform specific implementation depending on target platform.

//...
Image getImage(String resourceName) {
   // ImageUtil is an interface with method getImage
   ImageUtil imageUtil = (ImageUtil) Class.forName(
           // get platform-specific implementation, eg
           //   "mypackage.platformspecific.s40.S40ImageUtil"
           //   "mypackage.platformspecific.bb.BBImageUtil"
           //   "mypackage.platformspecific.symbian.SymbialImageUtil"
           "mypackage.platformspecific.s40.S40ImageUtil");
   return imageUtil.getImage(resourceName);
}
//...
gnat
  • 6,213
  • 108
  • 53
  • 73