2

次のコード

navigator.geolocation.getCurrentPosition(getGeo_Success, getGeo_Fail, {
    enableHighAccuracy : true,
    maximumAge : Infinity,
    timeout : 15000
});

現在のGPS位置を取得します-しかし-有効なGPS信号が必要です(もちろん、デバイスのGPS機能をオンにする必要があります)。

他のアプリケーション(たとえば、Androidデバイスのマップ)を見ると、マップを開くにジオロケーションを更新するアプリケーションを使用していなくても、最後の既知の位置を取得する方法を知っています。マップ上の自分の位置が表示されます。 GPS信号がまったくない建物の中にいても。

明確にするために、アプリケーションが最後に取得したジオロケーションには興味がありません。次回起動するときに、そのジオロケーションはおそらく無関係になるでしょう。

質問は: HTML5 / Phonegapでこれをどのように達成できますか?に設定されnavigator.geolocationていても、現在の位置を取得することしか知らないようです(つまり、最後にキャッシュされた位置の年齢は関係ないので、ヒットしても問題ありません(またはそうあるべきです!))maximumAgeInfinity

4

3 に答える 3

2

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ソリューション:

iOSのネイティブを利用するカスタムクラスへのインターフェイスを作成する小さなPhonegapプラグインを作成しました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); }
                               );
于 2012-06-05T13:28:32.870 に答える
1

PhoneGap / SenchaTouch2アプリケーションで関数を作成しました

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()を呼び出すたびに、すぐに結果が得られます。これは、私の目的にとっては良い回避策です。

于 2012-06-14T09:54:41.087 に答える
0

getGeo_Success関数呼び出しでlocalStoragesetLocation([the_location])に保存することをお勧めします。phoneGapを使用する各デバイスはすでにlocalStorageを実装していると想定できます。 このように、あなたは常にそこに有効な場所を持っています。必要なときにいつでもポップします。

function getLocation() {
  return JSON.parse(localStorage.getItem('location'));
}
function setLocation(location) {
  localStorage.setItem('vibesList', JSON.stringify(vibes));
}

編集:デバイスが認識している最新の場所(アプリではない)を取得する場合は、デバイスから現在のデータを取得するバックグラウンドプロセスを介して取得する必要があります。これは問題のあるアプローチです。理由は次のとおりです。

  1. すべてのデバイスで許可されているわけではありません。
  2. そのためにphonegapに接続するには、独自のネイティブカスタムプラグインを作成する必要があります。
于 2012-06-05T12:26:32.863 に答える