2
votes

Okay, I don't believe this is a cn1 issue, but I am running out of options. I have an app and I have been using the Capture.capturePhoto to give the user the ability to snap a photo with their device and upload it to my server. Has been working great for several months now. I have been asked to add the ability to upload a photo from the mobiles photo gallery, I thought it would be trivial, but after figuring out how to scale the image down and store it in Storage, I am now stumped with it just sending 0 bytes to my server.

I know it's not my server, that has not changed and can still upload files from various sources including the ones captured with the photo in the cn1 app.

Here is the code that uploads the photo

private void uploadImage(String filename, String name) throws IOException {
    String ext = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
    if (ext.equals("jpg") || ext.equals("jpeg") || ext.equals("pjpeg") || ext.equals("png")) {
        MultipartRequest request = new MultipartRequest() {
            Hashtable h;
            @Override
            protected void readResponse(InputStream input) throws IOException {
                JSONParser p = new JSONParser();
                h = p.parse(new InputStreamReader(input));
                super.readResponse(input);
            }

            @Override
            protected void postResponse() {
                List<Map<String, Object>> media = (List<Map<String, Object>>)h.get("media");
                Dialog.show("Photo Uploaded", media.size() + " photo(s) uploaded and available to send.", "OK", null);
            }
        };
        request.setUrl(MyApplication.IMGSERVER);
        request.setPost(true);
        request.addData(name, filename, "image/" + ext);
        request.addRequestHeader("X-Dart-Token", token);
        NetworkManager.getInstance().addToQueue(request);
    } else {
        Dialog.show("Invalid Photo Format", "The photo format (" + ext+ ") is not supported. Try with jpg or png.", "OK", null);
    }
}

Here is the relevant parts of code that get and scale the photo from the gallery

Display.getInstance().openGallery(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (actionEvent != null && actionEvent.getSource() != null) {
        String filepath = (String)actionEvent.getSource();
        if (filepath != null) {
            // scale down the image
           String filename = "tempfile.png";
           boolean success = false;
           if (Storage.isInitialized()) {
               try {
                   OutputStream out = Storage.getInstance().createOutputStream(filename);
                   ImageIO.getImageIO().save(filepath, out, ImageIO.FORMAT_PNG, 500, -1, 1);
                   out.close();
                   success = true;
                } catch (IOException e1) {
                    Log.p("image scaling failed " + e1.getMessage());
                    Dialog.show("Photo Upload", "Unable to scale photo:" + e1.getMessage(), "OK", null);
                }
                if (success) {
                    // open dialog and have user provide name
                    try {
                        String tmpFilepath = FileSystemStorage.getInstance().getAppHomePath() + filename;
                        Dialog.show("Image File", tmpFilepath, "OK", null);
                        uploadImage(tmpFilepath, name);
                    } catch (IOException err) {
                        Log.p("Image Upload Failed:" + err.getMessage());
                        Dialog.show("Picture Uploaded Failed", "Something prevented the upload of the image.", "OK", null);
                    }
                }
            }
        }
    }
}

I purposely cut out a lot of the surrounding code in the above snippet to focus on what I believe to be important.

I left in the Dialog statements that I am using for debugging so I can see what the path is on the device. If I run this in the simulator, and choose a file, it uploads fine, but when I run it on an iPhone, the file sent to the server has 0 bytes, and the Dialog in the uploadImage method will display that '0 photo(s) uploaded'. When using Storage.g.entrySize() on "tempfile.png" it displays the file has not being 0 in size. How can I properly reference this file to send it to the server.

1

1 Answers

1
votes

You are saving the gallery image to Storage but the upload method works with FileSystemStorage those aren't compatible so you get incompatible behaviors.