четверг, 26 июля 2012 г.

PhoneGap: пишем для Android на Html и JavaScript


Разработка для мобильных платформ становится всё популярнее, затягивая всё больше программистов из смежных отраслей. Если вы писали, к примеру, серверный Java-код, то проблем с освоением платформы Android у вас скорее всего не будет. А если "в прошлой жизни" вы делали сайты на html+css+javascript? Тут нужно не только учить новый язык, но и осваивать "настоящее" ООП, которое не сразу и не каждому даётся. Если же вы решили охватить и IPhone/IPad, то учить нужно ещё и Objective-C. Что же делать, если учить новые технологии некогда, а подарить миру своё приложение для смартфонов хочется уже сейчас?
Фреймворк PhoneGap помогает решить эту проблему. Пишите приложение как локальную веб-страницу, а доступ к возможностям смартфона предоставит PhoneGap. Тут я постараюсь дать пошаговое руководство, как сделать простое Android-приложение на Html и JavaScript с помощью PhoneGap. Писать будем в IntelliJ IDEA. Эта замечательная IDE в последнее время сумела выбросить Eclipse из моего компьютера :)
Итак, приступим. Тут будет много скриншотов: лучше один раз увидеть, чем один раз прочитать.
Создаём Android-проект в IntelliJ IDEA



Выбираем тип модуля - Android:


Указываем имя проекта, имя основного пакета и т.п.:


Получаем самый обычный Android-проект, в который теперь будем добавлять библиотеки PhoneGap.

Добавляем немного PhoneGap...

Из архива, который можно скачать тут, нам понадобится:
  1. Файл cordova-2.0.0.jar из lib/android копируем в libs
  2. Файл cordova-2.0.0.js из lib/android копируем в assets/www
  3. Каталог xml из lib/android копируем в res
В результате получим такую структуру файлов в нашем проекте:


Библиотеку cordova-2.0.0.jar добавляем в зависимости нашего модуля:


Теперь меняем код главного Activity:

package net.multipi.pgt;
 
import android.os.Bundle;
import org.apache.cordova.DroidGap;
 
public class MyActivity extends DroidGap {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.loadUrl("file:///android_asset/www/index.html");
    }
}

Тут мы изменили имя абстрактного предка на DroidGap, убрали метод setContentView, который устанавливал "андроидную" разметку и выполнили загрузку локальной html-страницы, в которой дальше всё и будет происходить. Кстати и создадим её в каталоге assets/www:


Желательно ещё не забыть подправить файл AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="net.multipi.pgt"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8"/>
    <supports-screens
            android:largeScreens="true"
            android:normalScreens="true"
            android:smallScreens="true"
            android:resizeable="true"
            android:anyDensity="true"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
    <application android:label="@string/app_name">
        <activity android:name="MyActivity"
                  android:configChanges="orientation|keyboardHidden"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest> 

Вся это гора разрешений, которую мануалы PhoneGap рекомендуют нам запросить у пользователя, несомненно заставит его задуматься о вменяемости разработчика. Поэтому уберите те uses-permission, которые вам реально не нужны.

А дальше всё пишем на Html5

Теперь можно забыть о загадочной платформе Android и вернуться в милый уютный мир html, css и javascript. Открываем index.html и пишем там:

<!DOCTYPE html>
<html>
<head>
    <title>PhoneGap example</title>
    <script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
    <script type="text/javascript">
 
        var getInfo = function () {
            var info = "Device UID:" + device.uuid;
            info += "<br/>Screen width:" + screen.width;
            info += " height:" + screen.height;
            document.getElementById("info").innerHTML = info;
        };
 
    </script>
</head>
<body onload="document.addEventListener('deviceready', getInfo, true);">
<h1>Hello PhoneGap!</h1>
<div id="info"></div>
</body>
</html>

Запускаем проект на эмуляторе и получаем:


Наше приложение выводит то, что мы рисуем в html а также данные, которые PhoneGap получил от устройства: IMEI и разрешение экрана. Как мы добились этого от PhoneGap? У нас есть несколько объектов, которые представляют нам доступ к свойствам системы (например device и screen). Всё что мы хотим от устройства, мы получим от них. Полное описание объектов и их свойств можно получить в документации к PhoneGap.

2 комментария:

  1. Все собрал как написано. Надпись Hello PhoneGap! в эмуляторе выводится, а вот тех.данные нет. Подскажите, что не так!

    ОтветитьУдалить
  2. Где вот это менять(в каком файле)
    ---------------------------------------------------------
    Теперь меняем код главного Activity:

    package net.multipi.pgt;

    import android.os.Bundle;
    import org.apache.cordova.DroidGap;

    public class MyActivity extends DroidGap {

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.loadUrl("file:///android_asset/www/index.html");
    }
    }

    ОтветитьУдалить