Android onLocationChanged location.getTime() возвращает неправильное время

У меня есть Samsung Galaxy Tab A. Я реализовал android.location.LocationListener, и onLocationChanged(Location location) вызывается, и это дает мне правильную долготу и широту, но,

Проблема в том, что location.getTime() дает мне неправильное время, оно возвращает время около 300000 мил или около того. Должно быть что-то вроде 1471243684497.

Я не знаю, что делать.

Класс GPSTracker:

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener
{
    //flag for GPS Status
    boolean isGPSEnabled = false;
    
    //flag for network status
    //boolean isNetworkEnabled = false;
    
    boolean canGetLocation = false;
    
    Location location;
    double latitude;
    double longitude;
    
    //The minimum distance to change updates in metters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; //10 metters
    
    //The minimum time beetwen updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1000 * 10; // 1 minute
    
    //Declaring a Location Manager
    protected LocationManager locationManager;
    
    /*public GPSTracker(Context context) 
    {
        this.mContext = context;
        getLocation();
    }*/
    
    public Location getLocation(Context ctx)
    {
        try
        {
            locationManager = (LocationManager) ctx.getSystemService(LOCATION_SERVICE);
    
            //getting GPS status
            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
            //getting network status
            //isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
            if (!isGPSEnabled /*&& !isNetworkEnabled*/)
            {
                // no network provider is enabled
            }
            else
            {
                this.canGetLocation = true;
    
                //First get location from Network Provider
               /* if (isNetworkEnabled)
                {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
    
                    Log.d("Network", "Network");
    
                    if (locationManager != null)
                    {
                        location = 
                                locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        updateGPSCoordinates();
                    }
                }*/
    
                //if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled)
                {
                    if (location == null)
                    {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
    
                        Log.d("GPS Enabled", "GPS Enabled");
    
                        if (locationManager != null)
                        {
                            location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            updateGPSCoordinates();
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            //e.printStackTrace();
            Log.e("Error : Location", "Impossible to connect to LocationManager", e);
        }
    
        return location;
    }
    
    public void updateGPSCoordinates()
    {
        if (location != null)
        {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
        }
    }
    
    /**
     * Stop using GPS listener
     * Calling this function will stop using GPS in your app
     */
    
    public void stopUsingGPS()
    {
        if (locationManager != null)
        {
            locationManager.removeUpdates(GPSTracker.this);
        }
    }
    
    /**
     * Function to get latitude
     */
    public double getLatitude()
    {
        if (location != null)
        {
            latitude = location.getLatitude();
        }
    
        return latitude;
    }
    
    /**
     * Function to get longitude
     */
    public double getLongitude()
    {
        if (location != null)
        {
            longitude = location.getLongitude();
        }
    
        return longitude;
    }
    
    /**
     * Function to check GPS/wifi enabled
     */
    public boolean canGetLocation()
    {
        if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)/*&&
                !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)*/){
            this.canGetLocation = false;
        } else {
            this.canGetLocation = true;
        }
        return this.canGetLocation;
    }
    
    /**
     * Get list of address by latitude and longitude
     * @return null or List<Address>
     */
    public List<Address> getGeocoderAddress(Context context)
    {
        if (location != null)
        {
            Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
            try 
            {
                List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
                return addresses;
            } 
            catch (IOException e) 
            {
                //e.printStackTrace();
                Log.e("Error : Geocoder", "Impossible to connect to Geocoder", e);
            }
        }
    
        return null;
    }
    
    /**
     * Try to get AddressLine
     * @return null or addressLine
     */
    public String getAddressLine(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);
            String addressLine = address.getAddressLine(0);
    
            return addressLine;
        }
        else
        {
            return null;
        }
    }
    
    /**
     * Try to get Locality
     * @return null or locality
     */
    public String getLocality(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);
            String locality = address.getLocality();
    
            return locality;
        }
        else
        {
            return null;
        }
    }
    
    /**
     * Try to get Postal Code
     * @return null or postalCode
     */
    public String getPostalCode(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);
            String postalCode = address.getPostalCode();
    
            return postalCode;
        }
        else
        {
            return null;
        }
    }
    
    /**
     * Try to get CountryName
     * @return null or postalCode
     */
    public String getCountryName(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);
            String countryName = address.getCountryName();
    
            return countryName;
        }
        else
        {
            return null;
        }
    }
    
    @Override
    public void onLocationChanged(Location location) 
    {   
    }
    
    @Override
    public void onProviderDisabled(String provider) 
    {   
    }
    
    @Override
    public void onProviderEnabled(String provider) 
    {   
    }
    

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}

И мой собственный класс, расширяющий класс GPSTracker:

public class NewMainService extends GPSTracker {
    

    @Override
    public void onLocationChanged(Location location) {
        long time = location.getTime();
        Log.i("TAG", "onLocationChanged time: "+time); //prints wrong timestamp
        super.onLocationChanged(location);
    }
}

ИЗМЕНИТЬ:

на других устройствах все работает нормально.

Я погуглил, и это ошибка на некоторых устройствах. прослушиватели местоположения перестают получать изменения через некоторое время.

время, которое он мне дает, похоже на время безотказной работы устройства, это несколько часов, это не дата.

EDIT 2: теперь я использую вместо этого com.google.android.gms.location.FusedLocationProviderClient, а android.location.LocationManager даже больше не дает мне никаких обновлений местоположения на Android 10+.


person M D P    schedule 15.08.2016    source источник
comment
Была такая же проблема (LocationManager возвращает местоположение с временем безотказной работы устройства вместо времени с эпохи) - если возможно, не могли бы вы дать ссылки на ошибку? Не удалось найти ничего, кроме этого SO-вопроса. Большое спасибо!   -  person Aleph Aleph    schedule 11.05.2017
comment
@AlephAleph, в итоге я реализовал свой собственный простой прослушиватель местоположения, а не Fused Location. и смешал его с блокировкой пробуждения типа PARTIAL_WAKE_LOCK, я зарегистрировал Locationmanager для прослушивания как сетевого провайдера, так и провайдера GPS. и теперь он работает нормально.   -  person M D P    schedule 12.05.2017
comment
У меня похожая проблема на некоторых устройствах Asus. Я использую Fused Location Provider. Метод getTime() иногда возвращает время с ошибкой в ​​один час. Я не меняю время и часовой пояс устройства. Вы нашли какое-нибудь решение?   -  person Bobs    schedule 16.05.2018
comment
При запуске запросов местоположения onLocationChanged, кажется, дает старое местоположение из некоторого буфера. Я всегда устанавливаю время последнего исправления и беру время только в том случае, если время больше, чем последнее исправление (и не беру время с первого исправления, а только устанавливаю с ним last_location_time). Я предлагаю также проверить провайдера и потратить время, только если provider.equals(LocationManager.GPS_PROVIDER); Я не думаю, что вы могли бы полагаться на временную метку Wi-Fi, если таковая имеется. Я все еще задаюсь вопросом, действительно ли это отказоустойчиво или мне следует полностью отказаться от использования времени GPS и полностью переключиться на SNTP.   -  person FrankKrumnow    schedule 01.07.2020
comment
@FrankKrumnow Вместо этого используйте com.google.android.gms.location.FusedLocationProviderClient   -  person M D P    schedule 03.07.2020


Ответы (1)


Вы можете использовать прослушиватель местоположения NMEA и получать только время от него. это всегда верно и указано время UTC, даже если вы измените часовой пояс или дату и время вашего устройства, это всегда будет давать вам текущую реальную дату и время.

Ограничения:

-Если GPS или местоположение отключены, вы не получите NMEA. (вы можете проверить, включено ли местоположение или нет)

-если местоположение включено, но пользователь изменил его точность на сетевую только через настройки, вы не получите NMEA. (вы можете проверить, если locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) )

person M D P    schedule 14.06.2017