检索最后一个已知的地理位置 - Phonegap
Posted
技术标签:
【中文标题】检索最后一个已知的地理位置 - Phonegap【英文标题】:Retrieving last known geolocation - Phonegap 【发布时间】:2012-06-05 12:12:08 【问题描述】:以下代码
navigator.geolocation.getCurrentPosition(getGeo_Success, getGeo_Fail,
enableHighAccuracy : true,
maximumAge : Infinity,
timeout : 15000
);
获取当前 GPS 位置 - 但是 - 必须有有效的 GPS 信号(当然,设备的 GPS 功能应该打开)。
如果我们查看其他应用程序(例如,android 设备上的地图) - 它知道如何检索 最后已知 位置 - 即使我没有使用更新地理位置的应用程序 在打开地图之前 - 它会在地图上显示我的位置,即使我在完全没有 GPS 信号的建筑物内。
澄清一下:我对我的应用程序检索到的最后一个地理位置不感兴趣,因为下次我将启动它时,该地理位置可能无关紧要。
问题是:我们如何使用 html5/Phonegap 实现这一点?似乎navigator.geolocation
只知道检索当前位置,即使maximumAge
设置为Infinity
(这意味着,最后缓存位置的年龄无关,所以任何命中都可以(或者,应该是! ))
【问题讨论】:
【参考方案1】:ANDROID 解决方案(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 代码上,只需使用以下命令调用本机 java:
window.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's 函数的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);
);
【讨论】:
请记住,此解决方案仅适用于 android,正如我之前所说 - 您必须为每种设备类型本地找到解决方案。祝你好运【参考方案2】:在我的 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() 时,我都会立即得到结果。就我的目的而言,这是一个很好的解决方法。
【讨论】:
【参考方案3】:我建议在您的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));
编辑:如果你想检索设备知道的最新位置(不是应用程序),你必须通过background从设备中提取当前数据的过程。这是有问题的方法,因为:
-
并非所有设备都允许这样做。
您必须编写自己的本地自定义 plugin 才能连接
phonegap。
【讨论】:
以上是关于检索最后一个已知的地理位置 - Phonegap的主要内容,如果未能解决你的问题,请参考以下文章