Отслеживаем местоположение устройства в мобильном приложении NativeScript Angular

Отслеживаем местоположение устройства в мобильном приложении NativeScript Angular

Тема работы с GPS при создании мобильных приложений NativeScript часто встречается у начинающих разработчиков. И сегодня мы создадим такое приложение на NativeScript с Angular под Android и iOS.

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

Создаём новый проект

Для начала создадим новый проект NativeScript с Angular, TypeScript и HTML.
Выполните в консоли следующие команды:

tns create GeoProject --ng
cd GeoProject
tns platform add ios
tns platform add android

Ключ —ng нужен для создания проекта именно с Angular. Также помните, что создать проект для iOS можно только на Mac с установленным Xcode.

Теперь установим плагин для геолокации:

tns plugin add nativescript-geolocation
Документация по плагину доступна здесь.

Разработка логики на TypeScript и интерфейса на HTML

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

Откройте файл app/app.component.ts и добавьте туда следующий код:

import { Component, NgZone } from "@angular/core";
import * as Geolocation from "nativescript-geolocation";

@Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent {

public latitude: number;
public longitude: number;
private watchId: number;

public constructor(private zone: NgZone) {
this.latitude = 0;
this.longitude = 0;
}

private getDeviceLocation(): Promise {
return new Promise((resolve, reject) => {
Geolocation.enableLocationRequest().then(() => {
Geolocation.getCurrentLocation({timeout: 10000}).then(location => {
resolve(location);
}).catch(error => {
reject(error);
});
});
});
}

public updateLocation() {
this.getDeviceLocation().then(result => {
this.latitude = result.latitude;
this.longitude = result.longitude;
}, error => {
console.error(error);
});
}

public startWatchingLocation() {
this.watchId = Geolocation.watchLocation(location => {
if(location) {
this.zone.run(() => {
this.latitude = location.latitude;
this.longitude = location.longitude;
});
}
}, error => {
console.dump(error);
}, { updateDistance: 1, minimumUpdateTime: 1000 });
}

public stopWatchingLocation() {
if(this.watchId) {
Geolocation.clearWatch(this.watchId);
this.watchId = null;
}
}

}
Рассмотрим подробнее этот код. В методе constructor класса AppComponent инициализируются переменные и подключается служба NgZone из Angular. Нам она нужна для использования слушателей (listeners) и обновления интерфейса с их помощью.

В документации NativeScript говорится об использовании функции isEnabled компонента Geolocation для определения работоспособности копонентов геолокации устройства. Я не использую эту функцию, потому что она иногда возвращает странный результат. Вместо этого мы воспользуемся этим:

private getDeviceLocation(): Promise {
return new Promise((resolve, reject) => {
Geolocation.enableLocationRequest().then(() => {
Geolocation.getCurrentLocation({timeout: 10000}).then(location => {
resolve(location);
}).catch(error => {
reject(error);
});
});
});
}

Здесь мы вызываем метод enableLocationRequest, который проверит разрешение на доступ к компонентам и если такое разрешение будет получено, нам будет возвращены текущие координаты. Так как это происходит не сразу, мы и используем promise.

Функция getDeviceLocation не привязана к интерфейсу и она частная. А для обновления интерфейса мы будем использовать метод updateLocation.

А что нужно сделать, чтобы отслеживать изменения координат?
Для этого и нужны методы startWatchingLocation и stopWatchingLocation.

public startWatchingLocation() {
this.watchId = Geolocation.watchLocation(location => {
if(location) {
this.zone.run(() => {
this.latitude = location.latitude;
this.longitude = location.longitude;
});
}
}, error => {
console.dump(error);
}, { updateDistance: 1, minimumUpdateTime: 1000 });
}

Здесь создаём слушателя и обновляем интерфейс с Angular. Слушатель возвращает id, который мы будем использовать, когда захотим его остановить.

Свойство updateDistance показываем, что мы хотим обновлять показания координат только при изменениях более, чем на 1 метр, но свойство minimumUpdateTime указывает, что это обновление происходит только раз в секунду. Поиграйтесь с этими значениями, но помните — они влияют на срок работы от батареи!

Перейдём к интерфейсу. Откройте файл app/app.component.html и добавьте туда следующую разметку:











Здесь у нас есть верхняя панель и три кнопки для управления геолокацией, которые привязаны к логике в TypeScript коде.

В этом простом примере мы рассмотрели только первые шаги по работе с геолокацией в NativeScript. Надеюсь, он вам поможет в работе.

По материалам «Track The Device Geolocation In A NativeScript Angular Mobile Application» by Nic Raboy

Leave a Comment