2

I have gone through this tutorial http://coenraets.org/blog/phonegap-tutorial/. It is working fine for searching an employee and also renders the view for single employee.But location , contacts and camera are not working. It is only saying ….API not supported.I have used phonegap build and installed apk in my device.

I have also tried by added plugins camera,console,device,contacts,dialogs and geolocation and runned the following commands

cordova build

cordova emulate android

But still not on my way?

Here is all of my code

index.html

<html>
    <head>
        <script src="css/source-sans-pro.js"></script>
        <link href="css/styles.css" rel="stylesheet"/>
    </head>
    <body>
        <script id="home-tpl" type="text/x-handlebars-template">
            <div class='header'><h1>Home</h1></div>
            <div class='search-bar'><input class='search-key' type="search"/></div>
            <div class="scroll"><ul class='employee-list'></ul></div>
        </script>
        <script id="employee-li-tpl" type="text/x-handlebars-template">
            {{#.}}
            <li><a href="#employees/{{this.id}}">{{this.firstName}} {{this.lastName}}<br/>{{this.title}}</a></li>
            {{/.}}
        </script>

        <script id="employee-tpl" type="text/x-handlebars-template">
            <div class='header'><a href='#' class="button header-button header-button-left">Back</a><h1>Details</h1></div>
            <div class='details'>
                <img class='employee-image' src='img/{{firstName}}_{{lastName}}.jpg' />
                <h1>{{firstName}} {{lastName}}</h1>
                <h2>{{title}}</h2>
                <span class="location"></span>
                <ul>
                    <li><a href="tel:{{officePhone}}">Call Office<br/>{{officePhone}}</a></li>
                    <li><a href="tel:{{cellPhone}}">Call Cell<br/>{{cellPhone}}</a></li>
                    <li><a href="sms:{{cellPhone}}">SMS<br/>{{cellPhone}}</a></li>
                    <li><a href="#" class="add-location-btn">Add Location</a></li>
                    <li><a href="#" class="add-contact-btn">Add to Contacts</a></li>
                    <li><a href="#" class="change-pic-btn">Change Picture</a></li>
                </ul>
            </div>
        </script>



        <script src="lib/jquery-1.8.2.min.js"></script>
        <script src="lib/iscroll.js"></script>
        <script src="lib/handlebars.js"></script>
        <script src="js/storage/memory-store.js"></script>
        <script src="js/HomeView.js"></script>
        <script src="js/EmployeeView.js"></script>
        <script src="js/main.js"></script>

        </body>
</html>

main.js

var app = {
   initialize: function() {
        var self = this;
        this.detailsURL = /^#employees\/(\d{1,})/;
        this.registerEvents();
        this.store = new MemoryStore(function() {
            self.route();
        });
   },
    showAlert: function (message, title) {
        if (navigator.notification) {
            navigator.notification.alert(message, null, title, 'OK');
        } else {
            alert(title ? (title + ": " + message) : message);
        }
    },

    registerEvents: function() {
        $(window).on('hashchange', $.proxy(this.route, this));
        var self = this;
        // Check of browser supports touch events...
        if (document.documentElement.hasOwnProperty('ontouchstart')) {
            // ... if yes: register touch event listener to change the "selected" state of the item
            $('body').on('touchstart', 'a', function(event) {
                $(event.target).addClass('tappable-active');
            });
            $('body').on('touchend', 'a', function(event) {
                $(event.target).removeClass('tappable-active');
            });
        } else {
            // ... if not: register mouse events instead
            $('body').on('mousedown', 'a', function(event) {
                $(event.target).addClass('tappable-active');
            });
            $('body').on('mouseup', 'a', function(event) {
                $(event.target).removeClass('tappable-active');
            });
        }

    },
    route: function() {
        var self = this;
        var hash = window.location.hash;
        if (!hash) {
            if (this.homePage) {
                this.slidePage(this.homePage);
            } else {
                this.homePage = new HomeView(this.store).render();
                this.slidePage(this.homePage);
            }
            return;
        }
        var match = hash.match(this.detailsURL);
        if (match) {
            this.store.findById(Number(match[1]), function(employee) {
                self.slidePage(new EmployeeView(employee).render());
            });
        }
    },
    slidePage: function(page) {

        var currentPageDest,
        self = this;

        // If there is no current page (app just started) -> No transition: Position new page in the view port
        if (!this.currentPage) {
            $(page.el).attr('class', 'page stage-center').attr('id', 'homePage');;
            $('body').append(page.el);
            this.currentPage = page;
            return;
        }

        // Cleaning up: remove old pages that were moved out of the viewport
        $('.stage-right, .stage-left').not('#homePage').remove();

        if (page === app.homePage) {
            // Always apply a Back transition (slide from left) when we go back to the search page
            $(page.el).attr('class', 'page stage-left');
            currentPageDest = "stage-right";
        } else {
            // Forward transition (slide from right)
            $(page.el).attr('class', 'page stage-right');
            currentPageDest = "stage-left";
        }

        $('body').append(page.el);

        // Wait until the new page has been added to the DOM...
        setTimeout(function() {
            // Slide out the current page: If new page slides from the right -> slide current page to the left, and vice versa
            $(self.currentPage.el).attr('class', 'page transition ' + currentPageDest);
            // Slide in the new page
            $(page.el).attr('class', 'page stage-center transition');
            self.currentPage = page;
        });

    }


};

app.initialize();

HomeView.js

var HomeView = function(store) {
   this.initialize = function() {
        // Define a div wrapper for the view. The div wrapper is used to attach events.
       this.el = $('<div />');
       var that = this;
       this.el.on('keyup', '.search-key', function(){
           that.findByName();
       });
    };

    this.initialize();

    this.render = function() {
        this.el.html(HomeView.template());
        return this;
    };

   this.findByName = function() {
        store.findByName($('.search-key').val(), function(employees) {
            $('.employee-list').html(HomeView.liTemplate(employees));
            if (self.iscroll) {
                console.log('Refresh iScroll');
                self.iscroll.refresh();
            } else {
                console.log('New iScroll');
                self.iscroll = new iScroll($('.scroll', self.el)[0], {hScrollbar: false, vScrollbar: false });
            }
        });
   };
}

HomeView.template = Handlebars.compile($("#home-tpl").html());
HomeView.liTemplate = Handlebars.compile($("#employee-li-tpl").html());

EmployeeView.js

var EmployeeView = function(employee) {
    this.initialize = function() {
        this.el = $('<div/>');
        var that=this;

        this.el.on('click', '.add-location-btn',function(event){
             that.addLocation(event);
        });


        this.el.on('click', '.add-contact-btn',function(event){
            that.addToContacts(event);
        });

        this.el.on('click', '.change-pic-btn',function(event){ 
            that.changePicture(event);
        });
    };

    this.initialize();
    this.render = function() {
        this.el.html(EmployeeView.template(employee));
        return this;
    };

    this.addToContacts = function(event) {
        event.preventDefault();
        console.log('addToContacts');
        if (!navigator.contacts) {
            app.showAlert("Contacts API not supported", "Error");
            return;
        }
        var contact = navigator.contacts.create();
        contact.name = {givenName: employee.firstName, familyName: employee.lastName};
        var phoneNumbers = [];
        phoneNumbers[0] = new ContactField('work', employee.officePhone, false);
        phoneNumbers[1] = new ContactField('mobile', employee.cellPhone, true); // preferred number
        contact.phoneNumbers = phoneNumbers;
        contact.save();
        return false;
    };

    this.changePicture = function(event) {
        event.preventDefault();
        if (!navigator.camera) {
            app.showAlert("Camera API not supported", "Error");
            return;
        }
        var options =   {   quality: 50,
                            destinationType: Camera.DestinationType.DATA_URL,
                            sourceType: 1,      // 0:Photo Library, 1=Camera, 2=Saved Photo Album
                            encodingType: 0     // 0=JPG 1=PNG
                        };

        navigator.camera.getPicture(
            function(imageData) {
                alert("this is image data::"+imageData)
                $('.employee-image', this.el).attr('src', "data:image/jpeg;base64," + imageData);
            },
            function() {
                app.showAlert('Error taking picture', 'Error');
            },
            options);

        return false;
    };

    this.addLocation = function(event) {
        event.preventDefault();
        console.log('addLocation');
        navigator.geolocation.getCurrentPosition(
            function(position) {
                $('.location', this.el).html(position.coords.latitude + ',' + position.coords.longitude);
            },
            function() {
                alert('Error getting location');
            });
        return false;
    };

}

EmployeeView.template = Handlebars.compile($("#employee-tpl").html());
gaurav
  • 128
  • 1
  • 8

3 Answers3

3

I am just doing that tutorial myself, it is very good but targeted at earlier versions of PhoneGap. First of all the file called namedconfig.xml in the tutorial should now be called config.xml, which is important to change!

You mention that you are using an emulator, but you might well find that some of the items such as contacts and geolocation, will only work on a physical device.

Also, since then PhoneGap have introduced the idea of plugins. You mention plugins but have you added them correctly? For me, I found that for my Android 4.1.1 device I only needed to add the following to my config.xml to get it all working. I just put them after the feature tag.

<gap:plugin name="org.apache.cordova.contacts" />
<gap:plugin name="org.apache.cordova.camera" />

However depending on your device you may find you need others too, such as geolocation and dialogs. A list of plugins is here: https://build.phonegap.com/plugins. Click PhoneGap Plugins to get the functionality that used to be built in by default.

0

I have a SO Q & A that should solve your problem.

Basically, the platforms and plugins are not installed, even though you think they are. Run cordova plugins ls to check. To actually install them, add them from git repos. Everything is in the link. I hope it helps.

Community
  • 1
  • 1
Roman
  • 8,826
  • 10
  • 63
  • 103
0

you should include cordova.js before other js:

<script src="cordova.js"></script>
<script src="lib/jquery-1.8.2.min.js"></script>
<script src="lib/iscroll.js"></script>
<script src="lib/handlebars.js"></script>
<script src="js/storage/memory-store.js"></script>
<script src="js/HomeView.js"></script>
<script src="js/EmployeeView.js"></script>
<script src="js/main.js"></script>
farhad
  • 1