Friday, January 4, 2013

DemoApp Sencha Touch 2.1 + PhoneGap 2.2.0 + Android

As promised in my previous post, I will demonstrate how easy it is to access the camera of your Android device with PhoneGap's Camera API.

Prerequisites:

  • You have successfully completed the tutorial in my previous post and you have your packaged app running on your Android device OR your Android emulator.
  • You already have your own Sencha Touch app and you just need to access the camera for your device.
Generating a Sencha Touch app provides you with an app folder which contains five other folders(controller, model, profile, view, store, view). A Main.js file has already been created for you in the view folder. Now we need to create a Controller for our app where we will store all our logic.
In the root of your app's folder run the following command in Terminal.app:

sencha generate controller MainController
 Your app folder should then look like this:
    Now lets modify our Main.js. Replace the code in you Main.js file with the following code.
    NB: The name of my app is "DemoApp" so replace all instances of "DemoApp" in the code with the name of your app.
    Ext.define('DemoApp.view.Main', {
        extend   : 'Ext.tab.Panel',
        xtype    : 'main',
        requires : [
            'Ext.TitleBar',
            'Ext.Img'
        ],
        config   : {
            tabBarPosition : 'bottom',
    
            items : [
                {
                    xtype   : 'container',
                    iconCls : 'home',
                    title   : 'Home',
                    items   : [
                        {
                            xtype  : 'titlebar',
                            docked : 'top',
                            title  : 'DemoApp',
                            items  : [
                                {
                                    xtype    : 'button',
                                    itemId   : 'deleteBtn',
                                    iconCls  : 'delete',
                                    align    : 'right',
                                    iconMask : true,
                                    ui       : 'decline',
                                    action   : 'delete',
                                    hidden   : true
                                }
    
                            ]
                        },
                        {
                            xtype    : 'button',
                            text     : 'Take photo',
                            itemId   : 'photoBtn',
                            margin   : '5 10 0 10',
                            iconMask : true,
                            ui       : 'confirm',
                            action   : 'capture'
                        },
                        {
                            xtype  : 'container',
                            layout : 'fit',
                            margin : '10 0 0 0',
                            itemId : 'imgContainer',
                            items  : [
                                {
                                    xtype  : 'image',
                                    itemId : 'img',
                                    height : 400
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    });
    
    Lastly, lets modify our MainController.js by replace the code in MainController.js with the following code.
    NB: The name of my app is "DemoApp" so replace all instances of "DemoApp" in the code with the name of your app.
    Ext.define('DemoApp.controller.MainController', {
        extend : 'Ext.app.Controller',
    
        config : {
            control : {
                "button[action=capture]" : {
                    tap : 'capturePhoto'
                },
                "button[action=delete]"  : {
                    tap : 'deletePhoto'
                }
            },
    
            refs : {
                photoBtn     : '#photoBtn',
                Img          : '#img',
                deleteBtn    : '#deleteBtn',
                imgContainer : '#imgContainer'
            }
        },
    
        deletePhoto : function () {
            var me = this,
                img = me.getImg(),
                deleteBtn = me.getDeleteBtn();
    
            img.destroy();
            me.createImg(); //replace destroyed img component
            deleteBtn.setHidden(true);
        },
    
        // function to replace destroyed image
        createImg   : function () {
            var me = this,
                imgContainer = me.getImgContainer(),
                img;
    
            img = {
                xtype  : 'image',
                itemId : 'img',
                height : 400
            };
    
            imgContainer.add(img);
        },
    
        capturePhoto : function () {
            var me = this,
                pictureSource, // picture source
                destinationType, // sets the format of returned value
                deleteBtn = me.getDeleteBtn(),
                photoComponent = me.getImg();
    
            // Wait for Cordova to connect with the device
            document.addEventListener("deviceready", onDeviceReady, false);
    
            // Take picture using device camera and retrieve image as base64-encoded string
            navigator.camera.getPicture(
                onPhotoDataSuccess,
                onFail, {
                    quality : 50, destinationType : destinationType.DATA_URL
                });
    
            /*-------------- Helper Functions -------------- */
            function onDeviceReady () {
                pictureSource = navigator.camera.PictureSourceType;
                destinationType = navigator.camera.DestinationType;
            }
    
            function onPhotoDataSuccess (imageData) {
                var imgSrc = 'data:image/jpeg;base64,'.concat(imageData);
    
                photoComponent.setSrc(imgSrc);
    
                //hide delete button
                deleteBtn.setHidden(false);
            }
    
            // Called if something bad happens.
            function onFail (message) {
                alert('Failed because: ' + message);
            }
        }
    });
    Finally run the following command to build and package your app onto your Android device or emulator.
    sencha app build package && build/DemoApp/android/cordova/debug
    
    NB: Again, replace "DemoApp" with the name of your app.


    Video

    Your app should work like the one in the video.


    All done! Have fun with your app :).

    3 comments:

    1. thanks a lot! I've searched a lot to get such code :)

      ReplyDelete
      Replies
      1. not working DATA_URL error

        Delete
      2. same error here... any solution for this uncaught reference error?

        Delete