codenameone / CameraKitCodenameOne

A cross platform API for low level camera access
3 stars 5 forks source link

Picker component freezes after using Capturing the image #7

Closed sankardevisharath closed 4 years ago

sankardevisharath commented 4 years ago

Hi,

The date picker component is getting frozen if we use it after using Camerakit.

Below are the steps to regenerate the issue along with the test case.

  1. Open app
  2. Click to capture a photo.
  3. Then app will show another form with two Picker date component.
  4. Click on picker
  5. Try to click "Ok" from the date selection. (Try clicking multiple times)
  6. App screen freezes.

import com.codename1.camerakit.CameraEvent;
import com.codename1.camerakit.CameraKit;
import com.codename1.camerakit.CameraKitFeatures;
import com.codename1.camerakit.CameraListener;
import com.codename1.components.FloatingActionButton;
import com.codename1.components.SpanLabel;
import com.codename1.components.ToastBar;
import static com.codename1.ui.CN.*;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.ui.Toolbar;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.l10n.DateFormat;
import com.codename1.l10n.SimpleDateFormat;
import com.codename1.media.Media;
import com.codename1.media.MediaManager;
import com.codename1.ui.Button;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.FontImage;
import com.codename1.ui.Image;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.spinner.Picker;

/**
 * This file was generated by <a href="https://www.codenameone.com/">Codename
 * One</a> for the purpose of building native mobile applications using Java.
 */
public class TestCase {
private Form current;
    private Resources theme;
    private CameraKit ck;
    private Reel reel;

    public void init(Object context) {
        ck = CameraKit.create();

        // use two network threads instead of one
        updateNetworkThreadCount(2);

        theme = UIManager.initFirstTheme("/theme");

        // Enable Toolbar on all Forms by default
        Toolbar.setGlobalToolbar(true);

        // Pro only feature
        Log.bindCrashProtection(true);

    }

    private class Reel extends Container {

        Reel() {
            super(BoxLayout.y());
            setScrollableY(true);
        }

        public void addToReel(Image img) {
            img = img.scaledWidth(isTablet() ? convertToPixels(50) : convertToPixels(20));
            add(new Label(img));
        }

        public void addVideo(String path) {
            try {
                Media m = MediaManager.createMedia(path, true);
                m.prepare();

                //m.setNativePlayerMode(true);
                Component videoCmp = m.getVideoComponent();
                videoCmp.setPreferredW(isTablet() ? convertToPixels(50) : convertToPixels(20));
                videoCmp.setPreferredH(isTablet() ? convertToPixels(30) : convertToPixels(12));

                add(videoCmp);

            } catch (Exception ex) {
                Log.e(ex);
                ToastBar.showErrorMessage("Failed to load video from path "+path);
            }
        }
    }

    public void start() {
        if(ck != null && !ck.isStarted()) {
            ck.start();
        }
        if(current != null){
            current.show();
            return;
        }
        reel = new Reel();
        Form hi = new Form("Native Camera", new LayeredLayout());
        hi.setScrollableY(false);
        if(ck != null) {
            ck.addCameraListener(new CameraListener() {
                @Override
                public void onError(CameraEvent ev) {
                    // We currently get some errors on Android
                    Log.p(ev.getMessage() + " : " + ev.getExceptionMessage());
                }

                @Override
                public void onImage(CameraEvent ev) {
                    ToastBar.showInfoMessage("Captured image bytes");
                    byte[] bytes = ev.getJpeg();
                    Image img = Image.createImage(bytes, 0, bytes.length);
//                    reel.addToReel(img);
//                    hi.revalidate();
                    showAnotherForm();
                }

                @Override
                public void onVideo(CameraEvent ev) {
                    ToastBar.showInfoMessage("Captured video: " + ev.getFile());
                    reel.addVideo(ev.getFile());
                    hi.revalidate();
                }
            });
            hi.add(ck.getView());
            Button video = new Button();
            FontImage.setMaterialIcon(video, FontImage.MATERIAL_VIDEOCAM);
            video.addActionListener(e -> {
                if (!ck.supportsFeatures(CameraKitFeatures.CaptureVideo)) {
                    ToastBar.showErrorMessage("Video capture is not supported on this platform");
                    return;
                }
                Boolean b = (Boolean)video.getClientProperty("capturing");
                if(b == null) {
                    video.putClientProperty("capturing", Boolean.TRUE);
                    ck.captureVideo();
                    FontImage.setMaterialIcon(video, FontImage.MATERIAL_VIDEOCAM_OFF);
                } else {
                    video.putClientProperty("capturing", null);
                    ck.stopVideo();
                    FontImage.setMaterialIcon(video, FontImage.MATERIAL_VIDEOCAM);
                }
            });
            FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_CAMERA);
            fab.bindFabToContainer(hi, CENTER, BOTTOM);
            fab.addActionListener(e -> {
                if (ck.supportsFeatures(CameraKitFeatures.CaptureImage)) {
                    ck.captureImage();
                } else {
                    ToastBar.showErrorMessage("Image capture is not supported on this platform");
                }

            });

            Button toggleCamera = new Button();
            FontImage.setMaterialIcon(toggleCamera, FontImage.MATERIAL_CAMERA_FRONT);
            Button toggleFlash = new Button();

            FontImage.setMaterialIcon(toggleFlash, FontImage.MATERIAL_FLASH_ON);
            toggleCamera.addActionListener(e -> {
                if (ck.supportsFeatures(CameraKitFeatures.ToggleFacing)) {
                    ck.toggleFacing();
                } else {
                    ToastBar.showErrorMessage("Front/Back camera toggle is not supported on this platform.");
                }

            });
            toggleFlash.addActionListener(e -> {
                if (ck.supportsFeatures(CameraKitFeatures.Flash)) {
                    ck.toggleFlash();
                } else {
                    ToastBar.showErrorMessage("Flash is not supported on this platform");
                }
            });
            Container buttons = BoxLayout.encloseY(video, toggleCamera, toggleFlash);
            buttons.setScrollableY(true);
            hi.add(BorderLayout.east(buttons));

            hi.add(BorderLayout.west(reel));
        } else {
            hi.add(BorderLayout.north(new SpanLabel("Loading native camera view")));
        }
        hi.show();
    }

    public void showAnotherForm(){
        Form form = new Form(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE));
        form.setScrollable(false);
        Container container = new Container(BoxLayout.y());
        container.add(new Label("Test", "heading5"));
        container.add(new Label("", "newLine"));
        container.add(new Label("", "newLine"));

        final Picker fromDate = new Picker();
        fromDate.setType(Display.PICKER_TYPE_DATE);
        container.add(new Label("From Date", "heading7"));
        container.add(fromDate);
        container.add(new Label("", "newLine"));

        final Picker toDate = new Picker();
        toDate.setType(Display.PICKER_TYPE_DATE);
        container.add(new Label("To Date", "heading7"));
        container.add(toDate);

        Button nextBtn = new Button("Proceed");
        nextBtn.setUIID("loginBtn");
        nextBtn.addActionListener((ev) -> {
            DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
            String fromDateStr = dateFormat.format(fromDate.getDate());
            String toDateStr = dateFormat.format(toDate.getDate());

        });
        container.add(new Label("", "newLine"));
        container.add(new Label("", "newLine"));
        container.add(nextBtn);
        form.add(BorderLayout.CENTER, container);

        form.show();
    }
    public void stop() {
        if(ck.isStarted()) {
            ck.stop();
        }
        current = getCurrentForm();
        if(current instanceof Dialog) {
            ((Dialog)current).dispose();
            current = getCurrentForm();
        }
    }

    public void destroy() {
    }
}

Thank you,

shannah commented 4 years ago

What platform? iOS, Android?

shannah commented 4 years ago

I reproduced the issue on iOS. This is fixed now. Will be included in next update on Friday.