以下代码
navigator.geolocation.getCurrentPosition(getGeo_Success, getGeo_Fail, {
enableHighAccuracy : true,
maximumAge : Infinity,
timeout : 15000
});
检索当前的GPS位置 - BUT - 必须有一个有效的GPS信号(当然,应该打开设备的GPS功能)。
如果我们查看其他应用程序(例如,Android设备上的地图) - 它知道如何检索上次已知的位置 - 即使我没有使用更新地理位置的应用程序在打开地图之前 - 它显示了我在地图上的位置,即使我在一个没有GPS信号的建筑物内。
只是为了澄清:我对我的应用程序检索到的最后一个地理定位不感兴趣,因为下次我开始它时,地理位置可能会无关紧要。
问题是:我们如何通过HTML5 / Phonegap实现这一目标?似乎navigator.geolocation
只知道检索当前位置,即使maximumAge
设置为Infinity
(这意味着,最后一个缓存位置的年龄无关紧要,所以任何命中都可以(或者,应该!))
答案 0 :(得分:2)
ANDROID SOLUTION(iPhone解决方案如下):
这很整洁:
我使用了Android的原生LocationManager
,它提供了getLastKnownLocation
功能 - 名称说明了所有
这是相关代码
1)将以下java类添加到您的应用程序
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)确保您的主要课程如下所示:
public class App extends DroidGap {
// Hold a private member of the class that calls LocationManager
private GetNativeLocation gLocation;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This line is important, as System Services are not available
// prior to initialization
super.init();
gLocation = new GetNativeLocation(this, appView);
// Add the interface so we can invoke the java functions from 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)在您的JS代码上,只需使用:
调用本机javawindow.NativeLocation.doInit();
alert(window.NativeLocation.getLat());
alert(window.NativeLocation.getLong());
多数民众议员! : - )
修改: iPhone解决方案:
我写了一个小小的Phonegap插件,它创建了一个自定义类的接口,该类使用了iOS的原生CLLocationManager
1)Phonegap插件(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)使我们能够调用'CCLocationManager函数的objective-c类 * 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)最后,调用主.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); }
);
答案 1 :(得分:1)
在我的PhoneGap / Sencha Touch 2应用程序中,我创建了函数
function getLastKnownLocation(){
if(typeof localStorage.lastKnownPosition == "undefined"){
localStorage.lastKnownPosition = JSON.stringify(null);
}
navigator.geolocation.getCurrentPosition(
function(position){
localStorage.lastKnownPosition = JSON.stringify(position);
}
);
return JSON.parse(localStorage.lastKnownPosition);
}
所以每当我调用getLastKnownLocation()时,我立即得到一个结果。对我来说这是一个很好的解决方法。
答案 2 :(得分:0)
我建议您在getGeo_Success
函数调用setLocation([the_location])
中将其存储在 localStorage 。
您可以假设使用phoneGap的每个设备都已实现localStorage。<登记/>
这样,你总是有有效的位置。然后只需在需要时弹出它。
function getLocation() {
return JSON.parse(localStorage.getItem('location'));
}
function setLocation(location) {
localStorage.setItem('vibesList', JSON.stringify(vibes));
}
编辑:如果您要重新访问设备所知道的最新地点(而不是应用),则必须通过后台进行操作从设备中提取当前数据的过程。这是有问题的方法,因为: