Статьи

Создание мобильного приложения на основе местоположения с использованием HTML5 и Javascript: часть 3

В предыдущей части серии я показал вам код всех HTML-страниц «Где я припарковал свою машину». Однако пока они бесполезны, потому что мы не написали бизнес-логику за ними. В этой статье мы начнем добавлять несколько строк конфигурации jQuery Mobile в проект, а затем я продолжу объяснение некоторых файлов JavaScript, которые обеспечивают работу приложения, а также описание нескольких API-интерфейсов Cordova.

Конфигурация jQuery для мобильных устройств

jQuery Mobile многое делает для вас, просто добавив его в свой проект без каких-либо специальных настроек. Тем не менее, будут случаи, когда вы захотите изменить или взять под контроль поведение по умолчанию. Вы можете добиться этого, написав файл конфигурации. Как говорилось в первой части серии , в приложении есть файл с именем jquery.mobile.config.js который, как вы можете догадаться, содержит конфигурацию для jQuery Mobile. Самые наблюдательные из вас могли заметить, что в файле index.html конфигурация загружается перед библиотекой. Это необходимо сделать, потому что при запуске jQuery Mobile запускается событие, называемое mobileinit , и это также событие, которое необходимо связать, чтобы переопределить настройки по умолчанию. Следовательно, вы должны подключить обработчик до запуска jQuery Mobile, но после библиотеки jQuery.

Вы можете переопределить конфигурацию по умолчанию двумя способами. Первый — это использование метода jQuery extend() как показано в следующем примере.

 $(document).bind('mobileinit', function() { $.extend($.mobile , { property1: value1, property2: value2 // and so on... }); }); 

Второй способ — установить свойства с $.mobile объекта $.mobile .

 $(document).bind('mobileinit', function() { $.mobile.property1 = value1; $.mobile.property2 = value2; // and so on... }); 

Объяснение всех свойств jQuery Mobile выходит за рамки этой статьи, однако вы можете подробно изучить их, ознакомившись с документацией по настройке jQuery Mobile .

В файле конфигурации приложения я не буду менять многие свойства. Я сосредоточусь на изменении перехода страниц, возможности отображения текста при отображении виджета загрузчика страниц и темы. Полный источник файла (который использует второй метод для установки свойств jQuery Mobile) приведен ниже.

 $(document).on( 'mobileinit', function() { // Default pages' transition effect $.mobile.defaultPageTransition = 'slide'; // Page Loader Widget $.mobile.loader.prototype.options.textVisible = true; // Theme $.mobile.page.prototype.options.theme = 'b'; $.mobile.page.prototype.options.headerTheme = 'b'; $.mobile.page.prototype.options.contentTheme = 'b'; $.mobile.page.prototype.options.footerTheme = 'b'; $.mobile.page.prototype.options.backBtnTheme = 'b'; } ); 

API

С этого раздела я начну описывать API, используемые в проекте. Помимо API Карт Google, два других — это API геолокации и API веб-хранилища — это спецификации W3C. Мы будем использовать эти API через платформу Cordova, однако некоторые устройства могут уже обеспечивать реализацию этих API. Для этих устройств Cordova будет использовать их встроенную поддержку вместо реализации Cordova, но для тех, у которых нет поддержки хранилища, реализация Cordova была разработана, чтобы оставаться совместимой со спецификациями W3C.

Управление Местами

В этом разделе я покажу вам класс с именем Position , который отвечает за управление местоположениями. Его цель состоит в том, чтобы создавать, удалять и загружать местоположения с помощью API веб-хранилища , которое состоит из двух областей: сеанса и локального. Cordova использует локальное хранилище, потому что хранилище всегда на уровне приложения. Все местоположения будут храниться в элементе, который называется «позиции».

Прежде чем продолжить, я хочу выделить два факта. Во-первых, для хранения сложных данных (например, объектов и массивов) с помощью API-интерфейса веб-хранилища необходимо использовать формат JSON. Итак, в методах класса Position вы увидите использование класса JSON и его методов parse() и stringify() . Во-вторых, Windows Phone 7 не поддерживает точечную запись, поэтому вы должны использовать методы setItem() и getItem() для обеспечения совместимости для всех устройств. Это только первая из многих странностей, с которыми вам придется столкнуться при разработке с Cordova. Поскольку с «Где я припарковал свой автомобиль» мы не ориентируемся на конкретную платформу, вы должны учитывать различную поддержку и особенности API Cordova. К счастью, первое, с чем мы столкнулись, было не так сложно.

Для целей приложения нам нужно сохранить широту и долготу пользователя и автомобиля, но нам также нужна точность измерения, чтобы дать пользователю представление о том, насколько точны наши местоположения. Я оберну первые три данных в класс под названием Coords .

Чтение координат не очень удобно для пользователя, поэтому для повышения удобства использования мы будем использовать API Карт Google для получения адреса текущего местоположения. Приложение также будет хранить дату и время, связанные с этим местоположением GPS. Помните, что приложение будет хранить до 50 местоположений, поэтому, если пределы достигнуты, лишние позиции (более старые) будут удалены с помощью метода JavaScript slice() .

Для того, что обсуждалось до сих пор, отправная точка класса Position реализована с помощью следующего кода.

 function Position(position, address, datetime) { var _db = window.localStorage; var MAX_POSITIONS = 50; this.getMaxPositions = function() { return MAX_POSITIONS; } this.position = position; this.address = address; this.datetime = datetime; } function Coords(latitude, longitude, accuracy) { this.latitude = latitude; this.longitude = longitude; this.accuracy = accuracy; } 

Как вы уже догадались, в смысле объектно-ориентированного подхода в _db свойство _db является приватным, а MAX_POSITIONS — константой. С данным скелетом мы не можем многое сделать, на самом деле нам нужны методы, позволяющие приложению взаимодействовать с API-интерфейсом веб-хранилища. Эти методы

  • savePosition() для сохранения позиции автомобиля
  • updatePosition() обновляет последнюю updatePosition() позицию с адресом, если обратный вызов API Google Maps завершился успешно
  • deletePosition() чтобы позволить пользователю удалить ранее сохраненную позицию
  • getPositions() для загрузки всех сохраненных мест

Во всех перечисленных методах я проверю, является ли база данных var ( _db ) null и если да, я покажу пользователю сообщение об ошибке. Я тестирую это состояние, потому что мне нравится пытаться предвидеть и управлять неожиданными проблемами интерфейса. Чтобы показать сообщение, я воспользуюсь методом alert() API Cordova Notification . Большинство поддерживаемых платформ используют собственное диалоговое окно, однако другие (например, Bada 2.X) используют внешний вид хорошо известной функции браузера alert() , которая менее настраиваема. Функция Cordova alert() принимает до четырех параметров:

  1. сообщение : строка, содержащая сообщение для отображения
  2. alertCallback : обратный вызов для вызова при закрытии диалогового окна предупреждения.
  3. title : заголовок диалогового окна (по умолчанию «Alert»)
  4. buttonName : текст кнопки, включенной в диалог (по умолчанию «ОК»)

Есть еще одна странность, которую мы должны учитывать при разработке с PhoneGap. Windows Phone 7 игнорирует имя кнопки и всегда использует значение по умолчанию. И нет встроенного оповещения браузера, поэтому, если вы хотите использовать alert('message'); Вы должны назначить window.alert = navigator.notification.alert . Полный список различий между мобильными операционными системами см. В документации Cordova Notification alert() .

Если вы зашли так далеко, вы заслуживаете приз: полный источник описанных методов. Вы можете скопировать и вставить код в класс Position после методов getMaxPositions() или ранее, это не имеет значения.

 this.savePosition = function(position, address) { if (!_db) { console.log('The database is null. Unable to save position'); navigator.notification.alert( 'Unable to save position', function(){}, 'Error' ); } var positions = this.getPositions(); if (positions == null) positions = []; positions.unshift(new Position(position, address, new Date())); // Only the top MAX_POSITIONS results are needed if (positions.length > this.MAX_POSITIONS) positions = positions.slice(0, this.MAX_POSITIONS); _db.setItem('positions', JSON.stringify(positions)); return positions; } this.updatePosition = function(index, position, address) { if (!_db) { console.log('The database is null. Unable to update position'); navigator.notification.alert( 'Unable to update position', function(){}, 'Error' ); } var positions = this.getPositions(); if (positions != null && positions[index] != undefined) { positions[index].coords = position; positions[index].address = address; } _db.setItem('positions', JSON.stringify(positions)); return positions; } this.deletePosition = function(index) { if (!_db) { console.log('The database is null. Unable to delete position'); navigator.notification.alert( 'Unable to delete position', function(){}, 'Error' ); } var positions = this.getPositions(); if (positions != null && positions[index] != undefined) positions.splice(index, 1); _db.setItem('positions', JSON.stringify(positions)); return positions; } this.getPositions = function() { if (!_db) { console.log('The database is null. Unable to retrieve positions'); navigator.notification.alert( 'Unable to retrieve positions', function(){}, 'Error' ); } var positions = JSON.parse(_db.getItem('positions')); if (positions == null) positions = []; return positions; } 

Вывод

В этой третьей части вы увидели, как настроить «Где я припарковал свой автомобиль», чтобы изменить переход страниц, вариант отображения текста при отображении виджета загрузчика страниц и тему. Вы также узнали, как хранить позиции автомобиля с помощью API веб-хранилища. В следующей статье я покажу вам два последних файла JavaScript: maps.js и functions.js . Первая содержит функции для инициализации приложения и некоторые другие служебные функции, а вторая имеет функции, которые используют API Карт Google для рисования карты и маршрута к автомобилю.