mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00
BCL: updated location to support distance measuring
This commit is contained in:
@ -1,6 +1,8 @@
|
|||||||
Initializing location:
|
Initializing location:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
var LocationManager = require("Location").LocationManager;
|
||||||
|
|
||||||
console.log('is location enabled: ' + LocationManager.isLocationEnabled());
|
console.log('is location enabled: ' + LocationManager.isLocationEnabled());
|
||||||
|
|
||||||
this.locationManager = new LocationManager();
|
this.locationManager = new LocationManager();
|
||||||
|
@ -17,6 +17,42 @@ export class LocationManager {
|
|||||||
|
|
||||||
private _locationListener: any;
|
private _locationListener: any;
|
||||||
|
|
||||||
|
private static locationFromAndroidLocation(androidLocation: android.location.Location): types.Location {
|
||||||
|
var location = new types.Location();
|
||||||
|
location.latitude = androidLocation.getLatitude();
|
||||||
|
location.longitude = androidLocation.getLongitude();
|
||||||
|
location.altitude = androidLocation.getAltitude();
|
||||||
|
location.horizontalAccuracy = androidLocation.getAccuracy();
|
||||||
|
location.verticalAccuracy = androidLocation.getAccuracy();
|
||||||
|
location.speed = androidLocation.getSpeed();
|
||||||
|
location.direction = androidLocation.getBearing();
|
||||||
|
location.timestamp = new Date(androidLocation.getTime());
|
||||||
|
location.androidNative = androidLocation;
|
||||||
|
//console.dump(location);
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static androidLocationFromLocation(location: types.Location): android.location.Location {
|
||||||
|
var androidLocation = new android.location.Location('custom');
|
||||||
|
androidLocation.setLatitude(location.latitude);
|
||||||
|
androidLocation.setLongitude(location.longitude);
|
||||||
|
if (location.altitude)
|
||||||
|
androidLocation.setAltitude(location.altitude);
|
||||||
|
if (location.speed)
|
||||||
|
androidLocation.setSpeed(float(location.speed));
|
||||||
|
if (location.direction)
|
||||||
|
androidLocation.setBearing(float(location.direction));
|
||||||
|
if (location.timestamp) {
|
||||||
|
try {
|
||||||
|
androidLocation.setTime(long(location.timestamp.getTime()));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error('invalid location timestamp');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return androidLocation;
|
||||||
|
}
|
||||||
|
|
||||||
public static isLocationEnabled(): boolean {
|
public static isLocationEnabled(): boolean {
|
||||||
var criteria = new android.location.Criteria();
|
var criteria = new android.location.Criteria();
|
||||||
criteria.setAccuracy(1); // low ? fine ? who knows what 1 means (bug in android docs?)
|
criteria.setAccuracy(1); // low ? fine ? who knows what 1 means (bug in android docs?)
|
||||||
@ -24,6 +60,16 @@ export class LocationManager {
|
|||||||
return (lm.getBestProvider(criteria, true) != null) ? true : false;
|
return (lm.getBestProvider(criteria, true) != null) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static distanceInMeters(loc1: types.Location, loc2: types.Location): number {
|
||||||
|
if (!loc1.androidNative) {
|
||||||
|
loc1.androidNative = LocationManager.androidLocationFromLocation(loc1);
|
||||||
|
}
|
||||||
|
if (!loc2.androidNative) {
|
||||||
|
loc2.androidNative = LocationManager.androidLocationFromLocation(loc2);
|
||||||
|
}
|
||||||
|
return loc1.androidNative.distanceTo(loc2.androidNative);
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// put some defaults
|
// put some defaults
|
||||||
this.desiredAccuracy = types.DesiredAccuracy.HIGH;
|
this.desiredAccuracy = types.DesiredAccuracy.HIGH;
|
||||||
@ -34,37 +80,14 @@ export class LocationManager {
|
|||||||
this.androidLocationManager = app_module.Application.current.android.context.getSystemService('location');
|
this.androidLocationManager = app_module.Application.current.android.context.getSystemService('location');
|
||||||
}
|
}
|
||||||
|
|
||||||
private static locationFromAndroidLocation(androidLocation: android.location.Location): types.Location {
|
////////////////////////
|
||||||
var location = new types.Location();
|
|
||||||
location.latitude = androidLocation.getLatitude();
|
|
||||||
location.longitude = androidLocation.getLongitude();
|
|
||||||
location.altitude = androidLocation.getAltitude();
|
|
||||||
location.horizontalAccuracy = androidLocation.getAccuracy();
|
|
||||||
location.verticalAccuracy = androidLocation.getAccuracy();
|
|
||||||
location.speed = androidLocation.getSpeed();
|
|
||||||
location.direction = androidLocation.getBearing();
|
|
||||||
location.timestamp = new Date(androidLocation.getTime());
|
|
||||||
//console.dump(location);
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitoring
|
// monitoring
|
||||||
|
////////////////////////
|
||||||
|
|
||||||
public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: string) => any) {
|
public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: Error) => any) {
|
||||||
if (!this.isStarted) {
|
if (!this.isStarted) {
|
||||||
var criteria = new android.location.Criteria();
|
var criteria = new android.location.Criteria();
|
||||||
criteria.setAccuracy((this.desiredAccuracy === types.DesiredAccuracy.HIGH) ? 1 : 2);
|
criteria.setAccuracy((this.desiredAccuracy === types.DesiredAccuracy.HIGH) ? 1 : 2);
|
||||||
/* // We could provide 'true' for the second parameter here and get only enabled providers.
|
|
||||||
// However this would exclude the case when user enables the provider later.
|
|
||||||
// Another option is to get the best provider, but then again, this would
|
|
||||||
// exclude all other providers matching our criteria
|
|
||||||
var providers = this.androidLocationManager.getProviders(criteria, false);
|
|
||||||
var it = providers.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
var element = it.next();
|
|
||||||
console.log('found provider: ' + element);
|
|
||||||
this.androidLocationManager.requestLocationUpdates(element, 200, 10, this._locationListener);
|
|
||||||
}*/
|
|
||||||
this._locationListener = <any>new android.location.LocationListener({
|
this._locationListener = <any>new android.location.LocationListener({
|
||||||
onLocationChanged: function (location: android.location.Location) {
|
onLocationChanged: function (location: android.location.Location) {
|
||||||
if (this._onLocation) {
|
if (this._onLocation) {
|
||||||
@ -89,12 +112,12 @@ export class LocationManager {
|
|||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (onError) {
|
if (onError) {
|
||||||
onError(e.message);
|
onError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (onError) {
|
else if (onError) {
|
||||||
onError('location monitoring already started');
|
onError(new Error('location monitoring already started'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -106,7 +129,9 @@ export class LocationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
// other
|
// other
|
||||||
|
////////////////////////
|
||||||
|
|
||||||
public getLastKnownLocation(): types.Location {
|
public getLastKnownLocation(): types.Location {
|
||||||
var criteria = new android.location.Criteria();
|
var criteria = new android.location.Criteria();
|
||||||
@ -130,7 +155,4 @@ export class LocationManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public distanceInMeters(loc1: types.Location, loc2: types.Location): number {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
39
Location/location.d.ts
vendored
39
Location/location.d.ts
vendored
@ -4,22 +4,6 @@
|
|||||||
HIGH,
|
HIGH,
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare class LocationPoint {
|
|
||||||
public latitude: number;
|
|
||||||
public longitude: number;
|
|
||||||
|
|
||||||
public altitude: number;
|
|
||||||
|
|
||||||
public horizontalAccuracy: number;
|
|
||||||
public verticalAccuracy: number;
|
|
||||||
|
|
||||||
public speed: number; // in m/s ?
|
|
||||||
|
|
||||||
public direction: number; // in degrees
|
|
||||||
|
|
||||||
public timestamp: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare class LocationRegion {
|
export declare class LocationRegion {
|
||||||
public latitude: number;
|
public latitude: number;
|
||||||
public longitude: number;
|
public longitude: number;
|
||||||
@ -41,11 +25,9 @@ export declare class Location {
|
|||||||
direction: number; // in degrees
|
direction: number; // in degrees
|
||||||
|
|
||||||
timestamp: Date;
|
timestamp: Date;
|
||||||
}
|
|
||||||
|
|
||||||
export declare class LocationChangeListener {
|
public androidNative: any; // android Location
|
||||||
onLocationChange(location: Location);
|
public iosNative: any; // iOS native location
|
||||||
onLocationError(error: string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare class RegionChangeListener {
|
export declare class RegionChangeListener {
|
||||||
@ -55,29 +37,18 @@ export declare class RegionChangeListener {
|
|||||||
|
|
||||||
export declare class LocationManager {
|
export declare class LocationManager {
|
||||||
static isLocationEnabled(): boolean;
|
static isLocationEnabled(): boolean;
|
||||||
|
static distanceInMeters(loc1: Location, loc2: Location): number;
|
||||||
|
|
||||||
desiredAccuracy: number;
|
desiredAccuracy: number;
|
||||||
updateDistance: number;
|
updateDistance: number;
|
||||||
// minimum time interval between location updates, in milliseconds (android only)
|
// minimum time interval between location updates, in milliseconds (android only)
|
||||||
minimumUpdateTime: number;
|
minimumUpdateTime: number;
|
||||||
isStarted: boolean;
|
isStarted: boolean;
|
||||||
|
|
||||||
// listeners
|
|
||||||
locationChangeListener: LocationChangeListener;
|
|
||||||
/* regionChangeListener: RegionChangeListener;
|
|
||||||
|
|
||||||
// regions
|
|
||||||
addRegion(region: LocationRegion);
|
|
||||||
|
|
||||||
removeRegion(region: LocationRegion);
|
|
||||||
|
|
||||||
clearRegions();*/
|
|
||||||
|
|
||||||
// monitoring
|
// monitoring
|
||||||
|
startLocationMonitoring(onLocation: (location: Location) => any, onError?: (error: Error) => any);
|
||||||
startLocationMonitoring(onLocation: (location: Location) => any, onError?: (error: string) => any);
|
|
||||||
stopLocationMonitoring();
|
stopLocationMonitoring();
|
||||||
|
|
||||||
// other
|
// other
|
||||||
getLastKnownLocation(): Location;
|
getLastKnownLocation(): Location;
|
||||||
distanceInMeters(loc1: Location, loc2: Location): number;
|
|
||||||
}
|
}
|
@ -12,17 +12,6 @@ export class LocationManager {
|
|||||||
public isStarted: boolean;
|
public isStarted: boolean;
|
||||||
private iosLocationManager: CoreLocation.CLLocationManager;
|
private iosLocationManager: CoreLocation.CLLocationManager;
|
||||||
|
|
||||||
public static isLocationEnabled(): boolean {
|
|
||||||
return CoreLocation.CLLocationManager.locationServicesEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.isStarted = false;
|
|
||||||
this.desiredAccuracy = types.DesiredAccuracy.HIGH;
|
|
||||||
this.updateDistance = -1; // kCLDistanceFilterNone
|
|
||||||
this.iosLocationManager = new CoreLocation.CLLocationManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static locationFromCLLocation(clLocation: CoreLocation.CLLocation): types.Location {
|
private static locationFromCLLocation(clLocation: CoreLocation.CLLocation): types.Location {
|
||||||
var location = new types.Location();
|
var location = new types.Location();
|
||||||
location.latitude = clLocation.coordinate.latitude;
|
location.latitude = clLocation.coordinate.latitude;
|
||||||
@ -33,12 +22,45 @@ export class LocationManager {
|
|||||||
location.speed = clLocation.speed;
|
location.speed = clLocation.speed;
|
||||||
location.direction = clLocation.course;
|
location.direction = clLocation.course;
|
||||||
location.timestamp = new Date(clLocation.timestamp.timeIntervalSince1970() * 1000);
|
location.timestamp = new Date(clLocation.timestamp.timeIntervalSince1970() * 1000);
|
||||||
|
location.iosNative = clLocation;
|
||||||
//console.dump(location);
|
//console.dump(location);
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static iosLocationFromLocation(location: types.Location): CoreLocation.CLLocation {
|
||||||
|
var hAccuracy = location.horizontalAccuracy ? location.horizontalAccuracy : -1;
|
||||||
|
var vAccuracy = location.verticalAccuracy ? location.verticalAccuracy : -1;
|
||||||
|
var speed = location.speed ? location.speed : -1;
|
||||||
|
var course = location.direction ? location.direction : -1;
|
||||||
|
var altitude = location.altitude ? location.altitude : -1;
|
||||||
|
var timestamp = location.timestamp ? Foundation.NSDate.dateWithTimeIntervalSince1970(location.timestamp.getTime()) : null;
|
||||||
|
var iosLocation = CoreLocation.CLLocation.initWithCoordinateAltitudeHorizontalAccuracyVerticalAccuracyCourseSpeedTimestamp(CoreLocation.CLLocationCoordinate2DMake(location.latitude, location.longitude), altitude, hAccuracy, vAccuracy, course, speed, timestamp);
|
||||||
|
return iosLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static isLocationEnabled(): boolean {
|
||||||
|
return CoreLocation.CLLocationManager.locationServicesEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static distanceInMeters(loc1: types.Location, loc2: types.Location): number {
|
||||||
|
if (!loc1.iosNative) {
|
||||||
|
loc1.iosNative = LocationManager.iosLocationFromLocation(loc1);
|
||||||
|
}
|
||||||
|
if (!loc2.iosNative) {
|
||||||
|
loc2.iosNative = LocationManager.iosLocationFromLocation(loc2);
|
||||||
|
}
|
||||||
|
return loc1.iosNative.distanceFromLocation(loc2.iosNative);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.isStarted = false;
|
||||||
|
this.desiredAccuracy = types.DesiredAccuracy.HIGH;
|
||||||
|
this.updateDistance = -1; // kCLDistanceFilterNone
|
||||||
|
this.iosLocationManager = new CoreLocation.CLLocationManager();
|
||||||
|
}
|
||||||
|
|
||||||
// monitoring
|
// monitoring
|
||||||
public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: string) => any) {
|
public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: Error) => any) {
|
||||||
if (!this.isStarted) {
|
if (!this.isStarted) {
|
||||||
var LocationListener = Foundation.NSObject.extends({
|
var LocationListener = Foundation.NSObject.extends({
|
||||||
setupWithFunctions: function (onLocation, onError) {
|
setupWithFunctions: function (onLocation, onError) {
|
||||||
@ -59,9 +81,9 @@ export class LocationManager {
|
|||||||
},
|
},
|
||||||
|
|
||||||
locationManagerDidFailWithError: function (manager, error) {
|
locationManagerDidFailWithError: function (manager, error) {
|
||||||
console.log('location error received ' + error.localizedDescription());
|
console.error('location error received ' + error.localizedDescription());
|
||||||
if (this.onError) {
|
if (this.onError) {
|
||||||
this.onError(error.localizedDescription());
|
this.onError(new Error(error.localizedDescription()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +97,7 @@ export class LocationManager {
|
|||||||
this.iosLocationManager.startUpdatingLocation();
|
this.iosLocationManager.startUpdatingLocation();
|
||||||
}
|
}
|
||||||
else if (onError) {
|
else if (onError) {
|
||||||
onError('location monitoring already started');
|
onError(new Error('location monitoring already started'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,9 +117,4 @@ export class LocationManager {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public distanceInMeters(loc1: types.Location, loc2: types.Location): number {
|
|
||||||
// TODO
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export class Location {
|
|||||||
public direction: number; // in degrees
|
public direction: number; // in degrees
|
||||||
|
|
||||||
public timestamp: Date;
|
public timestamp: Date;
|
||||||
|
|
||||||
|
public androidNative: any; // android Location
|
||||||
|
public iosNative: any; // iOS native location
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LocationRegion {
|
export class LocationRegion {
|
||||||
|
4
declarations.ios.d.ts
vendored
4
declarations.ios.d.ts
vendored
@ -90,6 +90,7 @@ declare module Foundation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class NSDate {
|
export class NSDate {
|
||||||
|
static dateWithTimeIntervalSince1970(datetime: number);
|
||||||
timeIntervalSince1970(): number;
|
timeIntervalSince1970(): number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +115,7 @@ declare module CoreLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CLLocation {
|
export class CLLocation {
|
||||||
|
static initWithCoordinateAltitudeHorizontalAccuracyVerticalAccuracyCourseSpeedTimestamp(coordinate: any, altitude: number, horizontalAccuracy: number, verticalAccuracy: number, course: number, speed: number, timestamp: Foundation.NSDate);
|
||||||
coordinate: any;
|
coordinate: any;
|
||||||
altitude: number;
|
altitude: number;
|
||||||
horizontalAccuracy: number;
|
horizontalAccuracy: number;
|
||||||
@ -122,4 +124,6 @@ declare module CoreLocation {
|
|||||||
speed: number;
|
speed: number;
|
||||||
course: number;
|
course: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CLLocationCoordinate2DMake(latitude: number, longitude: number) : any;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ export class http {
|
|||||||
// TODO: Accept: application/json header for JSON calls and check the response for Image not url!
|
// TODO: Accept: application/json header for JSON calls and check the response for Image not url!
|
||||||
private static get(url: string, successCallback: (result: any) => void, errorCallback?: (e: Error) => void) {
|
private static get(url: string, successCallback: (result: any) => void, errorCallback?: (e: Error) => void) {
|
||||||
try {
|
try {
|
||||||
var isImage = url.match(/\.(jpeg|jpg|gif|png)$/) != null;
|
var isImage = url.match(/\.(jpeg|jpg|gif|png)$/i) != null;
|
||||||
|
|
||||||
var context = app_module.Application.current.android.context;
|
var context = app_module.Application.current.android.context;
|
||||||
var request = com.koushikdutta.ion.Ion.with(context, url);
|
var request = com.koushikdutta.ion.Ion.with(context, url);
|
||||||
|
Reference in New Issue
Block a user