zoukankan      html  css  js  c++  java
  • [译] 第十天: PhoneGap

    前言

    今天的30天挑战,我决定学习手机开发。长期以来,我对手机开发心存疑虑,认为大部分的应用没有手机市场,实际上,我一直对手机开发提不起兴趣。然后,在移动方面的大力发展,事实上越来越多的人选择用手机上网,我决定试试手机开发。我将用PhoneGap开启我的移动开发之旅。 

     

    在这篇博客里,我们先看看PhoneGap的基础,然后用它开发一个手机应用。 

    手机应用用例 

    我们今天要开发的手机应用是一个对30天学习30种技术挑战的阅读器。用户可以在任何Android, Symbian, webOS, 或者 Windows Phone上安装,可以从https://build.phonegap.com/apps/635001/share下载。 

     

    这个应用可以做以下: 

    1. 给出这个系列已经发布的博客列表,用户点击任何博客,都会在手机浏览器里打开。  

                                        

    1. 读者可以用它发表反馈。 

                            

    PhoneGap 是什么? 

    PhoneGap是一个免费开源的移动开发框架,采用如HTML, CSSJavaScript的标准Web技术。 

     

    它封装了Web应用资源,而不仅仅是本地App,并且可以上传到各种App 商店。更重要的是,可以用它跨平台开发,意味着,理论上你只要对这个应用写一次,就可以发到不同的平台上。比如,这个程序我是为Android写的,但是用PhoneGap build, 也可以生成其他平台的包。大部分的标准功能,如相机,定位,存储等等可以用JavaScript API写,PhoneGap提供的JavaScript API是基于目标平台的。 

     

    一些关于PhoneGap的事迹:

    1. 2009年,Nitobi开发了一个移动开发框架叫PhoneGap. 
    2. 201110月,Adobe收购Notobi(PhoneGap新创公司). 
    3. AdobePhoneGap设立Apache基金。 
    4. 有个开源项目叫Apache Cordova. 
    5. PhoneGapAdobe实施在开源项目Apacke Cordova上的,PhoneGap的核心使用Apache Cordova. 
    6. 它有基于体系的插件,所有设备功能可用插件形式,我们这里会用到几个插件。 

    我为什么关注PhoneGap? 

    我考虑PhoneGap的原因: 

    1. 没有必要学习每个设备上每个应用的原生应用开发。如果开发者想在多个平台上开发,PhoneGap的跨平台特色可以节约很多时间和努力。我会HTML,CSSJavaScript,所以可以很顺利开始手机开发。 
    2. 对于开发用REST APICRUD手机应用很有效。 
    3. 不用强制开发者使用某一CSS库,可以自由选择自己的风格,我这里使用jQuery. 

    PhoneGap前提准备 

    PhoneGap需要NOdeJS,我们用npm安装。NPM是NodeJS的包管理器,新版本的NodeJS自带,可以从官网下载最新版本。 

     

    同时你也需要安装目标平台的SDK, 例如,你想创建Android程序,就需要安装Android开发工具。PhoneGap用他们的SDK去建目标平台的包。 

    开始PhoneGap 

    使用以下方式安装PhoneGap. 

    $ sudo npm install -g phonegap 

    这个命令会全局安装PhoneGap包,允许Phonegap命令在任何路径可用。 

    要安装插件,就要安装Cordova 命令器。 

    输入以下命令安装Cordova. 

    $ sudo npm install -g cordova 

    Github 仓库 

    今天的demo在 github: 30technologies30days-mobile-app

    创建PhoneGap应用 

    phonegap提供了用命令新建模板phonegap项目,输入以下命令。 

    $ phonegap create reader --id io.reader --name Reader30 

    这个命令会创建一个reader路径。 

    第一个参数指定了阅读器生成的路径,另外两个参数可选,io.reader提供项目的反转域标识,Reader30提供程序显示的文字。  

     

    这个phonegap阅读器程序的文件夹结构如图。

     来看看各生成的文件夹.

    1. Merges文件夹提供空间给要发布到指定平台的特定资源。例如,我们可能用mergesAndriod设备改变字体大小。
    2. Platorms路径保存平台创建文件,当我们创建了一个项目,这些原始文件都会别置于这个平台路径下。
    3. Plugins文件夹保存这个程序要用的插件,当我们安装了一个插件,这个文件就会在这个路径下。
    4. WWW路径存放程序的源文件如html, cssimg文件。我们主要在这里花费时间。Config.xml文件包含了程序生成和分配需要的元数据,元数据包含如程序名字,描述,作者信息,程序权限等,这里有完整列表。

     

    Android上运行程序,输入以下命令。

    $ phonegap run android

    它会先为Android创建阅读器程序,如果有设备连接好就会在上面跑这个示例程序。如果没有连接的,Android模拟器会启动并在上面运行程序。

    注意:Android模拟器的性能很差,所以建议你连接真实移动设备。加速Android模拟器的建议参考Grant Shipley博客

    开发手机应用

    我们的程序如上所示有两个页面,一个一个来写。

    第一个:列出所有博客

    主页列出这段时间发表的所有博客,先更新index.html,从我的git上复制cssjavascript文件。

        <!DOCTYPE html>
        <html>
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <meta name="apple-mobile-web-app-capable" content="yes">
          <meta name="apple-mobile-web-app-status-bar-style" content="black">
          <title>Learn 30 technologies in 30 days</title> 
          <link rel="stylesheet" href="css/vendor/jquery.mobile-1.3.1.min.css"> 
          <link rel="stylesheet" href="css/vendor/jquery.loadmask.css"> 
        </head>
        <body> 
        <div data-role="page" id="mainPage">
                <div data-role="header" data-position="fixed"> 
                    <h1>30Technologies30Days</h1>
                    <a href="#feeback" data-icon="edit" data-theme="b" class="feedback ui-btn-right" data-role="button" data-inline="true" data-ajax="false">Feedback</a> 
                    <div data-role="navbar">
                    <ul>
                        <li><a href="#home" class="home ui-btn-active" data-icon="home">Home</a></li> 
                    </ul>
                </div>
                </div> 
                <div id="main" data-role="content"> 
                </div> 
                <div data-theme="a" data-role="footer">
                <h3>
                    © Shekhar Gulati 2013
                </h3>
            </div>
        </div> 
        <script type="text/x-mustache-template" id="home-template">
          <ul id="blogs" data-role="listview" data-filter="true" data-filter-placeholder="Search blogs..." data-inset="true"> 
          </ul>
        </script> 
        <script type="text/x-mustache-template" id="blog-template">
        <li>
            <a href="{{url}}" target="_blank">
                <h3>{{title}}</h3>
                <p><strong>{{publishedOn}}</strong></p>
            </li>
        </script>  
        <script src="phonegap.js"></script>
        <script src="js/vendor/jquery-1.9.1.min.js"></script>
        <script src="js/vendor/jquery.mobile-1.3.1.min.js"></script>
        <script src="js/vendor/jquery.ui.map.js"></script>
        <script src="js/vendor/jquery.loadmask.min.js"></script>
        <script src="js/vendor/jquery.timeago.js"></script>
        <script type="text/javascript" src="js/vendor/mustache.js"></script>
        <script type="text/javascript" src="js/app.js"></script>
        </body>
        </html>
    View Code

    以上代码会导入所有需要的cssjavascript文件,用jQuery mobile实现适合本地程序的样式,同时也定义了mustache模板来列出博客。

     

    程序的javascriptapp.js文件里。

    $(document).ready(function(){
        homeView();
        $('.home').on('tap', renderHomeView);   
        $('.feedback').on('tap', renderFeedbackFormView); 
     
    }); 
    function renderHomeView(event){
        event.preventDefault();
        homeView();
    } 
    function homeView(){
        $('#main').empty();
        $('.home').addClass("ui-btn-active");
        $('#main').html(template("home"));
        var url = 'http://30technologiesin30days-t20.rhcloud.com/api/v1/blogs';
        $.mobile.loading( 'show',{});
        $.ajax({
            url : url,
            dataType : 'json',
            success : function(data){
                $.mobile.loading( 'hide',{});
                $.each(data , function(i , obj){
                    var template = $("#blog-template").html();
                    obj.publishedOn = $.timeago(obj.publishedOn);
                    $("#blogs").append(Mustache.to_html(template,obj));
                    $('#blogs').listview('refresh');
                });
            },
            error : function(XMLHttpRequest,textStatus, errorThrown) {   
                $.mobile.loading( 'hide',{text:"Fetching blogs.."});  
                alert("Something wrong happended on the server. Try again..");   
            }
        }) 
        $('#main').trigger('create'); 
    } 
    function template(name) {
            return Mustache.compile($('#'+name+'-template').html());
    } 
    function showNotification(message , title){
            if (navigator.notification) {
            navigator.notification.alert(message, null, title, 'OK');
            } else {
                alert(title ? (title + ": " + message) : message);
            }
    }
    View Code

    以上app.js做了以下动作:

    1. 绑定文档ready事件,准备好后,主页会被加载。
    2. 主页用REST调用提取所有博客,我们用jQuery完成REST调用。
    3. 当接收到数据,就迭代创建博客的列表。最后刷新显示页。

    允许访问REST服务器

    PhoneGap默认是不允许程序访问远程资源,这就意味着程序不能使用REST 调用,为了让程序能使用REST调用,就得使PhoneGap允许访问,可以用一个 * 通配符使程序可访问所有资源,参照文档

    config.xml里更新访问配置。

    <access origin="*" />

    安装插件

    这个程序用了几个插件来访问设备的特定功能。

    $ cordova plugin add org.apache.cordova.geolocation
    $ cordova plugin add org.apache.cordova.dialogs
    1. 第一个命令安装定位插件,Geolocation提供设备的位置信息,例如经纬度,我们会在后面使用,更多用法参考文档
    1. 第二个命令安装会话插件,dialogs提供本地常用提醒,更多使用参考文档

    第二个:反馈提交表

    第二个页面允许用户对这个系列提交反馈。

    添加feedback表来记录。

    <script type="text/x-mustache-template" id="feedback-form-template"> 
        <form action="" id="feedbackForm">
                <div data-role="fieldcontain">
                    <label for="name">
                        Describe
                    </label>
                    <input type="text" name="name" id="name" placeholder="Full Name eg. Shekhar Gulati ">
                </div>
                <div data-role="fieldcontain">
                    <label for="description">
                        Describe
                    </label>
                    <textarea name="description" id="description" placeholder="Message for author.."></textarea>
                </div>
                <div id="checkboxes1" data-role="fieldcontain"> 
                    <fieldset data-role="controlgroup" data-type="vertical">
                        <legend>
                            Share my location
                        </legend>
                        <input id="sharemylocation" name="sharemylocation" type="checkbox" value="true">
                        <label for="sharemylocation">
                            Share
                        </label>
                    </fieldset>
                </div>
                <button id="create-button" data-inline="true">Feedback</button>
            </form>
    </script>
    View Code

    这个app.js文件更新了监听feedback类里所有元素的tap事件,feedbakck类在顶部添加了feedback链接。

    $(document).ready(function(){
        homeView();
        $('.home').on('tap', renderHomeView);   
        $('.feedback').on('tap', renderFeedbackFormView); 
     
    }); 
    function renderFeedbackFormView(event){
        event.preventDefault();
        $('#main').empty();
        $('#main').html(template("feedback-form"));
        $('#main').trigger('create');
        $('#create-button').bind('tap',shareFeedback);
    } 
    function shareFeedback(event){
            event.preventDefault();
            $('#feedbackForm').mask();        
            var name = $('#name').val();
            var description = $('textarea#description').val();
            var sharemylocation = $("#sharemylocation:checked").val() === undefined ? "false" : "true";
            var data = {name:name , description:description , lngLat :[]};
            if(sharemylocation === "true"){
                navigator.geolocation.getCurrentPosition(function(position){
                    var lngLat = [position.coords.longitude , position.coords.latitude];
                    data.lngLat = lngLat;
                    postFeedback(data);
     
                } , function(error){
                        alert('code: '    + error.code    + '
    ' +
                          'message: ' + error.message + '
    ');
                        $('#feedbackForm').unmask(); 
                });
            }else{
                postFeedback(data);
            } 
    } 
    function postFeedback(data){
        $.ajax({
                    type : 'POST',
                    url : 'http://30technologiesin30days-t20.rhcloud.com/api/v1/feedback',
                    crossDomain : true,
                    data : JSON.stringify(data),
                    dataType : 'json',
                    contentType: "application/json",
                    success : function(data){
                        $('#feedbackForm').unmask();
                        $('#feedbackForm')[0].reset();
                        showNotification('Received your feedback', 'Info');
                        homeView();
                    },
                    error : function(XMLHttpRequest,textStatus, errorThrown) {     
                      $('#feedbackForm').unmask();
                      alert("Error status :"+textStatus);  
                      alert("Error type :"+errorThrown);   
                    }
            });
    }
    View Code

     

    提交feedback表后我们可以从表里得到数据,如果用户勾选了sharemylocation,我们就用geolocation API获取用户位置。最后,我们给REST web服务器提交POST, 对一个成功的反馈提交,可以给用户提示。

    运行程序

    现在可以输入以下命令安装和运行程序。

    $ phonegap run android

     

    这是今天的内容,继续给反馈吧。

     

    原文:https://www.openshift.com/blogs/day-10-phonegap-mobile-development-for-the-dummies

  • 相关阅读:
    Eureka 系列(04)客户端源码分析
    Eureka 系列(03)Spring Cloud 自动装配原理
    Eureka 系列(02)Eureka 一致性协议
    Eureka 系列(01)最简使用姿态
    Feign 系列(05)Spring Cloud OpenFeign 源码解析
    python 线程,进程与协程
    Python IO多路复用
    python 作用域
    python 网络编程:socket(二)
    python 网络编程:socket
  • 原文地址:https://www.cnblogs.com/endless-on/p/3488257.html
Copyright © 2011-2022 走看看