Блогът на Гонзо

Анатомия на едно мобилно уеб приложение, част първа: къде съм аз?

От доста време търсех задачка, върху която да опитам да приложа различни NEWT. И както изисква добрата практика, намерих поле за изява в решаването на собствените си нужди. Работата е там, че от както ползвам Foursquare пробвах две различни приложения за Symbian, но и двете имаха един и същ недостатък – не работят без GPS приемникът на телефона да работи. Проблемът е, че GPS приемникът на моя телефон изпитва големи трудности при намирането на сателитите, ако няма връзка с Интернет, а пък аз все още се дърпам от абонаментите, включващи канал за данни. И така, в моя случай или има GPS (когато съм отвън), или има Интернет (когато мястото, където се намирам, предлага WiFi). И така, решението на проблема е

GeoLocation API

Въпреки че не е част от спецификацията на HTML5, GeoLocation API често се споменава заедно с него и е естествена част от NEWT. Позволява ни чрез съвсем малко JavaScript да определим местоположението на потребителя. Отворих една страничка, демонстрираща възможностите на GeoLocation и бях изумен от точността – точката върху картата беше на 100 – 200 метра от вкъщи. Напълно достатъчно за нуждите ми.

Да видим как става номера:

if (navigator.geolocation) {
	navigator.geolocation.getCurrentPosition( 
		function (position) {
                    // имаме местоположението на потребителя: position.coord.lat и position.coords.lon
		}, 
		function (error) {
                    // грешка при определянето на местоположението
		}
	);
}
else {
    // браузъра не поддържа GeoLocation API
}

Можете да разчитате, че успешно ще установите мястото на потребителя, стига той да ползва достатъчно нова версия на Firefox, Safari, Chrome или Opera. Но за мен е интересно дали ще работи на мобилния ми телефон. Моят парашут се отвори, когато инсталирах Opera Mobile 10.1, а собствениците на iPhone или телефон с Android могат да бъдат локализирани и без нужда от инсталиране на допълнителен софтуер. Единствената особеност е, че някои устройства с Android 2.1 изискват да е включен GPS приемника, въпреки, че не разчитат на него (пробвах с Globul Q1 SE).

Как работи GeoLocation?

Добре де, а как браузъра определя местоположението без GPS, ще попитате вие? Браузърите използват няколко метода, чрез които определят местоположението в зависимост от наличните GPS и мрежови устройства.

Когато има наличен GPS, браузърите на мобилни телефони могат да използват данните от него, за да установят с голяма точност местоположението на потребителя. Този подход работи на телефони с Android OS и на iPhone, но WebKit браузърат на моята Nokia 5800 не поддържа въобще GeoLocation API, въпреки, че телефона има GPS.

Когато няма GPS, или той не може да установи местоположението, браузъра използва други методи. Първата възможност е чрез информация от GSM мрежата – клетките са с известно местоположение и чрез изчисление на базата на силата на сигнала от различните клетки местоположението може да се установи с достатъчно голяма точност. Това е всъщност една от функциите на A-GPS устройствата, вграждани в мобилните телефони. Другата е изтеглянето на алманаха с местоположението на сателитите през Интернет, което ускорява установяването на местоположението.

Когато и този метод не е наличен, има още един начин местоположението да се установи със задоволителна точност. Има различни фирми, които обикалят по улиците с автомобили и събират информация за силата на сигнала на различните WiFi мрежи. След това може лесно по обратния път да се установи къде се намира дадено устройство по списъка с видими мрежи и тяхната сила. Това е и основния метод, който използват Opera и Firefox, като и двата браузъра правят заявка до услуга на Google за това. За Opera това се разбира лесно – първото нещо, което браузъра ви пита, преди да върне резултат за местоположението, е дали сте съгласни с общите условия на Google за тази услуга. За Firefox го разбрах, докато следях заявките от браузъра чрез разширението TemperData.

И последният възможен метод за установяване на местоположението е чрез GeoIP. Това е най-неточния метод – в най-добрия случай местоположението ще е с точност до град или квартал (дали?), което са от няколко километра до десетки километри. А в най-лошия случай GeoIP базата данни може да позиционира потребителя в съвсем друга държава или континент.

По-подробно за методите на API-то

Но да се върнем към JavaScript и GeoLocation API. В горния пример показах как в общи линии се използва методът getCurrentPosition. Този метод връща текущата позиция на браузъра, като приема три аргумента. Първият е callback функция, която да се изпълни при успешно установяване на местоположението, и която приема като параметър обект, описващ местоположението. Вторият параметър е callback функция, която да се изпълни в случай на грешка и приемаща като параметър обект, който я описва. Третият параметър, който съм пропуснал в примера, е обект, чрез който се подават различни настройки към метода. Втория и третия аргументи могат да бъдат пропуснати.

if (navigator.geolocation) {
    var options = {
        enableHighAccuracy = true, // Ако е истина, изисква възможно най-точни резултати
        timeout = 5000, // Колко време да чакате да получите позицията, в милисекунди
        maximumAge = 10000 // Колко стара позиция сте склонни да приемете
    }
    navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
}
else {
    // браузъра не поддържа GeoLocation API
}

function successCallback(position){
    alert(position.coords.latitude + ', ' + position.coords.longitude);
}

function errorCallback(){
    switch (error.code) {
    case error.TIMEOUT:
        alert ('Timeout');
        break;
    case error.POSITION_UNAVAILABLE:
        alert ('Position unavailable');
        break;
    case error.PERMISSION_DENIED:
        alert ('Permission denied');
        break;
    case error.UNKNOWN_ERROR:
        alert ('Unknown error');
        break;
    default:
        alert(error.message);
    }
}

Обектът, описващ позицията на устройството има следния вид:


{
    timestamp: [DOMTimeStamp], 
    coords: {
        latitude: [double],
        longitude: [double],
        altitude: [double],
        accuracy: [double],
        altitudeAccuracy: [double],
        heading: [double],
        speed: [double]
    }
}

Ако браузърът няма възможност да установи височината, посоката или скоростта, стойността на съответното свойство трябва да е null.

Освен, че позволява да установим текущата позиция на браузъра, GeoLocation API има метод, чрез който да следим за промени на местоположението. Методът е watchPosition и се използва по същия начин както и getCurrentPosition. Разликата е, че callback функциите ще се изпълняват всеки път, когато устройството прецени, че има промяна в местоположението, и връща като резултат число подобно на setTimeout и setInterval. Следенето на позицията може да бъде прекъснато чрез метода clearWatch:

if (navigator.geolocation) {
    var watch = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
    setTimeout(function(){
        navigator.geolocation.clearWatch(watch);
    },600000);
}
else {
    // браузъра не поддържа GeoLocation API
}

Заключение

Някои от вас може би се чудят за какво му е на сайта да знае къде се намира потребителя, други вече си представят как ще следят жената или разтресения от пубертета син, а Бого ще е загрижен за личната неприкосновеност на потребителите (и с право!).

Да започнем от личната неприкосновеност – според спецификацията на W3C браузъра не трябва да издава местоположението си без изричното съгласие на потребителя. Тествах поведението на Firefox, Opera и Chrome на десктоп (Linux и Windows) и на браузърите на iPhone, няколко Android устройства, и на Opera Mobile на Symbian, и всички те спазват това изискване. Нещо повече, на iPhone трябваше да разреша някаква опция, забита из настройките на телефона, за да сработи приложението ми.

GeoLocation API ни позволява да навлезем в територия, запазена до скоро само за традиционните приложения. Вече имам идеи за няколко такива, повтарящи функционалността на приложения за Android или iPhone, но работещи на всякакви устройства без нужда от пренаписване. Освен това вече можем да предложим съдържанието по различен начин, знаейки, че потребителят се движи и вниманието му не е изцяло заето със сайта. Можем да предложим по-адекватни резултати от търсенето на “магазин за сърф”, знаейки, че той е в Бургас, а не във Варна. Следващата граница е вашето въображение.

Етикети: , , , ,

Comments (8)

Радослав Станков профил

Това API е лично доста подценявано от мен. Неможе да се отрече ползата му, и че начина му на ползване е доста добър. Но явно за сега не съм намерил къде да го ползвам. Но се надявам и на това да му дойде времето.

Гонзо профил

Всъщност не ги спряха, а ги замразиха до второ нареждане. Все още има надежда да оправят спецификацията и да ги пуснат.

Между другото намерих интересна публикация за Location API-то на Blackberry – изглежда техните телефони имат собствено JavaScript API за достъп до вградения GPS.

Гонзо профил

Още нещо интересно: Оказва се, че чрез XSS атака, насочена към безжичния рутер и Google Location Service (същата услуга, която ползват Firefox и Opera) може да бъде установено местоположението на рутера. Повече информация тук: http://samy.pl/mapxss/

Вашият коментар

XHTML: Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>