【问题标题】:In Android ,how to receive GPS location continuously?在Android中,如何连续接收GPS位置?
【发布时间】:2018-02-17 00:00:48
【问题描述】:

android.location.LocationListener 的位置监听器 onLocationChanged() 函数中的问题。

在下面的代码中请求 LocationManager 的 requestLocationUpdates 后,onLocationChanged 以不均匀的间隔被调用,即我将周期设置为 1 秒,但每秒后我没有收到位置更改。

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

@SuppressWarnings("MissingPermission")
public class SimplePositionProvider extends PositionProvider implements LocationListener {

public SimplePositionProvider(Context context, PositionListener listener) {
super(context, listener);

Log.i("SimplePositionProvider", "start");
if (!type.equals(LocationManager.NETWORK_PROVIDER)) {
type = LocationManager.GPS_PROVIDER;
}

}

public void startUpdates() {
Log.i("startUpdates", "start");
try {
Log.i("requestLocationUpdates", "start");
Log.i("TYPE", type);
locationManager.requestLocationUpdates(type, period, 0, this);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "error");
}
}

public void stopUpdates() {
Log.i("stopUpdates", "start");
locationManager.removeUpdates(this);
}

@Override
public void onLocationChanged(Location location) {
Log.i("onLocationChanged", "start");
updateLocation(location);
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i("onStatusChanged", "start");
}

@Override
public void onProviderEnabled(String provider) {
Log.i("onProviderEnabled", "start");
}

@Override
public void onProviderDisabled(String provider) {
Log.i("onProviderDisabled", "start");
}

}

【问题讨论】:

  • 创建定位服务以连续获取位置

标签: android performance gps android-gps


【解决方案1】:

根据tutorial,您应该使用FusedLocationProviderClient 来请求位置更新。如果没有记忆,该解决方案会以指定的时间间隔发送更新。您可以通过调用LocationServices.getFusedLocationProviderClient(Context context) 获得FusedLocationProviderClient

您可以在LocationRequestsetExpirationDuration 中设置请求过期持续时间,然后在每次过期后重新启动更新时使用类似以下代码:

Handler handler = new Handler(Looper.myLooper());
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
      if (expectingLocationUpdates) {
        restartLocationUpdates();
      }
    }
}, EXPIRATION_DURATION);

【讨论】:

    【解决方案2】:
    public class CustomLocationService extends Service implements LocationListener {
    
    
    private static final Location TODO = null;
    boolean isGPSEnabled = false;
    boolean isNetworkEnabled = false;
    public boolean canGetLocation = false;
    
    Location location;
    
    double latitude;
    double longitude;
    
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0;
    private static final long MIN_TIME_BW_UPDATES = 10000 * 60 * 1;
    private CommonSharedPreference commonSharedPreference = new CommonSharedPreference();
    
    protected LocationManager locationManager;
    private long time;
    Context context;
    
    
    @Override
    public void onCreate() {
        super.onCreate();
        context = this;
    
        time = MIN_TIME_BW_UPDATES;
        getLocation();
    
    }
    
    @Override
    public void onStart(Intent intent, int startId) {
        getLocation();
    }
    
    @Override
    public void onDestroy() {
        // handler.removeCallbacks(sendUpdatesToUI);
        super.onDestroy();
        Log.v("STOP_SERVICE", "DONE");
        locationManager.removeUpdates(GPSTracker.this);
    }
    
    public Location getLocation() {
        try {
            locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
    
            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
            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) {
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        return TODO;
                    }
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    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);
                        if (locationManager != null) {
                            location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return location;
    }
    
    
    public void stopUsingGPS() {
        if(locationManager != null) {
            locationManager.removeUpdates(GPSTracker.this);
        }
    }
    
    public double getLatitude() {
        if(location != null) {
            latitude = location.getLatitude();
        }
        return latitude;
    }
    
    public double getLongitude() {
        if(location != null) {
            longitude = location.getLongitude();
        }
    
        return longitude;
    }
    
    public boolean canGetLocation() {
        return this.canGetLocation;
    }
    
    
    @Override
    public void onLocationChanged(Location arg0) {
        // TODO Auto-generated method stub
    }
    
    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onProviderEnabled(String arg0) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
    

    }

    【讨论】:

    • 您好,首先感谢您的代码,但我的问题不是没有收到位置,而是始终没有得到它们!您正在使用 locationManager 的最后一个已知位置,我们被要求不要使用,我们希望以 30 秒为间隔获取当前位置
    • 一旦服务成为明星,onLocationChanged 将在给定的时间间隔内为您提供当前位置
    【解决方案3】:

    According to the documentation,您使用的period 参数是位置更新之间的最小间隔。如果您想在定位系统更新时尽快获取位置,请将period 设置为零。

    【讨论】:

    • 谢谢,但我们面临的问题是,位置接收不稳定,一段时间后断开连接。在模拟器中连续接收位置没有问题。
    • @BonnySebastian 您应该重新提出您的问题。这似乎不是它要问的。
    【解决方案4】:

    使用这个类..

        public class MyLocationService extends Service {
        private static final String TAG = "MyLocationService";
        private LocationManager mLocationManager = null;
        private static final int LOCATION_INTERVAL = 1000 * 30;;
        private static final float LOCATION_DISTANCE = 0f;
    
    
        private final IBinder serviceBinder = new MyLocationService.RunServiceBinder();
    
        public MyLocationService() {
        }
    
        LocationListener[] mLocationListeners = new LocationListener[]{
                new LocationListener(LocationManager.GPS_PROVIDER),
    
        };
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.e(TAG, "onStartCommand");
            super.onStartCommand(intent, flags, startId);
            return START_STICKY;
        }
    
        @Override
        public void onCreate() {
    
            Log.e(TAG, "onCreate");
    
            initializeLocationManager();
    
         /*   try {
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                        mLocationListeners[1]);
            } catch (java.lang.SecurityException ex) {
                Log.i(TAG, "fail to request location update, ignore", ex);
            } catch (IllegalArgumentException ex) {
                Log.d(TAG, "network provider does not exist, " + ex.getMessage());
            }*/
    
    
    
            try {
                mLocationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                        mLocationListeners[0]);
            } catch (java.lang.SecurityException ex) {
                Log.i(TAG, "fail to request location update, ignore", ex);
            } catch (IllegalArgumentException ex) {
                Log.d(TAG, "gps provider does not exist " + ex.getMessage());
            }
        }
    
        @Override
        public void onDestroy() {
            Log.e(TAG, "onDestroy");
            super.onDestroy();
            if (mLocationManager != null) {
                for (int i = 0; i < mLocationListeners.length; i++) {
                    try {
                        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                            return;
                        }
                        mLocationManager.removeUpdates(mLocationListeners[i]);
                    } catch (Exception ex) {
                        Log.i(TAG, "fail to remove location listener, ignore", ex);
                    }
                }
            }
        }
    
        private void removeUpdate(){
            if (mLocationManager != null) {
                for (int i = 0; i < mLocationListeners.length; i++) {
                    try {
                        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                            return;
                        }
                        mLocationManager.removeUpdates(mLocationListeners[i]);
                    } catch (Exception ex) {
                        Log.i(TAG, "fail to remove location listener, ignore", ex);
                    }
                }
            }
        }
    
        private void initializeLocationManager() {
            Log.e(TAG, "initializeLocationManager - LOCATION_INTERVAL: " + LOCATION_INTERVAL + " LOCATION_DISTANCE: " + LOCATION_DISTANCE);
            if (mLocationManager == null) {
                mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
            }
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            //   throw new UnsupportedOperationException("Not yet implemented");
            return null;
        }
    
        public class RunServiceBinder extends Binder {
            public MyLocationService getService() {
                return MyLocationService.this;
            }
        }
    
    
        private class LocationListener implements android.location.LocationListener {
            Location mLastLocation;
    
            public LocationListener(String provider) {
                Log.e(TAG, "LocationListener " + provider);
              //  Toast.makeText(MyLocationService.this, ""+provider, Toast.LENGTH_SHORT).show();
                mLastLocation = new Location(provider);
            }
    
            @Override
            public void onLocationChanged(Location location) {
                Log.e(TAG, "onLocationChanged: " + location);
               // Toast.makeText(MyLocationService.this, ""+"checked", Toast.LENGTH_SHORT).show();
                mLastLocation.set(location);
    
            }
    
            @Override
            public void onProviderDisabled(String provider) {
                Log.e(TAG, "onProviderDisabled: " + provider);
            }
    
            @Override
            public void onProviderEnabled(String provider) {
                Log.e(TAG, "onProviderEnabled: " + provider);
            }
    
            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                Log.e(TAG, "onStatusChanged: " + provider);
            }
        }
    
    
    }
    

    【讨论】:

    • 放置在我的玻璃桌子上时启动和停止需要时间(与我上面的代码相同)
    猜你喜欢
    • 2019-03-26
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2013-05-06
    相关资源
    最近更新 更多