Ranije sam već objavio jedan blog post na temu prikaza Google karte međutim ondje kao početnu lokaciju koristim zadane koordinate Vinkovaca.
1 2 3 4 5 6 7 |
loadMap(){ let latLng = new google.maps.LatLng('45.287906','18.805678'); let mapOptions = { center:latLng, zoom:11, mapTypeId: google.maps.MapTypeId.ROADMAP } |
I to je u redu opcija ako će korisnici aplikacije biti iz Vinkovaca, ali ako se korisnik nalazi u bilo kojem drugom mjestu neće baš imati koristi od aplikacije koja mu kao zadanu lokaciju prikazuje mjesto gdje on nije.
Zato moram pronaći način kako dinamički dohvatiti lokaciju korisnika u trenutku kada on pokreće mobilnu aplikaciju ili u trenutku kada on unutar mobilne aplikacije ode na dio koji mu prikazuje Google kartu.
Kako dohvatiti lokaciju korisnika?
U ovom slučaju mogu koristiti Ionic Native Geolocation plugin koji će mi omogućiti dohvaćanje lokacije korisnika (koordinate).
This plugin provides information about the device’s location, such as latitude and longitude. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs.
Plugin instaliram sljedećim naredbama:
1 2 |
$ ionic cordova plugin add cordova-plugin-geolocation --variable GEOLOCATION_USAGE_DESCRIPTION="To locate you" $ npm install --save @ionic-native/geolocation |
Odmah nakon instalacije plugin deklariram unutar app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import { BrowserModule } from '@angular/platform-browser'; import { ErrorHandler, NgModule } from '@angular/core'; import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; import { SplashScreen } from '@ionic-native/splash-screen'; import { StatusBar } from '@ionic-native/status-bar'; import { MyApp } from './app.component'; import { HomePage } from '../pages/home/home'; import { Geolocation } from '@ionic-native/geolocation'; @NgModule({ declarations: [ MyApp, HomePage ], imports: [ BrowserModule, IonicModule.forRoot(MyApp) ], bootstrap: [IonicApp], entryComponents: [ MyApp, HomePage ], providers: [ StatusBar, SplashScreen, Geolocation, {provide: ErrorHandler, useClass: IonicErrorHandler} ] }) export class AppModule {} |
Sada sam spreman za praktičan prikaz dohvaćanja lokacije korisnika. To radim pozivanjem funkcije mojaLokacija().
Korisnik mora odobriti Ionic aplikaciji dohvaćanje lokacije.
U ovom slučaju tek nakon što sam dobio koordinate korisnika pozivam funkciju this.loadMap(resp.coords.latitude, resp.coords.longitude); koja će prikazati Google kartu na ekranu, a korisnikova lokacija biti će na sredini ekrana.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mojaLokacija(){ let options = { enableHighAccuracy: true }; this._geolocation.getCurrentPosition(options).then((resp) => { console.log(resp); if(resp.coords.latitude && resp.coords.longitude){ this.loadMap(resp.coords.latitude, resp.coords.longitude); } }).catch((error) => { console.log('Error getting location', error); }); } |
Međutim, ovdje postoji jedan problem. Da bi ovo iznad bilo moguće na mobilnom uređaju u postavkama mora biti omogućeno dohvaćanje lokacije.
Komponenta na kraju sa svim funkcionalnostima izgleda ovako:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import { Component, ViewChild, ElementRef } from '@angular/core'; import { NavController } from 'ionic-angular'; import { Geolocation } from '@ionic-native/geolocation'; declare var google; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { @ViewChild('map') mapElmt: ElementRef; map: any; constructor(public _navCtrl: NavController, private _geolocation: Geolocation) { } ionViewDidEnter(){ this.mojaLokacija(); } mojaLokacija(){ let options = { enableHighAccuracy: true }; this._geolocation.getCurrentPosition(options).then((resp) => { console.log(resp); if(resp.coords.latitude && resp.coords.longitude){ this.loadMap(resp.coords.latitude, resp.coords.longitude); } }).catch((error) => { console.log('Error getting location', error); }); } loadMap(latitude, longitude){ let latLng = new google.maps.LatLng(latitude,longitude); let mapOptions = { center:latLng, zoom:13, mapTypeId: google.maps.MapTypeId.ROADMAP } this.map = new google.maps.Map(this.mapElmt.nativeElement, mapOptions); } } |
Ako to nije uključeno unutar Ionic aplikacije neće se prikazati ništa tj. ekran će biti prazan jer se funkcija za prikaz Google karte neće niti učitati jer nema koordinara. U slučaju da su varijable s koordinatama prazne prikazat će se zadana lokacija negdje u Africi na moru.
Naravno da ovo ne želim dopustiti i da korisnik Ionic aplikacije treba biti obaviješten o čemu se radi tj. ako želi koristiti određenu funkcionalnost mobilne aplikacije treba dati lokaciju uređaja. Korisnik čak ne mora niti znati da mu su mu postavke lokacije isključene i zato moram pronaći način kako da to saznam i omogućim mu da to uključi.
Android – upravljanje postavkama lokacije
Pomoću plugina Ionic Native Diagnostic mogu saznati je li dohvaćanje lokacije omogućeno na tom konkretnom Android uređaju. U slučaju kada nije imam mogućnost obavijestiti korisnika i omogućiti mu da uključi lociranje.
Checks whether device hardware features are enabled or available to the app, e.g. camera, GPS, wifi
Plugin instaliram sljedećim naredbama:
1 2 |
$ ionic cordova plugin add cordova.plugins.diagnostic $ npm install --save @ionic-native/diagnostic |
Odmah nakon instalacije plugin deklariram unutar app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import { BrowserModule } from '@angular/platform-browser'; import { ErrorHandler, NgModule } from '@angular/core'; import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; import { SplashScreen } from '@ionic-native/splash-screen'; import { StatusBar } from '@ionic-native/status-bar'; import { MyApp } from './app.component'; import { HomePage } from '../pages/home/home'; import { Geolocation } from '@ionic-native/geolocation'; import { Diagnostic } from '@ionic-native/diagnostic'; @NgModule({ declarations: [ MyApp, HomePage ], imports: [ BrowserModule, IonicModule.forRoot(MyApp) ], bootstrap: [IonicApp], entryComponents: [ MyApp, HomePage ], providers: [ StatusBar, SplashScreen, Geolocation, Diagnostic, {provide: ErrorHandler, useClass: IonicErrorHandler} ] }) export class AppModule {} |
Sada mogu testirati ovu opciju.
Ako sada pokrenem aplikaciju dobijem sljedeće
Klikom na “UKLJUČI” otvaraju se postavke u kojima je moguće uključiti geolociranje.
Sva se funkcionalnost nalazi unutar funkcije provjeraLokacije().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
provjeraLokacije(){ this._diagnostic.isLocationEnabled() .then((state) => { console.log(state); if (state == true){ this.mojaLokacija(); } else { let alert = this._alertCtrl.create({ title: 'Želite li uključiti geolociranje?', message: 'Geolociranje koristimo kako bismo Vam omogućili prikaz objekata u Vašoj blizini.', buttons: [ { text: 'Odustani', role: 'cancel', handler: () => { // } }, { text: 'Uključi', handler: () => { this._diagnostic.switchToLocationSettings(); } } ] }); alert.present(); } }).catch(e => console.error(e)); } |
Komponenta na kraju sa svim funkcionalnostima izgleda ovako:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
import { Component, ViewChild, ElementRef } from '@angular/core'; import { NavController, AlertController } from 'ionic-angular'; import { Geolocation } from '@ionic-native/geolocation'; import { Diagnostic } from '@ionic-native/diagnostic'; declare var google; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { @ViewChild('map') mapElmt: ElementRef; map: any; constructor(public _navCtrl: NavController, private _geolocation: Geolocation, private _diagnostic: Diagnostic, public _alertCtrl: AlertController) { } ionViewDidEnter(){ this.provjeraLokacije(); } mojaLokacija(){ let options = { enableHighAccuracy: true }; this._geolocation.getCurrentPosition(options).then((resp) => { console.log(resp); if(resp.coords.latitude && resp.coords.longitude){ this.loadMap(resp.coords.latitude, resp.coords.longitude); } }).catch((error) => { console.log('Error getting location', error); }); } provjeraLokacije(){ this._diagnostic.isLocationEnabled() .then((state) => { console.log(state); if (state == true){ this.mojaLokacija(); } else { let alert = this._alertCtrl.create({ title: 'Želite li uključiti geolociranje?', message: 'Geolociranje koristimo kako bismo Vam omogućili prikaz objekata u Vašoj blizini.', buttons: [ { text: 'Odustani', role: 'cancel', handler: () => { // } }, { text: 'Uključi', handler: () => { this._diagnostic.switchToLocationSettings(); } } ] }); alert.present(); } }).catch(e => console.error(e)); } loadMap(latitude, longitude){ let latLng = new google.maps.LatLng(latitude,longitude); let mapOptions = { center:latLng, zoom:13, mapTypeId: google.maps.MapTypeId.ROADMAP } this.map = new google.maps.Map(this.mapElmt.nativeElement, mapOptions); } } |
Zaključak
Struktura projekta prema package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
{ "name": "IonicGeolocation", "version": "0.0.1", "author": "Tomislav Stanković", "homepage": "https://www.tomislavstankovic.com/", "private": true, "scripts": { "start": "ionic-app-scripts serve", "clean": "ionic-app-scripts clean", "build": "ionic-app-scripts build", "lint": "ionic-app-scripts lint" }, "dependencies": { "@angular/animations": "5.2.11", "@angular/common": "5.2.11", "@angular/compiler": "5.2.11", "@angular/compiler-cli": "5.2.11", "@angular/core": "5.2.11", "@angular/forms": "5.2.11", "@angular/http": "5.2.11", "@angular/platform-browser": "5.2.11", "@angular/platform-browser-dynamic": "5.2.11", "@ionic-native/core": "~4.17.0", "@ionic-native/diagnostic": "^4.18.0", "@ionic-native/geolocation": "^4.18.0", "@ionic-native/splash-screen": "~4.17.0", "@ionic-native/status-bar": "~4.17.0", "@ionic/storage": "2.2.0", "cordova-android": "7.0.0", "cordova-plugin-device": "^2.0.2", "cordova-plugin-geolocation": "^4.0.1", "cordova-plugin-ionic-keyboard": "^2.1.3", "cordova-plugin-ionic-webview": "^2.2.5", "cordova-plugin-splashscreen": "^5.0.2", "cordova-plugin-statusbar": "^2.4.2", "cordova-plugin-whitelist": "^1.3.3", "cordova.plugins.diagnostic": "^4.0.10", "ionic-angular": "3.9.2", "ionicons": "3.0.0", "rxjs": "5.5.11", "sw-toolbox": "3.6.0", "zone.js": "0.8.26" }, "devDependencies": { "@ionic/app-scripts": "3.2.1", "typescript": "~2.6.2" }, "description": "An Ionic Geolocation project", "cordova": { "plugins": { "cordova-plugin-whitelist": {}, "cordova-plugin-statusbar": {}, "cordova-plugin-device": {}, "cordova-plugin-splashscreen": {}, "cordova-plugin-ionic-webview": { "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+" }, "cordova-plugin-ionic-keyboard": {}, "cordova-plugin-geolocation": { "GEOLOCATION_USAGE_DESCRIPTION": "To locate you" }, "cordova.plugins.diagnostic": {} }, "platforms": [ "android" ] } } |