jquery - Retrieving last known geolocation - Phonegap -
the following code
navigator.geolocation.getcurrentposition(getgeo_success, getgeo_fail, { enablehighaccuracy : true, maximumage : infinity, timeout : 15000 }); retrieves current gps position - but - there must valid gps signal (and ofcourse, device's gps feature should turned on).
if @ other applications (say, maps on android devices) - knows how retrieve last known position - if didn't use application updates geolocation before opening maps - shows position on map, if i'm inside building no gps signal @ all.
just clarify: i'm not interested in last geolocation application retrieved, on next time i`ll start it, geolocation irrelevant.
question is: how can achieve html5/phonegap? seems navigator.geolocation knows retrieve current position, though, maximumage set infinity (which means, age of last cached position irrelevant, hit okay (or, should be!))
android solution (iphone solution follows):
this neat:
i've made use of android's native locationmanager, provides getlastknownlocation function - name says all
here's relevant code
1) add following java class application
package your.package.app.app; import org.apache.cordova.droidgap; import android.content.context; import android.location.*; import android.os.bundle; import android.webkit.webview; public class getnativelocation implements locationlistener { private webview mappview; private droidgap mgap; private location mostrecentlocation; public getnativelocation(droidgap gap, webview view) { mappview = view; mgap = gap; } public void onlocationchanged(location location) { // todo auto-generated method stub getlocation(); } public void getlocation() { locationmanager lm = (locationmanager)mgap. getsystemservice(context.location_service); criteria criteria = new criteria(); criteria.setaccuracy(criteria.accuracy_fine); string provider = lm.getbestprovider(criteria, true); lm.requestlocationupdates(provider, 1000, 500, this); mostrecentlocation = lm .getlastknownlocation(locationmanager.gps_provider); } public void doinit(){ getlocation(); } public double getlat(){ return mostrecentlocation.getlatitude();} public double getlong() { return mostrecentlocation.getlongitude(); } public void onproviderdisabled(string arg0) { // todo auto-generated method stub } public void onproviderenabled(string provider) { // todo auto-generated method stub } public void onstatuschanged(string provider, int status, bundle extras) { // todo auto-generated method stub } } 2) make sure main class looks follows:
public class app extends droidgap { // hold private member of class calls locationmanager private getnativelocation glocation; /** called when activity first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // line important, system services not available // prior initialization super.init(); glocation = new getnativelocation(this, appview); // add interface can invoke java functions our .js appview.addjavascriptinterface(glocation, "nativelocation"); try { super.loadurl("file:///android_asset/www/index.html"); } catch (exception e) { // todo: handle exception e.printstacktrace(); } } @override public void ondestroy() { // todo auto-generated method stub super.ondestroy(); } @override protected void onstop() { // todo auto-generated method stub super.onstop(); } } 3) on js code, call native java using:
window.nativelocation.doinit(); alert(window.nativelocation.getlat()); alert(window.nativelocation.getlong()); thats folks! :-)
edit: iphone solution:
i wrote tiny phonegap plugin creates interface custom class making use of ios's native cllocationmanager
1) phonegap plugin (js)
var nativelocation = { doinit: function(types, success, fail) { return cordova.exec(success, fail, "nativelocation", "doinit", types); }, getlongitude: function(types, success, fail){ return cordova.exec(success, fail, "nativelocation", "getlongitude", types); }, getlatitude: function(types, success, fail){ return cordova.exec(success, fail, "nativelocation", "getlatitude", types); } } 2) objective-c class enables invoke 'cclocationmanager's functions *nativelocation.h*
#import <foundation/foundation.h> #import <cordova/cdvplugin.h> #import <corelocation/corelocation.h> @protocol nativelocationdelegate @required - (void)locationupdate:(cllocation *)location; - (void)locationerror:(nserror *)error; @end @interface nativelocation : cdvplugin <cllocationmanagerdelegate> { id delegate; nsstring* callbackid; cllocationmanager *lm; boolean benabled; double nlat; double nlon; } @property (nonatomic, copy) nsstring* callbackid; @property (nonatomic, retain) cllocationmanager *lm; @property (nonatomic, readonly) boolean benabled; @property (nonatomic, assign) id delegate; - (void) doinit:(nsmutablearray*)arguments withdict:(nsmutabledictionary*)options; - (void) getlatitude:(nsmutablearray*)arguments withdict:(nsmutabledictionary *)options; - (void) getlongitude:(nsmutablearray*)arguments withdict:(nsmutabledictionary *)options; @end nativelocation.m
#import "nativelocation.h" @implementation nativelocation @synthesize callbackid; @synthesize lm; @synthesize benabled; @synthesize delegate; - (void)doinit:(nsmutablearray *)arguments withdict:(nsmutabledictionary *)options{ if (self != nil){ self.lm = [[[cllocationmanager alloc] init] autorelease]; self.lm.delegate = self; if (self.lm.locationservicesenabled == no) benabled = false; else benabled = true; } nlat = 0.0; nlon = 0.0; if (benabled == true) [self.lm startupdatinglocation]; cdvpluginresult* pluginresult = [cdvpluginresult resultwithstatus:cdvcommandstatus_ok messageasstring[@"ok" stringbyaddingpercentescapesusingencoding:nsutf8stringencoding]]; if (benabled == true){ [self writejavascript: [pluginresult tosuccesscallbackstring:self.callbackid]]; } else { [self writejavascript: [pluginresult toerrorcallbackstring:self.callbackid]]; } } - (void)locationmanager:(cllocationmanager *)manager didupdatetolocation:(cllocation *)newlocation fromlocation:(cllocation *)oldlocation { if ([self.delegate conformstoprotocol:@protocol(nativelocationdelegate)]) [self.delegate locationupdate:newlocation ]; } - (void)locationmanager:(cllocationmanager *)manager didfailwitherror:(nserror *)error { if ([self.delegate conformstoprotocol:@protocol(nativelocationdelegate)]) [self.delegate locationerror:error]; } - (void)dealloc { [self.lm release]; [super dealloc]; } - (void)locationupdate:(cllocation *)location { cllocationcoordinate2d ccoord = [location coordinate]; nlat = ccoord.latitude; nlon = ccoord.longitude; } - (void)getlatitude:(nsmutablearray *)arguments withdict:(nsmutabledictionary *)options{ self.callbackid = [arguments pop]; nlat = lm.location.coordinate.latitude; nlon = lm.location.coordinate.longitude; cdvpluginresult* pluginresult = [cdvpluginresult resultwithstatus:cdvcommandstatus_ok messageasdouble:nlat]; [self writejavascript: [pluginresult tosuccesscallbackstring:self.callbackid]]; } - (void)getlongitude:(nsmutablearray *)arguments withdict:(nsmutabledictionary *)options{ self.callbackid = [arguments pop]; nlat = lm.location.coordinate.latitude; nlon = lm.location.coordinate.longitude; cdvpluginresult* pluginresult = [cdvpluginresult resultwithstatus:cdvcommandstatus_ok messageasdouble:nlon]; [self writejavascript: [pluginresult tosuccesscallbackstring:self.callbackid]]; } @end 3) , finally, invoking main .js
function getlongitudesuccess(result){ glongitude = result; } function getlatitudesuccess(result){ glatitude = result; } function rungpstimer(){ var stmp = "gps"; thetime = settimeout('rungpstimer()', 1000); nativelocation.getlongitude( ["getlongitude"], getlongitudesuccess, function(error){ alert("error: " + error); } ); nativelocation.getlatitude( ["getlatitude"], getlatitudesuccess, function(error){ alert("error: " + error); } );
Comments
Post a Comment