无法在后台服务中使用 LocationManager 获取位置

Posted

技术标签:

【中文标题】无法在后台服务中使用 LocationManager 获取位置【英文标题】:Can't Get Location using LocationManager in Background Service 【发布时间】:2014-07-23 10:50:33 【问题描述】:

我创建了一个应用程序,它在后台服务中定期将您的位置存储在数据库中,但是它没有获取位置。我的代码是...

public class LocationService extends Service 

    private Double myLat, myLong;
    private Location location;
    private LocationManager locManager;
    private LocationListener locationListener;
    private boolean NETWORK_ENABLED, GPS_ENABLED, PASSIVE_ENABLED;

    @Override
    public IBinder onBind(Intent intent) 
        return null;
    

    @Override
    public void onCreate() 
        Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_LONG).show();
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        super.onStartCommand(intent, flags, startId);
        myLat = 0.00;
        myLong = 0.00;
        locationListener = new LocationListener() 
            @Override
            public void onLocationChanged(Location location) 
                LocationService.this.location = location;
                LocationService.this.myLat = location.getLatitude();
                LocationService.this.myLong = location.getLongitude();
                Toast.makeText(getApplicationContext(), "onLocationChanged", Toast.LENGTH_LONG).show();
                insertToDatabase();
            
            @Override
            public void onProviderDisabled(String provider) 

            @Override
            public void onProviderEnabled(String provider) 

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

        getMyCurrentLocation();

    

    private void getMyCurrentLocation() 
        location = null;
        locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        NETWORK_ENABLED = false; GPS_ENABLED = false; PASSIVE_ENABLED = false;
        NETWORK_ENABLED = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (NETWORK_ENABLED) 
            Toast.makeText(getApplicationContext(), "Network Provider", Toast.LENGTH_LONG).show();
            locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 45 * 1000l, 1f, locationListener);
         
        if (location == null) 
            //setGPSOn();
            GPS_ENABLED = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            if(GPS_ENABLED) 
                Toast.makeText(getApplicationContext(), "GPS Provider", Toast.LENGTH_LONG).show();  
                locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0l, 1f, locationListener);
            
            //setGPSOff();
         
        if (location == null) 
            PASSIVE_ENABLED = locManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
            if(PASSIVE_ENABLED) 
                Toast.makeText(getApplicationContext(), "Passive Provider", Toast.LENGTH_LONG).show();
                locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0l, 1f, locationListener);
            
        
        try 
            location = locManager.getLastKnownLocation(locManager.getBestProvider(new Criteria(), true));
         catch(NullPointerException e) 
        if (location != null) 
            myLat = location.getLatitude();
            myLong = location.getLongitude();
            insertToDatabase();
         else 
            Location loc = null;
            try 
                loc = getLastKnownLocation(this);
             catch(NullPointerException e) 
            if (loc != null) 
                myLat = loc.getLatitude();
                myLong = loc.getLongitude();
                insertToDatabase();
            
        
        locManager.removeUpdates(locationListener);
    

    private Location getLastKnownLocation(Context context) 
        Location location = null;
        LocationManager locationmanager = (LocationManager)context.getSystemService("location");
        List<?> list = locationmanager.getAllProviders();
        boolean i = false;
        Iterator<?> iterator = list.iterator();
        do 
            if(!iterator.hasNext())
                break;
            String s = (String)iterator.next();
            if(i != false && !locationmanager.isProviderEnabled(s))
                continue;
            Location location1 = locationmanager.getLastKnownLocation(s);
            if(location1 == null)
                continue;
            else 
                float f = location.getAccuracy();
                float f1 = location1.getAccuracy();
                if(f >= f1) 
                    long l = location1.getTime();
                    long l1 = location.getTime();
                    if(l - l1 <= 600000L)
                        continue;
                
            
            location = location1;
            i = locationmanager.isProviderEnabled(s);
         while (true);
        return location;
    

这没有给我任何位置....而且我的应用程序也没有崩溃或给出任何异常。

我已经在 Manifest 文件中正确注册了所有权限... ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION

我找不到该怎么办? 任何帮助将不胜感激 在此先感谢您的帮助...

【问题讨论】:

toasts 是否显示“网络提供商”或“GPS 提供商”? 是的!当我运行应用程序时,会显示所有 3 个祝酒词。但是,没有一个提供商将数据存储在我的数据库中。 尝试只启用一个,最好是网络提供商之一并检查。 我尝试只使用网络提供商,但没有任何反应 在得到任何东西之前不要移除监听器,看我的回答 【参考方案1】:
    //Use this class in your project:

    package com.example.location;

    import android.app.AlertDialog;
    import android.app.Service;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.location.Location;
    import android.location.LocationListener;
    import android.location.LocationManager;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.provider.Settings;
    import android.util.Log;

    public class LocationTracker extends Service implements LocationListener 

        private final Context mContext;

        // flag for GPS status
        boolean isGPSEnabled = false;

        // flag for network status
        boolean isNetworkEnabled = false;

        // flag for GPS status
        boolean canGetLocation = false;

        Location location; // location
        double latitude; // latitude
        double longitude; // longitude

        // The minimum distance to change Updates in meters
        private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

        // The minimum time between updates in milliseconds
        private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

        // Declaring a Location Manager
        protected LocationManager locationManager;

        public LocationTracker(Context context) 
            this.mContext = context;
            getLocation();
        

        public Location getLocation() 
            try 
                locationManager = (LocationManager) mContext
                        .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;
                    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);
                            if (location != null) 
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            
                        
                    
                    // 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);
                                if (location != null) 
                                    latitude = location.getLatitude();
                                    longitude = location.getLongitude();
                                
                            
                        
                    
                

             catch (Exception e) 
                e.printStackTrace();
                Log.i("Error", e.getMessage());
            

            return location;
        

        /**
         * Stop using GPS listener
         * Calling this function will stop using GPS in your app
         * */
        public void stopUsingGPS()
            if(locationManager != null)
                locationManager.removeUpdates(LocationTracker.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
         * @return boolean
         * */
        public boolean canGetLocation() 
            return this.canGetLocation;
        

        @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;
        

    

    //and in your main class(Activity), call this class as follows :
    double latitude = 0.0, longitude = 0.0;
    Geocoder geocoder = new Geocoder(this,Locale.getDefault());

    LocationTracker locationTracker = new LocationTracker(this);

        if(locationTracker.canGetLocation()) 

            latitude = locationTracker.getLatitude();
            longitude = locationTracker.getLongitude();
            Log.i("LocationTracker", "LatLong: " + latitude + ", " + longitude);                

            try
                List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);

                if (addresses.size() >  0) 

                    String address = addresses.get(0).getAddressLine(0);
                    String city = addresses.get(0).getAddressLine(1);
                    String country = addresses.get(0).getAddressLine(2);
                    String completeAddress = address + ", " + city + ", "+country;                      

                    Log.i("Complete Address", completeAddress);

                
            
            catch (Exception e)
                Log.i("Error", e.getMessage());
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
            
        
        else 
            Log.i("LocationTracker", "Unable to get location");
        

        // Make sure to include following permissions in your manifest file:

        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.INTERNET"/>

【讨论】:

工作中...谢谢,但是,我想每 10 分钟后调用一次此服务。那么,这在您的代码中是否可行。如果可能的话,请告诉我! @KasimRangwala 您可以通过更改 LocationTracker.java 中的 MIN_TIME_BW_UPDATES 值来更改时间间隔。然后,定位服务将在您提供的时间间隔内获取位置更新。【参考方案2】:

我认为您的问题是您立即删除了侦听器:

locManager.removeUpdates(locationListener); // comment this one out

getMyCurrentLocation();

你应该尝试在其他一些地方移除你的监听器。

【讨论】:

你是对的!删除 locManager.removeUpdates(locationListener);它工作正常!我的数据库中也有纬度和经度...但是,问题是应用程序仍然显示所有 3 个供应商 toast!所以,很难确定我从哪个供应商获得位置?

以上是关于无法在后台服务中使用 LocationManager 获取位置的主要内容,如果未能解决你的问题,请参考以下文章

Android:isProviderEnabled(LocationManager.NETWORK_PROVIDER) 不起作用。只有 isProviderEnabled(LocationManage

在 ionic 3 中使用后台地理位置无法将位置数据更新到服务器中

NSURLSession:无法与后台传输服务通信

无法在后台服务中将数据发送到Firebase

基于位置的应用程序无法在后台 iPhone 中运行

使用通知服务扩展振动 iphone 7,但它在后台无法与 iOS 12.1 一起使用