BCL: updated location and image APIs

This commit is contained in:
Stanimir Karoserov
2014-04-16 18:46:07 +03:00
parent 7fd0d2e251
commit 42d90285c5
10 changed files with 212 additions and 94 deletions

View File

@@ -178,6 +178,9 @@
<Folder Include="Deploy\Eclipse\" /> <Folder Include="Deploy\Eclipse\" />
<Folder Include="Deploy\xCode\" /> <Folder Include="Deploy\xCode\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Location\Readme.md" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)' == 'iOS'"> <PropertyGroup Condition="'$(Configuration)' == 'iOS'">
<TypeScriptModuleKind>commonjs</TypeScriptModuleKind> <TypeScriptModuleKind>commonjs</TypeScriptModuleKind>
<TypeScriptRemoveComments>True</TypeScriptRemoveComments> <TypeScriptRemoveComments>True</TypeScriptRemoveComments>

View File

@@ -1,5 +1,6 @@
The way we get local path here is different for now. Maybe we should get it from FS module in the future samples. Sample code Android: The way we get local path here is different for now. Maybe we should get it from FS module in the future samples. Sample code Android:
``` ```
// TODO: Update code sample using require and BCL File/Folder var Image = require("Image").Image;
var baseImage = Image.imageFromResource('foxie');
``` ```

View File

@@ -12,6 +12,26 @@ export class Image {
this.android = null; this.android = null;
} }
public static imageFromResource(name: string): Image {
var image = new Image();
return image.loadFromResource(name) ? image : null;
}
public static imageFromFile(path: string): Image {
var image = new Image();
return image.loadFromFile(path) ? image : null;
}
public static imageFromData(data: any): Image {
var image = new Image();
return image.loadFromData(data) ? image : null;
}
public static imageFromNativeBitmap(source: any): Image {
var image = new Image();
return image.loadFromNativeBitmap(source) ? image : null;
}
public loadFromResource(name: string): boolean { public loadFromResource(name: string): boolean {
var androidApp = app_module.tk.ui.Application.current.android; var androidApp = app_module.tk.ui.Application.current.android;
var res = androidApp.context.getResources(); var res = androidApp.context.getResources();
@@ -35,7 +55,7 @@ export class Image {
return (this.android != null); return (this.android != null);
} }
public loadFromBitmap(source: any): boolean { public loadFromNativeBitmap(source: any): boolean {
this.android = source; this.android = source;
return (this.android != null); return (this.android != null);
} }

7
Image/image.d.ts vendored
View File

@@ -4,10 +4,15 @@
} }
export declare class Image { export declare class Image {
static imageFromResource(name: string): Image;
static imageFromFile(path: string): Image;
static imageFromData(data: any): Image;
static imageFromNativeBitmap(source: any): Image;
loadFromResource(name: string): boolean; loadFromResource(name: string): boolean;
loadFromFile(path: string): boolean; loadFromFile(path: string): boolean;
loadFromData(data: any): boolean; loadFromData(data: any): boolean;
loadFromBitmap(source: any): boolean; loadFromNativeBitmap(source: any): boolean;
saveToFile(path: string, format: ImageType, quality?: number): boolean; saveToFile(path: string, format: ImageType, quality?: number): boolean;
getHeight(): number; getHeight(): number;

View File

@@ -10,6 +10,26 @@ export class Image {
this.ios = null; this.ios = null;
} }
public static imageFromResource(name: string): Image {
var image = new Image();
return image.loadFromResource(name) ? image : null;
}
public static imageFromFile(path: string): Image {
var image = new Image();
return image.loadFromFile(path) ? image : null;
}
public static imageFromData(data: any): Image {
var image = new Image();
return image.loadFromData(data) ? image : null;
}
public static imageFromNativeBitmap(source: any): Image {
var image = new Image();
return image.loadFromNativeBitmap(source) ? image : null;
}
public loadFromResource(name: string): boolean { public loadFromResource(name: string): boolean {
this.ios = UIKit.UIImage.imageNamed(name); this.ios = UIKit.UIImage.imageNamed(name);
return (this.ios != null); return (this.ios != null);
@@ -25,7 +45,7 @@ export class Image {
return (this.ios != null); return (this.ios != null);
} }
public loadFromBitmap(source: any): boolean { public loadFromNativeBitmap(source: any): boolean {
this.ios = source; this.ios = source;
return (this.ios != null); return (this.ios != null);
} }

21
Location/Readme.md Normal file
View File

@@ -0,0 +1,21 @@
Initializing location:
```
console.log('is location enabled: ' + LocationManager.isLocationEnabled());
this.locationManager = new LocationManager();
console.dump(this.locationManager.getLastKnownLocation());
this.locationManager.startLocationMonitoring(function(location) {
console.dump(location);
}, function(error) {
console.error(error);
});
```
Stopping location:
```
this.locationManager.stopLocationMonitoring();
```

View File

@@ -1,26 +1,75 @@
import types_module = require("Location/location_types"); import types = require("Location/location_types");
import app_module = require("Application/application"); import app_module = require("Application/application");
export class LocationManager { export class LocationManager {
// in meters
// we might need some predefined values here like 'any' and 'high'
public desiredAccuracy: number;
//public regions: LocationRegion[]; // The minimum distance (measured in meters) a device must move horizontally before an update event is generated.
public updateDistance: number;
private _locationManager: any; // minimum time interval between location updates, in milliseconds (android only)
private _locationListener: android.location.LocationListener; public minimumUpdateTime: number;
public isLocationEnabled(): boolean { public isStarted: boolean;
// TODO add proper implementation private androidLocationManager: any;
return true;
private _locationListener: any;
public static isLocationEnabled(): boolean {
var criteria = new android.location.Criteria();
criteria.setAccuracy(1); // low ? fine ? who knows what 1 means (bug in android docs?)
var lm = app_module.tk.ui.Application.current.android.context.getSystemService('location');
return (lm.getBestProvider(criteria, true) != null) ? true : false;
} }
constructor() { constructor() {
//this.regions = []; // put some defaults
this.desiredAccuracy = types_module.DesiredAccuracy.ANY; this.desiredAccuracy = types.DesiredAccuracy.HIGH;
this._locationManager = app_module.tk.ui.Application.current.android.context.getSystemService('location'); this.updateDistance = 10;
Log('location manager: ' + this._locationManager); this.minimumUpdateTime = 200;
this.isStarted = false;
this._locationListener = new android.location.LocationListener({ this.androidLocationManager = app_module.tk.ui.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
public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: string) => any) {
if (!this.isStarted) {
var criteria = new android.location.Criteria();
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({
onLocationChanged: function (location: android.location.Location) { onLocationChanged: function (location: android.location.Location) {
if (this._onLocation) {
this._onLocation(LocationManager.locationFromAndroidLocation(location));
}
}, },
onProviderDisabled: function (provider: string) { onProviderDisabled: function (provider: string) {
@@ -32,56 +81,56 @@ export class LocationManager {
onStatusChanged: function (arg1: string, arg2: number, arg3: android.os.Bundle): void { onStatusChanged: function (arg1: string, arg2: number, arg3: android.os.Bundle): void {
} }
}); });
this._locationListener._onLocation = onLocation;
this._locationListener._onError = onError;
try {
this.androidLocationManager.requestLocationUpdates(long(this.minimumUpdateTime), float(this.updateDistance), criteria, this._locationListener, null);
this.isStarted = true;
}
catch (e) {
if (onError) {
onError(e.message);
}
}
}
else if (onError) {
onError('location monitoring already started');
} }
// in meters
// we might need some predefined values here like 'any' and 'high'
public desiredAccuracy: number;
// listeners
public locationChangeListener: types_module.LocationChangeListener;
// public regionChangeListener: RegionChangeListener;
/* // regions
public addRegion(region: LocationRegion) {
this.regions.push(region);
}
public removeRegion(region: LocationRegion) {
}
public clearRegions() {
}*/
// monitoring
public startLocationMonitoring() {
var criteria = new android.location.Criteria();
criteria.setAccuracy((this.desiredAccuracy === types_module.DesiredAccuracy.HIGH) ? 3 : 1);
var providers = this._locationManager.getProviders(criteria, false);
var it = providers.iterator();
while (it.hasNext()) {
var element = it.next();
Log('found provider: ' + element);
this._locationManager.requestLocationUpdates(element, 200, 10, this._locationListener);
}
} }
public stopLocationMonitoring() { public stopLocationMonitoring() {
this._locationManager.removeUpdates(this._locationListener); if (this.isStarted) {
this.androidLocationManager.removeUpdates(this._locationListener);
this.isStarted = false;
}
} }
// other // other
public getLastKnownLocation(): types_module.Location { public getLastKnownLocation(): types.Location {
var criteria = new android.location.Criteria();
criteria.setAccuracy((this.desiredAccuracy === types.DesiredAccuracy.HIGH) ? 1 : 2);
try {
var providers = this.androidLocationManager.getProviders(criteria, false);
var it = providers.iterator();
while (it.hasNext()) {
var element = it.next();
console.log('found provider: ' + element);
var location = this.androidLocationManager.getLastKnownLocation(element);
if (location) {
return LocationManager.locationFromAndroidLocation(location);
}
}
}
catch (e) {
console.error(e.message);
}
return null; return null;
} }
public distanceInMeters(loc1: types_module.Location, loc2: types_module.Location): number { public distanceInMeters(loc1: types.Location, loc2: types.Location): number {
return 0; return 0;
} }
} }

View File

@@ -28,19 +28,19 @@ export declare class LocationRegion {
} }
export declare class Location { export declare class Location {
public latitude: number; latitude: number;
public longitude: number; longitude: number;
public altitude: number; altitude: number;
public horizontalAccuracy: number; horizontalAccuracy: number;
public verticalAccuracy: number; verticalAccuracy: number;
public speed: number; // in m/s ? speed: number; // in m/s ?
public direction: number; // in degrees direction: number; // in degrees
public timestamp: Date; timestamp: Date;
} }
export declare class LocationChangeListener { export declare class LocationChangeListener {
@@ -54,9 +54,12 @@ export declare class RegionChangeListener {
} }
export declare class LocationManager { export declare class LocationManager {
isLocationEnabled(): boolean; static isLocationEnabled(): boolean;
desiredAccuracy: number; desiredAccuracy: number;
updateDistance: number; updateDistance: number;
// minimum time interval between location updates, in milliseconds (android only)
minimumUpdateTime: number;
isStarted: boolean;
// listeners // listeners
locationChangeListener: LocationChangeListener; locationChangeListener: LocationChangeListener;

View File

@@ -2,20 +2,6 @@
export class LocationManager { export class LocationManager {
private isStarted: boolean;
private locationManager: CoreLocation.CLLocationManager;
public isLocationEnabled(): boolean {
return CoreLocation.CLLocationManager.locationServicesEnabled();
}
constructor() {
this.isStarted = false;
this.desiredAccuracy = types.DesiredAccuracy.HIGH;
this.updateDistance = -1; // kCLDistanceFilterNone
this.locationManager = new CoreLocation.CLLocationManager();
}
// in meters // in meters
// we might need some predefined values here like 'any' and 'high' // we might need some predefined values here like 'any' and 'high'
public desiredAccuracy: number; public desiredAccuracy: number;
@@ -23,10 +9,19 @@ export class LocationManager {
// The minimum distance (measured in meters) a device must move horizontally before an update event is generated. // The minimum distance (measured in meters) a device must move horizontally before an update event is generated.
public updateDistance: number; public updateDistance: number;
// listeners public isStarted: boolean;
//public locationChangeListener: types.LocationChangeListener; private iosLocationManager: CoreLocation.CLLocationManager;
// monitoring 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();
@@ -38,10 +33,11 @@ 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);
console.dump(location); //console.dump(location);
return location; return location;
} }
// monitoring
public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: string) => any) { public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: string) => any) {
if (!this.isStarted) { if (!this.isStarted) {
var LocationListener = Foundation.NSObject.extends({ var LocationListener = Foundation.NSObject.extends({
@@ -73,10 +69,10 @@ export class LocationManager {
var listener = new LocationListener(); var listener = new LocationListener();
listener.setupWithFunctions(onLocation, onError); listener.setupWithFunctions(onLocation, onError);
this.locationManager.delegate = listener; this.iosLocationManager.delegate = listener;
this.locationManager.desiredAccuracy = this.desiredAccuracy; this.iosLocationManager.desiredAccuracy = this.desiredAccuracy;
this.locationManager.distanceFilter = this.updateDistance; this.iosLocationManager.distanceFilter = this.updateDistance;
this.locationManager.startUpdatingLocation(); this.iosLocationManager.startUpdatingLocation();
} }
else if (onError) { else if (onError) {
onError('location monitoring already started'); onError('location monitoring already started');
@@ -85,7 +81,7 @@ export class LocationManager {
public stopLocationMonitoring() { public stopLocationMonitoring() {
if (this.isStarted) { if (this.isStarted) {
this.locationManager.stopUpdatingLocation(); this.iosLocationManager.stopUpdatingLocation();
this.isStarted = false; this.isStarted = false;
} }
} }
@@ -93,7 +89,7 @@ export class LocationManager {
// other // other
public getLastKnownLocation(): types.Location { public getLastKnownLocation(): types.Location {
var clLocation = this.locationManager.location; var clLocation = this.iosLocationManager.location;
if (null != clLocation) { if (null != clLocation) {
return LocationManager.locationFromCLLocation(clLocation); return LocationManager.locationFromCLLocation(clLocation);
} }

View File

@@ -32,7 +32,7 @@ export class http {
var d = promises.defer<image_module.Image>(); var d = promises.defer<image_module.Image>();
http.get(url, r => { http.get(url, r => {
var image = new image_module.Image(); var image = new image_module.Image();
image.loadFromBitmap(r); image.loadFromNativeBitmap(r);
d.resolve(image); d.resolve(image);
}, e => d.reject(e)); }, e => d.reject(e));
return d.promise(); return d.promise();