Part 2 - Camera Application

Table of Contents

Mobile JSF: Using ICEmobile to rapidly build mobile applications

The goal of this 4 part tutorial is to build an ICEmobile application that will allow users to take a photo using their device's camera, upload that photo to the application, and notify users of the new image upload using ICEmobile cloud push. The application will also provide screen size detection and allow navigation between views.

Part 1: Device Detection and Layout
Part 2: Camera Application
Part 3: Push Notification
Part 4: Page Navigation

Requirements

  1. Completed Part 1: Device Detection and Layout
  2. ICEmobile Container

Part 2: Camera Component


To achieve a full mobile experience we need to have access to the device's hardware; camera, microphone, video, bar code reader, etc.. In this step we are going to build a simple JSF form that contains a <mobi:camera/> component, an HTML5 input text, and a command button to submit all the collected data.

NOTE: The ICEmobile-SX container must be installed on the device for the camera component to have access to the device's camera. More information on installing and customizing device containers can be found here

Step 1

Let's build camera-capture.xthml. Our 1st row will contain our page description "Post a Shared Photo", the 2nd row will contain the camera component along with a thumbnail component that will show a preview of the snapped photo, and the 3rd will have a comment label and input text. Finally, the 4th row will contain a commandButton to submit the form and process the uploaded image. Please paste the following into the <form> of camera-capture.xhtml replacing the existing content:


camera-capture.xhtml.xhtml
      <mobi:uploadhelper />

      <mobi:fieldsetGroup>
	    <mobi:fieldsetRow>
                 Post a Shared Photo
            </mobi:fieldsetRow>
	    <mobi:fieldsetRow>
		 <mobi:camera id="cam" value="#{cameraBean.cameraImage}">
			<mobi:thumbnail for="cam" />
		</mobi:camera>
	    </mobi:fieldsetRow>
	    <mobi:fieldsetRow>
	        <h:outputLabel value="Comment: " />
	        <mobi:inputText placeholder="Add Comment" type="text"
					value="#{cameraBean.photoComment}" />
	    </mobi:fieldsetRow>
	    <mobi:fieldsetRow>
		 <mobi:commandButton buttonType="important"
                      actionListener="#{cameraBean.processUploadedImage}" value="Upload" />
	         <h:messages />
	    </mobi:fieldsetRow>
     </mobi:fieldsetGroup>


NOTE: The camera components makes use of the multipart upload (Servlet 3.0). Rather than having to encode the form, you can make use of the uploadhelper component.


Backing Beans

We currently have 1 managed bean defined in our markup, cameraBean. We will also reference a utility class named DeviceInput from this bean in order to help with the processing of the uploaded file.

Step 2

Create CameraBean.java in org.icesoft.samples.mobi.example1.view.model. Paste the following markup into this class:


CameraBean.java
@ManagedBean
@ManagedBean
@SessionScoped
public class CameraBean implements Serializable {

    // uploaded video will be stored as a resource.
    private static ArrayList<Resource> uploadedPhoto = new ArrayList<Resource>();
    // message used for notification message
    private static String uploadMessageComment;

    // camera uses map to store upload information.
    private Map cameraImage = new HashMap();

    public Resource getUploadedPhoto(){
        if (uploadedPhoto != null &&
                uploadedPhoto.size() > 0){
            return uploadedPhoto.get(uploadedPhoto.size()-1);
        }
        return null;
    }

    public List<Resource> getUploadedPhotos(){
        return uploadedPhoto;
    }

    public String getPhotoComment() {
        return uploadMessageComment;
    }

    public void setPhotoComment(String uploadMessage) {
        CameraBean.uploadMessageComment = uploadMessage;
    }

    public Map getCameraImage() {
        return cameraImage;
    }

    public void setCameraImage(Map cameraImage) {
        this.cameraImage = cameraImage;
    }

    public String getUploadMessageComment() {
        return uploadMessageComment;
    }
}


The <mobi:camera/> component is value bound to cameraBean.cameraImage. The instance variable cameraImage is a java.util.Map which will contain information such as contentType and the corresponding file object. The Bean also contains a String instance variable for the uploadedMessageComment.

Step 3

Let's implement the back end method for our submit method. In this action event method we are going to check that the cameraImage Map contains an image and if found, we use the DeviceInput utility to create a JSF Resource object for the uploaded photo. The JSF Resource object is then assigned to the uploadPhoto instance variable so that it can be displayed after the upload process. Please paste the following into CameraBean.java:


CameraBean.java
   public void processUploadedImage(ActionEvent event) {
        if (cameraImage != null &&
                cameraImage.get("contentType") != null &&
                ((String) cameraImage.get("contentType")).startsWith("image")) {
            // grab the new image and use DeviceInput to create a display resource
            File cameraFile = (File) cameraImage.get("file");
            if (cameraFile != null) {
                uploadedPhoto.add(DeviceInput.createResourceObject(
                        cameraFile, UUID.randomUUID().toString(),
                        (String) cameraImage.get("contentType")));

                // report successful upload to the user.
                FacesUtils.addInfoMessage("Upload was successful, notification sent.");
                return;
            }
        }
        // create error message for users.
        FacesUtils.addInfoMessage("The uploaded image file could not be correctly processed.");
    }


Step 4

CameraBean.java makes use of two utility helper classes: FacesUtil.java and DeviceInput.java. Please add both of these classes to the package org.icesoft.samples.mobi.example1.view.util;. You can find the source for each of these files here:

Step 5

Let's add the components required to display the uploaded camera image once it has been processed by the server. We are going to use the <mobi:graphicImage /> component to display the JSF Resource object and decorate it with a <mobi:fieldsetGroup/>. We have two both a small and large layout so for small view we will only display the currently uploaded file. Please replace the code in photo-display.xhtml with the following:


photo-display.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:icecore="http://www.icefaces.org/icefaces/core"
	xmlns:mobi="http://www.icesoft.com/icefaces/mobile/component">
	<mobi:fieldsetGroup>
		<mobi:fieldsetRow group="true">
                 Shared Photo
            </mobi:fieldsetRow>
		<mobi:fieldsetRow>
			<mobi:graphicImage value="#{cameraBean.uploadedPhoto}"
				style="width:150px;" />
		</mobi:fieldsetRow>
	</mobi:fieldsetGroup>
</ui:composition>


We also need to add the ability to show all uploaded photos to our large view. Please replace photo-list.xhtml with the following code:


photo-display.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:icecore="http://www.icefaces.org/icefaces/core"
	xmlns:mobi="http://www.icesoft.com/icefaces/mobile/component">
         <mobi:outputList>
		<mobi:outputListItem group="true">
             Recent Photos
         </mobi:outputListItem>
		<mobi:outputListItems value="#{cameraBean.uploadedPhotos}"
			var="photos">
			<mobi:graphicImage value="#{photos}" style="width:225px;" />
		</mobi:outputListItems>
	</mobi:outputList>
</ui:composition>


Run the Application

You are now able to use your device's camera to take a photo and upload it to the server. Depending on the device you are using, you should also see a style that matches the host operating system. On a desktop browser the iPad theme is the default.

Small View

For the small view, the uploaded photo will be displayed below in the Shared photo section:



Large View

For the large view, multiple photos will be show on the left hand side of the view:



Source

part2-camera.zip

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2016 ICEsoft Technologies Canada Corp.