Java – play location service getlastlocation returns null
I'm trying to listen to location changes, but sometimes the onlocationchanged callback is never called, getlastlocation returns null, and Google Maps always works perfectly
be careful
If I restart the device, the location service will only work for about 2 days; Later, when Google maps is still valid, neither my application nor the SDK example will work properly
This is my service code:
public class VisitService extends Service implements GooglePlayServicesClient.ConnectionCallbacks,GooglePlayServicesClient.OnConnectionFailedListener,LocationListener { private final IBinder mBinder = new VisitBinder(); // A request to connect to Location Services private LocationRequest mLocationRequest; // Stores the current instantiation of the location client in this object private LocationClient mLocationClient; private boolean mLocationServiceConnected = false; @Override public int onStartCommand(Intent intent,int flags,int startId) { initLocation(); return super.onStartCommand(intent,flags,startId); } @Override public IBinder onBind(Intent intent) { initLocation(); return mBinder; } public void startVisit() { if (!servicesConnected()) { listener.onVisitStartError(); return; } if (mLocationServiceConnected) { if (isAcceptableLocation(mLocationClient.getLastLocation())) { Toast.makeText(this,"You have arrived!",Toast.LENGTH_LONG); } else { mVisitListener.onVisitStartError(); } } } private boolean isAcceptableLocation(Location location) { if (location == null) { Toast.makeText(this,"Location is null",Toast.LENGTH_LONG).show(); return false; } return true; } private void initLocation() { if (mLocationRequest == null) { // Create a new global location parameters object mLocationRequest = LocationRequest.create(); /* * Set the update interval */ mLocationRequest .setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS); // Use high accuracy mLocationRequest .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Set the interval ceiling to one minute mLocationRequest .setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS); } if (mLocationClient == null) { mLocationClient = new LocationClient(this,this,this); mLocationClient.connect(); } } /** * Verify that Google Play services is available before making a request. * * @return true if Google Play services is available,otherwise false */ private boolean servicesConnected() { // Check that Google Play services is available int resultCode = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { // In debug mode,log the status Log.d(LocationUtils.APPTAG,getString(R.string.play_services_available)); return true; } else { return false; } } public class VisitBinder extends Binder { public VisitService getService() { return VisitService.this; } } /** * In response to a request to start updates,send a request to Location * Services */ private void startPeriodicUpdates() { mLocationClient.requestLocationUpdates(mLocationRequest,this); Toast.makeText(this,"Location Update Requested",Toast.LENGTH_LONG).show(); } /** * In response to a request to stop updates,send a request to Location * Services */ private void stopPeriodicUpdates() { mLocationClient.removeLocationUpdates(this); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(LocationUtils.APPTAG,"Location Services Connection faild"); } @Override public void onConnected(Bundle bundle) { Log.d(LocationUtils.APPTAG,"Location Services Connected"); mLocationServiceConnected = true; startPeriodicUpdates(); } @Override public void onDisconnected() { mLocationServiceConnected = false; } @Override public void onLocationChanged(Location location) { Toast.makeText(this,"Location has been changed",Toast.LENGTH_LONG).show(); } }
Android Manifest
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Solution
The first is a bug I also encountered this problem
You can try a simple solution
Request location update before trying to get the last location, that is, request location update before trying to find the last location using getlastlocation();
Like:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); Criteria crta = new Criteria(); crta.setAccuracy(Criteria.ACCURACY_FINE); crta.setAltituderequired(true); crta.setBearingrequired(true); crta.setCostAllowed(true); crta.setPowerRequirement(Criteria.POWER_LOW); String provider = locationManager.getBestProvider(crta,true); Log.d("","provider : "+provider); // String provider = LocationManager.GPS_PROVIDER; locationManager.requestLocationUpdates(provider,1000,locationListener); Location location = locationManager.getLastKNownLocation(provider);
This implementation is based on locationmanager Please select a location client
Hope to help you!
UPDATE
You can also use the onlocationchanged () method here, because it will update you every time you change the location, and the getlastlocation () method returns the best known location that may be null
According to Doc, the getlastlocation () method will return null in rare cases But this often happens to me
Latest updates
Guys, there's only one update about GPS:
First, we need to use the Google API client instead of the locationclient class
Secondly, we need to implement Google API client ConnectionCallbacks,GoogleApiClient. OnConnectionFailedListener
Third, we need to override its onconnected (), onconnectionsuspended () and onconnectionfailed () methods
You'll be glad to go
Cheers!