navigator.geolocation.getCurrentPosition() 方法在某些设备中返回位置请求超时 react-native

Posted

技术标签:

【中文标题】navigator.geolocation.getCurrentPosition() 方法在某些设备中返回位置请求超时 react-native【英文标题】:navigator.geolocation.getCurrentPosition() method returns location request timeout in some devices react-native 【发布时间】:2018-11-28 06:19:37 【问题描述】:

我正在开发一个跟踪用户位置的应用程序。我几乎已经完成了这项工作,但是当我进行测试时,有些设备会返回位置请求超时消息。在某些设备中也可以正常工作。我还添加了位置权限。在某些情况下,它还会返回“提供者 gps 不可用”。

LocationTrackingService.js

/**
 * Location Tracking Service
 */
import Toast from "react-native-simple-toast";
import WebService from "../webservice/WebService";
import WebServiceConfig,  APITypes  from "../webservice/WebServiceConfig";
import APINames from "../webservice/APINames";
// actions
import  getUserId  from "BkProvider/src/actions/AppInitializer";

// constants
const TIME_TO_CALL_API = 30000;
const WATCH_LOCATION_TIMEOUT = 1000;

const GeolocationOptions = 
    enableHighAccuracy: true,
    timeout: 10000,
    maximumAge: 1000


class LocationTrackingService 

    static classInstance = null;

    bookingId = '';
    currentWatchLocationTimeout = 0;
    isRunningService = false;
    callback = null;
    onGeolocationErrorOccurCallback = null;
    isServiceInBackground = false;

    /**
     * @returns LocationTrackingService
     */
    static getInstance() 

        if (LocationTrackingService.classInstance == null) 
            LocationTrackingService.classInstance = new LocationTrackingService();
        

        return this.classInstance;

    

    webServiceObject = null;
    apiNames = APINames;
    apiTypes = APITypes;

    /**
     * Method To Get Api Names
     */
    getAPINames() 
        return this.apiNames;
    

    /**
     * Method To Get Web Service Config Instance
     */
    getWebServiceConfigInstance(apiName) 
        if (apiName !== null) 
            return new WebServiceConfig(apiName)
        
        return null;
    

    /**
     * Method To Clear the web service object
     */
    clearWebServiceObject() 
        this.webServiceObject = null;
    

    /**
     * Method To Get Web Service Object
     * @param * onResultCallback 
     */
    getWebServiceObject(onResultCallback) 
        //if (this.webServiceObject == null)
        this.webServiceObject = new WebService(onResultCallback);

        return this.webServiceObject;
    

    /**
     * Method To Get User Id
     */
    getUserIdBase() 
        return getUserId();
    

    /**
     * Method To Show Toast
     * @param string message 
     */
    showToast(message) 
        if (message != null)
            Toast.show(message, Toast.SHORT);
        else
            Toast.show("Dev error message should not be null", Toast.SHORT);

    

    /**
     * Method To Set BookingId
     */
    setBookingId(bookingId) 
        if (bookingId)
            this.bookingId = bookingId;
    

    /**
     * This Method Start Service In Background Mode
     * If It Set Callback No Longer Work and UI no longer update
     */
    startServiceInBackground() 
        this.isServiceInBackground = true;
    

    /**
     * Method To Clock In The Provicer
     */
    clockInProvider() 
        navigator.geolocation.getCurrentPosition(response => 
            console.log(response)
            if (response && response.coords) 
                this.showToast('Step 1: Provider Clocked In');
                this.saveProviderClockInLogs(response.coords);
            
        ,
            (error) => 
                //this.onGeolocationErrorOccurCallback;
                console.log(error) //  TIMEOUT: 3,  POSITION_UNAVAILABLE: 2, PERMISSION_DENIED: 1, message: "Location request timed out", code: 3 
            ,
            GeolocationOptions
        )
    

    /**
     * Method To Save Provider Clock In Logs
     */
    saveProviderClockInLogs(geolocation) 
        let postParams = 
            "booking_id": this.bookingId,
            "provider_id": this.getUserIdBase(),
            "location": 
                "lat": geolocation.latitude,
                "lng": geolocation.longitude
            
        

        let apiConfig = this.getWebServiceConfigInstance(this.getAPINames().SaveProviderClockInLogs)
            .setAPIType(this.apiTypes.POST);

        this.getWebServiceObject(this.onResultCallback)
            .addServiceConfiguration(apiConfig)
            .addPostParameterObject(JSON.stringify(postParams))
            .execute()
    

    /**
     * Method To Clock Out Provier
     */
    clockOutProvider() 
        navigator.geolocation.getCurrentPosition((response) => 
            if (response && response.coords) 
                this.saveProviderClockOutLogs(response.coords);
            
        ,
            () => 
                this.onGeolocationErrorOccurCallback;
            ,
            GeolocationOptions
        );
    

    /**
     * Method To Save Provider Clock Out Logs
     */
    saveProviderClockOutLogs(response) 
        if (response) 
            let postParams = 
                "booking_id": this.bookingId,
                "provider_id": this.getUserIdBase(),
                "location": 
                    "lat": response.latitude,
                    "lng": response.longitude
                
            

            let apiConfig = this.getWebServiceConfigInstance(this.getAPINames().SaveProviderClockOutLogs)
                .setAPIType(this.apiTypes.POST);

            this.getWebServiceObject(this.onResultCallback)
                .addPostParameterObject(JSON.stringify(postParams))
                .addServiceConfiguration(apiConfig)
                .execute()
        
    

    providerRouteCoordinates = []; // provider routes followed coordinates

    /**
     * Method To Start Location Tracking
     */
    start(destinationLocation, bookingAddressArea) 
        this.showToast('Step 3: Before Update Location');
        console.log('provider tracking enable', destinationLocation)
        this.isRunningService = true;

        let currentPosition = 
            lat: '',
            lng: ''
        

        this.watchId = navigator.geolocation.watchPosition((response) => 

            this.showToast('Step 4: Location Changed')

            this.currentWatchLocationTimeout = this.currentWatchLocationTimeout + WATCH_LOCATION_TIMEOUT;

            currentPosition.lat = response.coords.latitude;
            currentPosition.lng = response.coords.longitude;

            this.providerRouteCoordinates.push(`$(currentPosition.lat).toString(),$(currentPosition.lng).toString()`);

            if (this.calculateBookingLocationDistanceFromProviderLocation(currentPosition.lat, currentPosition.lng, destinationLocation.lat, destinationLocation.lng) <= bookingAddressArea) 
                this.stopTracking();
                this.showToast('Provider Reached The Destination!')
                this.saveProviderRouteCoordinates(this.providerRouteCoordinates);
                this.providerRouteCoordinates = []; // clear the old routes coordinates
                this.providerReachedTheDestination();
            

            if (this.currentWatchLocationTimeout == TIME_TO_CALL_API) 
                this.currentWatchLocationTimeout = 0;
                this.showToast(`Step 5: Routes Are Updated In $this.currentWatchLocationTimeout`);
                this.saveProviderRouteCoordinates(this.providerRouteCoordinates);
                this.providerRouteCoordinates = []; // clear the old routes coordinates
            

        , (error) => 
            alert(JSON.stringify(error))
        , 
                timeout: WATCH_LOCATION_TIMEOUT,
                distanceFilter: 5,
                enableHighAccuracy: true
            );

    

    /**
     * Method To Pause Tracking
     */
    pauseTracking() 
        navigator.geolocation.getCurrentPosition((response) => 
            if (response && response.coords) 
                this.saveProviderPauseLogs(response.coords);
            
        ,
            () => 
                this.onGeolocationErrorOccurCallback;
            ,
            GeolocationOptions
        );
    

    /**
     * Method To Resume Tracking
     */
    resumeTracking() 
        navigator.geolocation.getCurrentPosition((response) => 
            if (response && response.coords) 
                this.saveProviderResumeLogs(response.coords);
            
        ,
            () => 
                this.onGeolocationErrorOccurCallback;
            ,
            GeolocationOptions
        );
    

    /**
     * Method To Save Provider Pause Logs
     */
    saveProviderPauseLogs(response) 
        if (response) 
            let postParams = 
                "booking_id": this.bookingId,
                "provider_id": this.getUserIdBase(),
                "location": 
                    "lat": response.latitude,
                    "lng": response.longitude
                
            

            let apiConfig = this.getWebServiceConfigInstance(this.apiNames.SaveProviderPauseLogs)
                .setAPIType(this.apiTypes.POST);

            this.getWebServiceObject(this.onResultCallback)
                .addServiceConfiguration(apiConfig)
                .addPostParameterObject(JSON.stringify(postParams))
                .execute()
        
    

    /**
     * Method To Save Provider Resume Logs
     */
    saveProviderResumeLogs(response) 
        if (response) 
            let postParams = 
                "booking_id": this.bookingId,
                "provider_id": this.getUserIdBase(),
                "resume_location": 
                    "lat": response.latitude,
                    "lng": response.longitude
                
            

            let apiConfig = this.getWebServiceConfigInstance(this.apiNames.SaveProviderResumeLogs)
                .setAPIType(this.apiTypes.POST);

            this.getWebServiceObject(this.onResultCallback)
                .addServiceConfiguration(apiConfig)
                .addPostParameterObject(JSON.stringify(postParams))
                .execute()
        
    

    /**
     * This Method Is Used To Save The Provider Route Coordinates
     */
    saveProviderRouteCoordinates(routesCoordinates) 
        // post params
        let postParams = 
            "route_coordinates": routesCoordinates
        
        let apiConfig = this.getWebServiceConfigInstance(this.apiNames.SavProviderTrackingLogs)
            .addURLParameters([this.bookingId, this.getUserIdBase()])
            .setAPIType(this.apiTypes.POST)

        this.getWebServiceObject(this.onResultCallback)
            .addServiceConfiguration(apiConfig)
            .addPostParameterObject(JSON.stringify(postParams))
            .execute()
    

    /**
     * On Provider Reached The Destination
     */
    providerReachedTheDestination() 
        let apiConfig = this.getWebServiceConfigInstance(this.apiNames.AddProviderArrivalTime)
            .addURLParameters([this.bookingId, this.getUserIdBase()])
            .setAPIType(this.apiTypes.PUT)

        this.getWebServiceObject(this.onResultCallback)
            .addServiceConfiguration(apiConfig)
            .execute()
    

    /**
     * Get Traveled Distance And Time
     */
    getTraveledDistanceAndTime() 
        let apiConfig = this.getWebServiceConfigInstance(this.apiNames.GetTraveledDistanceAndTime)
            .addURLParameters([this.bookingId, this.getUserIdBase()])

        this.getWebServiceObject(this.onResultCallback)
            .addServiceConfiguration(apiConfig)
            .execute()
    

    /**
     * Api Method To Save Adjustments
     */
    saveAdjustments(data) 
        if (data) 
            let postParams = 
                booking_id: this.bookingId,
                provider_id: this.getUserIdBase(),
                travel_time: data.travel_time,
                job_length: data.job_length,
                travel_distance: Number((data.travel_distance).toFixed(2))
            

            let apiConfig = this.getWebServiceConfigInstance(this.apiNames.SaveAdjustments)
                .setAPIType(this.apiTypes.POST)

            this.getWebServiceObject(this.onResultCallback)
                .addServiceConfiguration(apiConfig)
                .addPostParameterObject(JSON.stringify(postParams))
                .execute()
        
    

    /**
     * On Result Callback
     */
    onResultCallback = (webServiceResultObj) => 
        this.callback(webServiceResultObj);
    

    /**
     * Method To Stop Location Tracking
     */
    stopTracking() 
        this.isRunningService = false;
        navigator.geolocation.clearWatch(this.watchId);
    

    /**
     * Method To Calculate Booking Location Distance From Provider Location
     */
    calculateBookingLocationDistanceFromProviderLocation(lat1, lon1, lat2, lon2) 
        var R = 6371; // km (change this constant to get miles)
        var dLat = (lat2 - lat1) * Math.PI / 180;
        var dLon = (lon2 - lon1) * Math.PI / 180;
        var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        var d = R * c;
        return Math.round(d * 1000);
    



export default LocationTrackingService;

【问题讨论】:

【参考方案1】:

我有时也会遇到同样的问题。在我的情况下是因为 GPS 信号较弱,尝试将 enableHighAccuracy 设置为 false -- enableHighAccuracy: false

某些设备无法获得高精度信号。

【讨论】:

您好,感谢您的回复。我已经添加了这个,但仍然无法正常工作。

以上是关于navigator.geolocation.getCurrentPosition() 方法在某些设备中返回位置请求超时 react-native的主要内容,如果未能解决你的问题,请参考以下文章