Pull to refresh

Как это собрать приложение на android за 15 минут

Reading time13 min
Views20K


Для многих создание приложение — это что-то сверх силы. Но это приложение можно написать и за пару минут. Давно уже известно про написание приложений на HTML5. Последний раз, когда делал подобное, производилось множество манипуляций подключения различных библиотек и сборки на Eclipse. Сейчас приложение можно собрать из консоли одной командой cordova build.

Наша задача


За пару минут до прихода любимой сделать ей приятный сюрприз. Хорошо, когда ваши фото лежат с подписями к датам и тегами, описавшими дату. Подбираем нужные фото и начинаем делать приложение… но времени у нас мало и опыта в мобильной разработки нет, поэтому сделаем на html5 и упакуем cordova.

Для удобства у нас есть IDEA, которая нам поможет скомпилировать и сверстать приложение. Именно сверстать, потому что это единственная работа, которую предстоит сделать.

Что нам понадобится:
  1. JDK 6 (отсутствие этой версии посыпит ошибки)
  2. Android SDK
  3. NodeJs (на написание статьи 0.12.0)
  4. cordova (на написание статьи 4.3.0)
  5. Apache Ant (на написание статьи 1.8.4)
  6. IntelliJ IDEA (на написание статьи 14.0.1)


Хорошо что всё уже стояло единственно установкой для меня был cordova.

Установки компонентов
1) JDK можно скачать из архива oracle
2) Android SDK Tools не меньше 21v и соответственно версия adnroid под которую будем писать:

проверяем PATH адреса на SDK
3) NodeJs:
  1. npm install –g ant
    // check ant version
    ant -v
    

    если версии не показывает то необходимо прописать PATH


    Name : ANT_HOME
    Value : C:\Users\<Username>\AppData\Roaming\npm\node_modules\ant\ant
    PATH value : ;%ANT_HOME%\bin
    

    npm install -g cordova
    


4) IntelliJ IDEA ссылка 30 дней вам хватит на точно)

После того, как у нас всё необходимое есть, создаём новый проект.
Создание проекта
При первом же запуске устанавливаем плагин:


Перезагружаем IDE и потом заходим также в настрйоки:
Settings → Languages and Frameworks → JavaScript → PhoneGap/Cordova.



Вот теперь можно и создать новый проект:



Указываем все пути и создаём. Настраиваем компилятор:



+ этого приложение не нужно каждый раз компилировать. Достаточно выбрать:



При установленном плагине «Live Edit» ещё удобней.

Для разработки нам понадобится только 2х фала index.html — где находится наша страница (контент), index.js — основной код, который оживит приложение.

Подключаем в самом начале до тега body:

<head>
    <meta charset="utf-8" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="msapplication-tap-highlight" content="no" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, target-densitydpi=medium-dpi" />

    <link rel="stylesheet"  href="libs/jQM-flat/jquery.mobile.flatui.css">
    <link rel="stylesheet" type="text/css" href="css/index.css" />
    <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
    <link rel="stylesheet" href="stylesheets/app.css" type="text/css"/>
    <title>Любимая</title>
</head>

Выпадающие меню добавляем после body и всё остальное, что будем выводить:
<nav class="block-menu_left position-f col-1">
    <div class="block-menus">
        <img src="">
    </div>
    <ul class="menu-items">
        <li class="menu-item">
            <a href="#slid-02" slid="1">
                <p class="title">Любимая</p>
                <span class="inf">+</span>
                <span class="number">01</span>
            </a>
        </li>
        <li class="menu-item">
            <a href="#slid-02" slid="2">
                <p class="title">Места</p>
                <span class="inf">+</span>
                <span class="number">02</span>
            </a>
        </li>
        <li class="menu-item">
            <a href="#slid-02" slid="3">
                <p class="title">Память</p>
                <span class="inf">+</span>
                <span class="number">03</span>
            </a>
        </li>
    </ul>
</nav>


В самом низу до закрытия тега body подключаем:

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="libs/fastclick.min.js"></script>
<script type="text/javascript" src="libs/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="libs/jQueryMobile/jquery.mobile-1.3.2.min.js"></script>
<script type="text/javascript" src="js/plugins.min.js"></script>
<script type="text/javascript" src="js/index.min.js"></script>
<script type="text/javascript">
    app.initialize();
</script>


Для свайпов используем TouchSwipe-Jquery-Plugin https://github.com/mattbryson/TouchSwipe-Jquery-Plugin.
Все плагины я собираю в plugins.js.

Контент всего приложения:

index.html
  <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="msapplication-tap-highlight" content="no" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, target-densitydpi=medium-dpi" />

    <link rel="stylesheet"  href="libs/jQM-flat/jquery.mobile.flatui.css">
    <link rel="stylesheet" type="text/css" href="css/index.css" />
    <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
    <link rel="stylesheet" href="stylesheets/app.css" type="text/css"/>
    <title>Заголовок</title>
</head>
<body>
<nav class="block-menu_left position-f col-1">
    <div class="block-menus">
        <img src="">
    </div>
    <ul class="menu-items">
        <li class="menu-item">
            <a href="#slid-02" slid="1">
                <p class="title">текст</p>
                <span class="inf">+</span>
                <span class="number">01</span>
            </a>
        </li>
        <li class="menu-item">
            <a href="#slid-02" slid="2">
                <p class="title">текст</p>
                <span class="inf">+</span>
                <span class="number">02</span>
            </a>
        </li>
        <li class="menu-item">
            <a href="#slid-02" slid="3">
                <p class="title">текст</p>
                <span class="inf">+</span>
                <span class="number">03</span>
            </a>
        </li>
    </ul>
</nav>

    <div class="container">

        <div class="block_des-block_lis-navi">
            <a class="nivo-nextNavSlider"></a>
            <a class="nivo-prevNavSlider"></a>
        </div>

        <div id="slider" class="nivoSlider">
            <div class="slider-item" slider="n1">
                <div class="effect-text">
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст-></h1>
                </div>
            </div>
            <div class="slider-item" slider="n2">
                <h1>
                  текст
                </h1>
                <img class="images num1" src="">
                <img class="images num2" src="">
                <img class="images num3" src="">
                <div class="effect-text">
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                </div>
            </div>
            <div class="slider-item" slider="n3">
                <h1>
                 текст
                </h1>
                <img class="images num1" src="">
                <img class="images num2" src="">
                <img class="images num3" src="">
                <div class="effect-text">
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                </div>
            </div>
            <div class="slider-item" slider="n4">
                <span class="icon"></span>
                <h1>
                    текст
                </h1>
                <div class="effect-text">
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>текст</h1>
                    <h1>!!!!!!</h1>
                </div>
            </div>
        </div>
        <div id="slider_pagination" class="block_list-pagination type-slider"></div>
    </div>
</div>
<script type="text/javascript" src="libs/fastclick.min.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="libs/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="libs/jQueryMobile/jquery.mobile-1.3.2.min.js"></script>
<!--<script type="text/javascript" src="js/jquery.min.js"></script>-->
<script type="text/javascript" src="js/plugins.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
    app.initialize();
</script>
</body>
</html>


Весь код приложения:
index.js
var app = {
    SOME_CONSTANTS : false,
    initialize: function() {
        this.bindEvents();
        this.initFastClick();
        this.receivedEvent();
        this.onDeviceReady();
    },
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    initFastClick : function() {
        window.addEventListener('load', function() {
            FastClick.attach(document.body);
        }, false);
        var blockMenu = $('.block-menu_left');

        $(".block-menus, input.menu-bottom").click(function () {
            $('.block-menu_left .menu-items').toggleClass('open-menu');
        });

        $('a[href^="#"], a[href^="."]',blockMenu).click( function(){
            var nameSlid = $(this).attr('slid'),
                scroll_el = $("#slider_pagination a:nth-child("+nameSlid+")");
            $(scroll_el).click();
            return false;
        });
    },
    onDeviceReady: function() {
        $(".effect-text > h1").lettering('words').children("span").lettering().children("span").lettering();
    },
    receivedEvent: function() {
        var parentElement = document.getElementById('slider');
        $(parentElement).carouFredSel({
                width: '100%',
                height: '100%',
                mousewheel: true,
                align: 'auto',
                items: {
                    visible: {
                        min: 1,
                        max: 1
                    }
                },
                prev: {
                    button: '.nivo-nextNavSlider',
                    easing: scroll.easing,
                    onBefore: scroll.onBefore,
                    onAfter : scroll.onAfter
                },
                next: {
                    button: '.nivo-prevNavSlider',
                    easing: scroll.easing,
                    onBefore: scroll.onBefore,
                    onAfter : scroll.onAfter
                },
                pagination:{
                    container: "#slider_pagination",
                    easing: scroll.easing,
                    onBefore: scroll.onBefore,
                    onAfter : scroll.onAfter
                },
                scroll: {
                    items: 1,
                    easing: "cubic",
                    pauseOnHover: true,
                    onBefore: function( data ) {
                        var objects = data.items.old;
                        unhighlight(objects);
                    },
                    onAfter : function( data ) {
                        var objects = data.items.visible;
                        highlight(objects);
                    }
                },
                auto: false,
                autoPlay: false,
                circular: false,
                infinite: false
            }, {
                debug:false,
                transition:true,
                wrapper:{
                    element: "div",
                    classname: "caroufredsel_slider"
                }
            }
        );
        $(".slider-item",parentElement).swipe({
            swipe:function(event, direction, distance, duration, fingerCount) {
                var nameSlid = $(this).attr('slider'),
                    $class = nameSlid.substr(1, nameSlid.length);
                if (direction=='left'){
                    nameSlid = parseInt($class, 10)+1;
                }
                if (direction=='right'){
                    nameSlid = parseInt($class, 10)-1;
                }
                scroll_el = $("#slider_pagination a:nth-child("+nameSlid+")");
                $(scroll_el).click();
            }
        });
     }
};




Настройка иконки названия и подписи
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.phonegap.helloworld" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
    <name>Любимая</name>
    <description>
       Приложение для моей девушки.
    </description>
    <author email="ваш емаил" href="ссылка">
       Имя автора
    </author>
    <content src="index.html" />
    <preference name="permissions" value="none" />
    <preference name="orientation" value="default" />
    <preference name="target-device" value="universal" />
    <preference name="fullscreen" value="true" />
    <preference name="webviewbounce" value="true" />
    <preference name="prerendered-icon" value="true" />
    <preference name="stay-in-webview" value="false" />
    <preference name="ios-statusbarstyle" value="black-opaque" />
    <preference name="detect-data-types" value="true" />
    <preference name="exit-on-suspend" value="false" />
    <preference name="show-splash-screen-spinner" value="true" />
    <preference name="auto-hide-splash-screen" value="true" />
    <preference name="disable-cursor" value="false" />
    <preference name="android-minSdkVersion" value="7" />
    <preference name="android-installLocation" value="auto" />
    <gap:plugin name="org.apache.cordova.battery-status" />
    <gap:plugin name="org.apache.cordova.camera" />
    <gap:plugin name="org.apache.cordova.media-capture" />
    <gap:plugin name="org.apache.cordova.console" />
    <gap:plugin name="org.apache.cordova.contacts" />
    <gap:plugin name="org.apache.cordova.device" />
    <gap:plugin name="org.apache.cordova.device-motion" />
    <gap:plugin name="org.apache.cordova.device-orientation" />
    <gap:plugin name="org.apache.cordova.dialogs" />
    <gap:plugin name="org.apache.cordova.file" />
    <gap:plugin name="org.apache.cordova.file-transfer" />
    <gap:plugin name="org.apache.cordova.geolocation" />
    <gap:plugin name="org.apache.cordova.globalization" />
    <gap:plugin name="org.apache.cordova.inappbrowser" />
    <gap:plugin name="org.apache.cordova.media" />
    <gap:plugin name="org.apache.cordova.network-information" />
    <gap:plugin name="org.apache.cordova.splashscreen" />
    <gap:plugin name="org.apache.cordova.vibration" />
    <icon src="icon.png" />
    <icon gap:platform="android" gap:qualifier="ldpi" src="www/res/icon/android/icon-36-ldpi.png" />
    <icon gap:platform="android" gap:qualifier="mdpi" src="www/res/icon/android/icon-48-mdpi.png" />
    <icon gap:platform="android" gap:qualifier="hdpi" src="www/res/icon/android/icon-72-hdpi.png" />
    <icon gap:platform="android" gap:qualifier="xhdpi" src="www/res/icon/android/icon-96-xhdpi.png" />
    <icon gap:platform="ios" height="57" src="www/res/icon/ios/icon-57.png" width="57" />
    <icon gap:platform="ios" height="72" src="www/res/icon/ios/icon-72.png" width="72" />
    <icon gap:platform="ios" height="114" src="www/res/icon/ios/icon-57-2x.png" width="114" />
    <icon gap:platform="ios" height="144" src="www/res/icon/ios/icon-72-2x.png" width="144" />
    <icon gap:platform="webos" src="www/res/icon/webos/icon-64.png" />
    <icon gap:platform="winphone" src="www/res/icon/windows-phone/icon-48.png" />
    <icon gap:platform="winphone" gap:role="background" src="www/res/icon/windows-phone/icon-173-tile.png" />
    <gap:splash gap:platform="android" gap:qualifier="port-ldpi" src="www/res/screen/android/screen-ldpi-portrait.png" />
    <gap:splash gap:platform="android" gap:qualifier="port-mdpi" src="www/res/screen/android/screen-mdpi-portrait.png" />
    <gap:splash gap:platform="android" gap:qualifier="port-hdpi" src="www/res/screen/android/screen-hdpi-portrait.png" />
    <gap:splash gap:platform="android" gap:qualifier="port-xhdpi" src="www/res/screen/android/screen-xhdpi-portrait.png" />
    <gap:splash gap:platform="blackberry" src="www/res/screen/blackberry/screen-225.png" />
    <gap:splash gap:platform="ios" height="480" src="www/res/screen/ios/screen-iphone-portrait.png" width="320" />
    <gap:splash gap:platform="ios" height="960" src="www/res/screen/ios/screen-iphone-portrait-2x.png" width="640" />
    <gap:splash gap:platform="ios" height="1136" src="www/res/screen/ios/screen-iphone-portrait-568h-2x.png" width="640" />
    <gap:splash gap:platform="ios" height="1024" src="www/res/screen/ios/screen-ipad-portrait.png" width="768" />
    <gap:splash gap:platform="ios" height="768" src="www/res/screen/ios/screen-ipad-landscape.png" width="1024" />
    <gap:splash gap:platform="winphone" src="www/res/screen/windows-phone/screen-portrait.jpg" />
    <access origin="*" />
</widget>



Наше приложение готово.

image

Из адреса компиляции видно что наш .apk файл находится по адрессу <папка с проектом>\platforms\android\ant-build\MainActivity-debug.apk.

Эффект от приложения — стоил своей работы. Она была рада и юзала его, пока не села батарейка.

Как скомпилировать приложение под различные платформы docs.phonegap.com:

cordova platform add ios
cordova platform add wp7
cordova platform add wp8
cordova platform add windows8
cordova platform add amazon-fireos
cordova platform add android
cordova platform add blackberry10
cordova platform add firefoxos
cordova build

Исходники: github
Only registered users can participate in poll. Log in, please.
Стоит ли делать мобильные приложения на cordova/phonegap?
32.16% Да. Безусловно хороший вариант.91
37.81% Только для быстрой сборки или перевода уже готового сайта.107
30.04% Нет. Лишняя трата времени на шлак.85
283 users voted. 121 users abstained.
Tags:
Hubs:
Total votes 21: ↑9 and ↓12-3
Comments15

Articles