Not getting latitude and longitude from background

2019-06-08 18:47发布

问题:

I am new in android I want to run a service in background and get latitude and longitude or Geo address after 10 minutes and send to the server.

Please help me.

Here is my code:

In Activity

public void serviceCall(){
  Log.e("INSIDE ALARM", "INSIDE ALARM");
  Intent intent = new Intent(getApplicationContext(), MyService.class);
  final PendingIntent pIntent = PendingIntent.getBroadcast(this, MyService.REQUEST_CODE,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
  long firstMillis = System.currentTimeMillis();
  AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
  alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
                6000, pIntent);
}

in Reciver

public static final int REQUEST_CODE = 9411;

@Override
public void onReceive(Context context, Intent intent) {
  Intent inti = new Intent(context, LocationService.class);
  intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NEW_TASK);
  context.startService(inti);
}

in IntentService

protected void onHandleIntent(Intent intent) {
  Log.e("imsidehandler Service", ":=");
  mRequestingLocationUpdates = false;
  buildGoogleApiClient();
  createLocationRequest();
  buildLocationSettingsRequest();
  checkLocationSettings();
  sendDataServer();
}

public void onConnected(Bundle bundle) {
  if (mCurrentLocation == null) {
     mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
     mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
     updateLocationUI();
  }
}

public void onConnectionSuspended(int i) {

}

public void onLocationChanged(Location location) {
  mCurrentLocation = location;
  mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
}

public void onConnectionFailed(ConnectionResult connectionResult) {

}

private synchronized void buildGoogleApiClient() {
  mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

private void createLocationRequest() {
  mLocationRequest = new LocationRequest();
  mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
  mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
  mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}

private void buildLocationSettingsRequest() {
  LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
  builder.addLocationRequest(mLocationRequest);
  mLocationSettingsRequest = builder.build();
}

private void checkLocationSettings() {
  PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(
                    mGoogleApiClient,
                    mLocationSettingsRequest
            );
  result.setResultCallback(this);
}

protected boolean startLocationUpdates() {
  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 true;
  }

  return false;
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) this).setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(Status status) {
            mRequestingLocationUpdates = false;
        }
    });
}

private void updateLocationUI() {
  if (mCurrentLocation != null) {
    updateCityAndPincode(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());

  }
}

private void updateCityAndPincode(double latitude, double longitude) {
  try {
     Log.e("latitude","==>"+longitude);
     Log.e("longitude","==>"+longitude);
     this.latitude = latitude;
     this.longitude = longitude;
     getGeoAddress(latitude, longitude);
  } catch (Exception e) {
  }

}

private void getGeoAddress(Double latitude, Double longitude) {
  Geocoder geocoder = new Geocoder(this, Locale.getDefault());
  String result = null;
  List<Address> addressList = null;
  try {
     addressList = geocoder.getFromLocation(
                latitude, longitude, 1);

      if (addressList != null && addressList.size() > 0) {
         Address address = addressList.get(0);
         Log.e("address","==>"+address);
         for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
            result += address.getAddressLine(i);
            result += " ";
         }
         if (result.contains("null")) {
            result1 = result.replace("null", "");
         }
       }
    } catch (IOException e) {
        e.printStackTrace();
    }
  }

  public void onResult(LocationSettingsResult locationSettingsResult) {
    final Status status = locationSettingsResult.getStatus();
    switch (status.getStatusCode()) {
        case LocationSettingsStatusCodes.SUCCESS:

            startLocationUpdates();

            break;
        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
            try {
                status.startResolutionForResult((Activity) getApplicationContext(), REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException e) {
            }
            break;
        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
            break;

    }
}

please help me

回答1:

The getLastLocation() method just gets the last known location that the device happens to know. Sometimes the device does not "happen to know" its location and null is returned.

The device doesn't determine its location on its own, but only when some application request the location. So your app is now dependent on other applications requesting location updates.

Also the "last known location" here means exactly that: It may not be up-to-date. Locations do come with a time stamp which could be used to asses if the location might still be relevant.

I don't see a call to requestLocationUpdates() anywhere in your code. That would request up-to-date location updates at an interval which you can specify.

Your onConnected() method could have:

public void onConnected(Bundle bundle) {    
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

(The getLastLocation() call can be deleted.)

And your IntentService could implement LocationListener and do the same things as onConnected() now does, but only after a location update has arrived:

@Override
public void onLocationChanged(Location location) {
    // Cancel the updates after the first one:
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

    mCurrentLocation = location;
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    updateLocationUI();

}

This would be the way to request and process location updates with the smallest code changes.

Of course there are also other ways like requesting the updates every 10 minutes and processing them via a PendingIntent. There's this version of requestLocationUpdates() that takes a PendingIntent:

public abstract PendingResult<Status> requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callbackIntent)

That would replace your current timer mechanism.