Статьи

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

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

Сервисные функции

Как описано во введении, есть еще одна вспомогательная функция, которая должна объяснить, — это та, которая извлекает значение параметра внутри URL.

Получение значения параметра URL

Протокол HTTP имеет несколько методов запроса, но два наиболее распространенных — это GET и POST. Как вы, скорее всего, знаете, метод GET отправляет данные через переменные и значения, добавляющие URL, после вопросительного знака (www.website.com?variableone=build&variable2=mobile). К сожалению, jQuery Mobile не предлагает собственный метод для получения одного параметра URL. Фактически, единственный метод, который делает что-то подобное, это $.mobile.path.parseUrl() . Однако этот метод возвращает объект, имеющий свойство search которое дает вам все параметры, а не только тот, который требуется.

Чтобы удовлетворить наши потребности в разработке, я создал следующую функцию.

 function urlParam(name) { var results = new RegExp('[?&]' + name + '=([^&#]*)').exec(window.location.href); if (results != null && typeof results[1] !== 'undefined') return results[1]; else return null; } 

Инициализация приложения

Теперь, когда вы ознакомились со всеми функциями утилит, я объясню две функции инициализации, которые обеспечивают «Где я припарковал свой автомобиль». Первая функция, которую мы рассмотрим, называется initApplication() , определяет поведение элементов приложения, таких как кнопки домашней страницы ( index.html ). Страница истории positions.html ( positions.html ). initApplication() отвечает за управление несколькими другими элементами, которые вы увидите более подробно в следующих разделах.

Отключить кнопки условно

В четвертой части нашей серии я проиллюстрировал требования нашего приложения, продемонстрировав вам функцию, которая проверяет, все ли они выполнены ( checkRequirements() ). Когда пользователь запускает «Где я припарковал свой автомобиль», если тест не пройден, кнопки установки положения и поиска автомобиля будут отключены, и пользователь будет уведомлен о проблемах подключения. (В этом сценарии им не хватает доступа в Интернет, необходимого для использования API Карт Google.) Это делается с помощью следующего кода:

 $('#set-car-position, #find-car').click(function() { if (checkRequirements() === false) { $(this).removeClass('ui-btn-active'); return false; } }); 

Быть отзывчивым

Чтобы улучшить интерфейс приложения и сделать его отзывчивым, я создал функцию updateIcons() которую я буду использовать в качестве обработчика для pagebeforecreate и событий pagebeforecreate .

 $(document).on('pagebeforecreate orientationchange', updateIcons); 

Получить или установить позицию

Следующим фрагментом кода, одной из наиболее важных частей всего приложения, является функция обратного вызова, присоединенная к событию pageshow элемента map-page . Он отвечает за проверку того, требуется ли странице установить или получить позицию автомобиля, и действовать соответствующим образом с помощью функции urlParam() . Если значение переменной requestType set , мы будем использовать метод getCurrentPosition() API Geolocation, чтобы получить позицию и затем сохранить ее в базе данных приложения с помощью API-интерфейса Web Storage. После сохранения позиции я буду использовать requestLocation() и displayMap() нашего класса Map для получения адреса местоположения автомобиля и отображения карты, указывающей положение пользователя с маркером.

С другой стороны, если значение requestType равно get , мы будем использовать метод watchPosition() API геолокации, чтобы опрашивать местоположение пользователя, чтобы постоянно обновлять маршрут к его машине.

Необходимый код ниже.

 $('#map-page').live( 'pageshow', function() { var requestType = urlParam('requestType'); var positionIndex = urlParam('index'); var geolocationOptions = { timeout: 15 * 1000, // 15 seconds maximumAge: 10 * 1000, // 10 seconds enableHighAccuracy: true }; var position = new Position(); $.mobile.loading('show'); // If the parameter requestType is 'set', the user wants to set // his car position else he want to retrieve the position if (requestType == 'set') { navigator.geolocation.getCurrentPosition( function(location) { // Save the position in the history log position.savePosition( new Coords( location.coords.latitude, location.coords.longitude, location.coords.accuracy ) ); // Update the saved position to set the address name Map.requestLocation(location); Map.displayMap(location, null); navigator.notification.alert( 'Your position has been saved', function(){}, 'Info' ); }, function(error) { navigator.notification.alert( 'Unable to retrieve your position. Is your GPS enabled?', function(){ alert("Unable to retrieve the position: " + error.message); }, 'Error' ); $.mobile.changePage('index.html'); }, geolocationOptions ); } else { if (position.getPositions().length == 0) { navigator.notification.alert( 'You have not set a position', function(){}, 'Error' ); $.mobile.changePage('index.html'); return false; } else { navigator.geolocation.watchPosition( function(location) { // If positionIndex parameter isn't set, the user wants to retrieve // the last saved position. Otherwise he accessed the map page // from the history page, so he wants to see an old position if (positionIndex == undefined) Map.displayMap(location, position.getPositions()[0]); else Map.displayMap(location, position.getPositions()[positionIndex]); }, function(error) { console.log("Unable to retrieve the position: " + error.message); }, geolocationOptions ); } } } ); 

Инициализируйте страницу истории позиций

Как только пользователю понадобится файл positions.html , jQuery Mobile начнет улучшать компоненты страницы. После того, как фреймворк jQuery выполнил свою работу, нам нужно извлечь предыдущие местоположения пользователя и показать их в виде списка. Итак, я установлю функцию обратного вызова для события pageinit элемента position-page . Обратный вызов просто вызовет createPositionsHistoryList() которая будет проиллюстрирована через несколько минут.

 $('#positions-page').live( 'pageinit', function() { createPositionsHistoryList('positions-list', (new Position()).getPositions()); } ); 

Создать список истории позиций

Как указывалось ранее, createPositionsHistoryList() создает список элемент за элементом, используя сохраненную историю позиций и API веб-хранилища. Каждая запись в списке имеет два действия, которые пользователь может выполнить. Первое действие выполняется, как только пользователь касается текста адреса предыдущего местоположения, который отобразит его на карте так же, как он отображает текущее местоположение автомобиля при нажатии «Найти автомобиль». Это достигается путем отправки того же значения ( get ) в файл карты ( map.html ) для параметра requestType и путем добавления дополнительного значения, называемого index , которое указывает, какой элемент истории местоположений должен быть обработан. Если соединение недоступно и выбрано местоположение, пользователь будет уведомлен о проблеме с подключением, и никакие другие действия не будут выполняться.

Второе действие выполняется касанием значка удаления, который отображается справа от адреса для каждого элемента в списке. Это, конечно, удалит выбранный элемент как из списка, так и из базы данных. Если возникнут проблемы с удалением элемента, пользователь будет предупрежден.

Полный источник createPositionsHistoryList() указан ниже.

 /** * Create the positions' history list */ function createPositionsHistoryList(idElement, positions) { if (positions == null || positions.length == 0) return; $('#' + idElement).empty(); var $listElement, $linkElement, dateTime; for(var i = 0; i < positions.length; i++) { $listElement = $('<li>'); $linkElement = $('<a>'); $linkElement .attr('href', '#') .click( function() { if (checkRequirements() === false) return false; $.mobile.changePage( 'map.html', { data: { requestType: 'get', index: $(this).closest('li').index() } } ); } ); if (positions[i].address == '' || positions[i].address == null) $linkElement.text('Address not found'); else $linkElement.text(positions[i].address); dateTime = new Date(positions[i].datetime); $linkElement.text( $linkElement.text() + ' @ ' + dateTime.toLocaleDateString() + ' ' + dateTime.toLocaleTimeString() ); // Append the link to the <li> element $listElement.append($linkElement); $linkElement = $('<a>'); $linkElement.attr('href', '#') .text('Delete') .click( function() { var position = new Position(); var oldLenght = position.getPositions().length; var $parentUl = $(this).closest('ul'); position.deletePosition($(this).closest('li').index()); if (oldLenght == position.getPositions().length + 1) { $(this).closest('li').remove(); $parentUl.listview('refresh'); } else { navigator.notification.alert( 'Position not deleted. Something gone wrong so please try again.', function(){}, 'Error' ); } } ); // Append the link to the <li> element $listElement.append($linkElement); // Append the <li> element to the <ul> element $('#' + idElement).append($listElement); } $('#' + idElement).listview('refresh'); } 

Запуск приложения

В последнем разделе все части приложения были собраны и все файлы HTML, CSS и JavaScript были размещены на их месте. Итак, теперь вы готовы построить и развернуть «Где я припарковал свою машину». Но вы должны установить функции входа для всего приложения. Как вы уже догадались, функция будет initApplication() и будет работать после полной загрузки Cordova. Таким образом, вы можете безопасно вызывать API Cordova.

Для достижения этой цели мы установили initApplication() в качестве функции обратного вызова для события deviceready . Это можно сделать, добавив следующий код в файл index.html как вы уже указали в его источнике, указанном во второй части серии .

 <script> $(document).one('deviceready', initApplication); </script> 

Вывод

В этой статье я объяснил последние функции файла function.js . В следующей и последней части этой серии вы узнаете, как создать файл конфигурации ( config.xml ), описанный в первой статье для использования с Adobe PhoneGap Build . Файл конфигурации поможет нам указать определенные свойства приложения, такие как автор, экраны загрузки, разрешения и так далее. Как вы можете ожидать, я также опубликую ссылку на репозиторий, где вы можете скачать полный исходный код, чтобы вы могли поиграть с ним. Я также поделюсь некоторыми заключительными мыслями о том, какие функции вы можете добавить для дальнейшего улучшения приложения, и что, я надеюсь, команда Cordova осуществит в следующих выпусках, которые могут вывести наше приложение на новый уровень.