1
votes

I am generating an image that is saved in FileSytemStorage.getAppHomePath() dir. I now need to share it via Email, SMS ... That's why I am using the following code (based on Codename One documentation) in my action method :

    long time = new Date().getTime();

    String fullOutputPath = FileSystemStorage.getInstance().getAppHomePath()
            + "Montage_" + Long.toString(time) + ".png";

    // Save the image with the ImageIO class
    try (OutputStream os = FileSystemStorage.getInstance().openOutputStream(fullOutputPath)){
        ImageIO.getImageIO().save(montage.getMontageImage(), os, ImageIO.FORMAT_PNG, 1.0f);

        }


    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

        // Enable image sharing (outside the try/catch so that the outputstream in closed for sure)
        if (FileSystemStorage.getInstance().exists(fullOutputPath)) {
            Dialog.show("Saved", "Photo collage saved to " + fullOutputPath
                    + " (file size = " + FileSystemStorage.getInstance().getLength(fullOutputPath) +" B)", "OK", null);
            //Photo collage saved to file://home/Montage_14669... .png (file size = 50387B)

            findValidateMontageShareButton3().setImageToShare(fullOutputPath, "image/png");
            // Null pointer exception

So in that way I get a NPE and if I don't test if the file does exist there is no NPE but the image is still missing (both in the simulator and on the device).

The stack trace is as follows :

java.lang.NullPointerException
at userclasses.StateMachine.onPage3_ValidateMontageShareButton3Action(StateMachine.java:852)
at generated.StateMachineBase.handleComponentAction(StateMachineBase.java:757)
at com.codename1.ui.util.UIBuilder$FormListener.actionPerformed(UIBuilder.java:2835)
at com.codename1.ui.util.EventDispatcher.fireActionSync(EventDispatcher.java:459)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:362)
at com.codename1.ui.Button.fireActionEvent(Button.java:411)
at com.codename1.ui.Button.released(Button.java:442)
at com.codename1.ui.Button.pointerReleased(Button.java:530)
at com.codename1.ui.Form.pointerReleased(Form.java:2627)
at com.codename1.ui.Form.pointerReleased(Form.java:2563)
at com.codename1.ui.Component.pointerReleased(Component.java:3158)
at com.codename1.ui.Display.handleEvent(Display.java:2025)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1067)
at com.codename1.ui.Display.mainEDTLoop(Display.java:996)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

It looks that the file my app is generating is not accesible to the sharing app. Do I have to add any extra permission as advised here for Android ?

Please note : I don't know if it is related to this problem but I cannot access to Codename One Settings menu from Eclipse anymore (maybe since upgrade to CN1 lib v 115)

Any help appreciated,

Cheers

1
The necessary permissions should be in place. What's the stack of the null pointer exception? - Shai Almog
I added the stack trace. - HelloWorld
You gave me an idea. I tested if findValidateMontageShareButton3() was returning null and it was indeed. So although I cannot explain it, I changed to ((ShareButton) c).setImageToShare(fullOutputPath, "image/png"); and the NPE went away. Unfortunatelly the message I send still misses the image. - HelloWorld
The reason for the stack trace is simple, you need to use findValidateMontageShareButton3(f) and not findValidateMontageShareButton3(). The latter is only good if you are within the current form. For the settings issue try deleting guibuilder*.jar from the .codenameone directory under your home directory and see if that helps (this is probably unrelated though). When you say the image isn't included, where do you test it? On Android only? Did you include text as well? Try not including text. Which intent did you pick for sharing? - Shai Almog
Thanks for the tip regarding findValidateMontageShareButton. As far as the Codename One Settings is concerned, I also renamed the project without space (My Project -> MyProject) and it worked. So the image is not included in the simulator (and on my Android 4.4 device). I did not include text. But what is weird is that if I share the image, choose email, (the image is neither included in the email client mock up nor in my PC email client), go back to my app sharing page, share it again, now it appears. Same behaviour on the device : first time nothing, then second or third time sth. - HelloWorld

1 Answers

1
votes

So here is part of the answer which works in the simulator (ie the image appears in the fake email client => see image below).

Image in the fake email client

So it appears that the share button cannot be set up in the action method (ie the method that is triggered when the user click on the share button). It has to be set up previously.

Consequently, in the beforeShow method my code reads as follows :`

    FontImage.setMaterialIcon(findValidateMontageShareButton3(), FontImage.MATERIAL_CHECK_CIRCLE);


   final long time = new Date().getTime();

   // We generate the montage filename JPG otherwise it cannot be sent
   montage.setMontageFullPath(FileSystemStorage.getInstance().getAppHomePath()
            + "Montage_" + Long.toString(time) + ".jpg");

   // We assign the montage filename to the share button BEFORE we can click the button (otherwise the
   // filename cannot be taken into account)
   findValidateMontageShareButton3(f).setImageToShare(
        montage.getMontageFullPath(), "image/jpeg");

Then in the onAction method related to the share button the code reads :

    // Save the image with the ImageIO class
    // We wait until the file is completely written to continue
    Display.getInstance().invokeAndBlock(new Runnable() {

        @Override
        public void run() {
            try (OutputStream os = FileSystemStorage.getInstance().openOutputStream(montage.getMontageFullPath())){
                ImageIO.getImageIO().save(montage.getMontageImage(), os, ImageIO.FORMAT_JPEG, 1);   

            } catch (IOException e) {
                Dialog.show("Erreur", "Impossible de sauvegarder le montage! Merci de vérifier l'espace disque disponible.", null, "OK" );
            }
        }
    });

I tested it and it worked on the simulator but not on the device. Either with a png or a jpeg file, the file cannot be attached to the SMS or email (Android error message "abnormal file, can't attached file").

However if I do it a second time, then the file can be attached. So now the image is not missing but it cannot be attached (the first time) which is still embarrassing.