简体   繁体   中英

navigator.geolocation.getCurrentPosition() method returns location request timeout in some devices react-native

I'm working on an app in which user location is track. I have almost completed this but when I had tested there are some devices returns location request timeout message. Also in some devices it works fine. I have also added the location permissions. In some case it also returns "provider gps unavailable".

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;

I got the same issue sometimes. In my case was because of weak GPS signal, try to set enableHighAccuracy to false -- enableHighAccuracy: false .

Some devices can't get a high accuracy signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM