Получить последнее местоположение от FusedLocation в сервисе

Я пытаюсь getLastLocation() в моей службе, ведьма запускается каждую минуту. Как я вижу, fusedLocation требует Activity или же Executor в .addOnSuccessListener(), Как я могу получить это в Сервисе?

LocationCheckService.class

public class LocationCheckService extends Service{

    private FusedLocationProviderClient mFusedLocationClient;

    @Override
    public void onCreate() {
        super.onCreate();
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {

                        }
                    }
                });
    }

    @SuppressLint("MissingPermission")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_STICKY;
    }

2 ответа

Вам не нужен GoogleApiClient -

первый в Gradle добавить -

implementation 'com.google.android.gms:play-services-location:15.0.0'

В манифесте Android -

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

чем создать сервис, чтобы получить обновление местоположения как -

public class LocationUpdateService extends Service {

    private FusedLocationProviderClient client;
    private LocationRequest locationRequest;


    @Override
    public void onCreate() {
        super.onCreate();
        client = LocationServices.getFusedLocationProviderClient(this);
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(0);
        locationRequest.setFastestInterval(0);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
            client.requestLocationUpdates(locationRequest, locationCallback, null);
        } catch (SecurityException ignore) {
            Log.e("AppLocationService", "SecurityException - " + ignore.toString(), ignore);
        }
        return START_STICKY;
    }

    private final LocationCallback locationCallback = new LocationCallback() {

        @Override
        public void onLocationResult(LocationResult locationResult) {
            List<Location> locationList = locationResult.getLocations();
            if (locationList.size() != 0) {
                Location location = locationList.get(0);
                Log.e("AppLocationService", "Latitude  - " +location.getLatitude()+", longitude  - " +location.getLongitude() );
            }
        }
    };


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return null;
    }


}

Чтобы получать обновления в деятельности, вы можете использовать LocalBroadCast ИЛИ тот же код, который вы можете использовать в деятельности

ПРИМЕЧАНИЕ: не забудьте взять разрешение выше 23

Я предоставляю один отдельный класс для выборки данных о местоположении, используя faused API. Вы можете вызвать этот класс в свой сервис, он получает последние значения местоположения lat и long.

public class GPSController  implements
    LocationListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener{

OnLocationUpdateListener onLocationUpdateListener;
public final String TAG = getClass().getSimpleName();

private FusedLocationProviderApi fusedLocationProviderApi =    LocationServices.FusedLocationApi;
GoogleApiClient googleApiClient;
LocationRequest mLocationRequest;
Location mCurrentLocation;
private static long INTERVAL = 1000 * 10;
private static long FASTEST_INTERVAL = 1000 * 5;
FragmentActivity mActivity;
private boolean isLiveUpdate = false;


PendingResult<LocationSettingsResult> result;


/**
 * Checking permission and connect with Google Location service
 * @param activity
 */
public GPSController(FragmentActivity activity) {

    this.mActivity = activity;
    if(PermissionManager.checkPermission(mActivity,PermissionManager.ACCESS_LOCATION))
    {
        if (!isGooglePlayServicesAvailable()) {
            CustomLogHandler.printInfolog("checking googleplayservice : ", "false");
            ((BaseActivity)mActivity).showAlertDialog(mActivity, mActivity.getString(R.string.app_name), mActivity.getString(R.string.play_service_not_found));
        } else {
            CustomLogHandler.printInfolog("checking googleplayservice : ", "true");
            createLocationRequest();
            initFuseAPI();

        }
    }
    else
    {
        PermissionManager.askForPermission(PermissionManager.ACCESS_LOCATION,mActivity);
    }

}

public void connectForLocation()
{
    createLocationRequest();
    initFuseAPI();
}

/**
 * Turn on Live update of location on given interval
 * @param value
 * @param INTERVAL
 * @param FASTEST_INTERVAL
 */
public void turnOnLiveUpdate(boolean value,long INTERVAL,long FASTEST_INTERVAL)
{
    isLiveUpdate = value;
    this.INTERVAL = INTERVAL;
    this.FASTEST_INTERVAL = FASTEST_INTERVAL;
}

/**
 * Turn off live update of location
 */
public void turnOffLiveUpdate()
{
    isLiveUpdate = false;
}

/**
 * Disconnect from Google location service
 */
public void disconnect()
{
    try {
        Log.d(TAG, "onStop fired ..............");
        googleApiClient.disconnect();
        Log.d(TAG, "isConnected ...............: " +googleApiClient.isConnected());
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}

/**
 * Resume Location update service if stopped
 */
public void onResumeUpdate()
{
    try {
        if(googleApiClient != null) {
            if (googleApiClient.isConnected()) {
                startLocationUpdates();
                Log.d(TAG, "Location update resumed .....................");
            }
        }
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}


public void setLocatonUpdateListener(OnLocationUpdateListener onLocationUpdateListener)
{
    this.onLocationUpdateListener  = onLocationUpdateListener;
}

/**
 * Create location update request
 */
protected void createLocationRequest() {
    try {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}


/**
 * Initialize google location service
 */
void initFuseAPI()
{
    try
    {
        googleApiClient = new GoogleApiClient.Builder(mActivity)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        Log.d(TAG, "initFuseAPI fired ..............");
        googleApiClient.connect();
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}


/**
 * Check Google location service is available or not
 * @return
 */
private boolean isGooglePlayServicesAvailable() {
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mActivity);
    if (ConnectionResult.SUCCESS == status) {
        return true;
    } else {
        GooglePlayServicesUtil.getErrorDialog(status, mActivity, 0).show();
        return false;
    }
}

/**
 * called when connected with google location service
 * @param bundle
 */
@Override
public void onConnected( Bundle bundle) {
    Log.d(TAG, "onConnected - isConnected ...............: " + googleApiClient.isConnected());
    LocationManager manager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE );
    boolean statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if(statusOfGPS) {
        startLocationUpdates();
    }else
    {
        enableGpsService();
    }
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed( ConnectionResult connectionResult) {

}

/**
 * Location update received here
 * @param location
 */
@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "Firing onLocationChanged..............................................");
    mCurrentLocation = location;
    SetLocation();
}


void enableGpsService()
{
    try
    {
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);
        builder.setAlwaysShow(true);
        result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult( LocationSettingsResult locationSettingsResult) {
                final Status status = locationSettingsResult.getStatus();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        //already connected to GPS
                        startLocationUpdates();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by
                        // showing the user a dialog.
                        try {
                            status.startResolutionForResult(mActivity, PermissionManager.REQUEST_LOCATION);
                            startLocationUpdates();
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        //redirect user to setting screen, manually user can enble GPS
                        mActivity.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                        break;
                }
            }
        });
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}





/**
 * Request location update service
 */
public void startLocationUpdates()
{
    try {
        //check required even you checked it previously
        if (PermissionManager.checkPermission(mActivity, PermissionManager.ACCESS_LOCATION))
        {
            fusedLocationProviderApi.requestLocationUpdates(googleApiClient, mLocationRequest, this);
            Log.d(TAG, "Location update started ..............: ");
        } else {
            PermissionManager.askForPermission(PermissionManager.ACCESS_LOCATION, mActivity);
        }
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}

/**
 * Stop location update
 */
public void stopLocationUpdates() {
    try {
        if(googleApiClient != null) {
            fusedLocationProviderApi.removeLocationUpdates(
                    googleApiClient, this);
            Log.d(TAG, "Location update stopped .......................");
        }
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}


/**
 * set location values received
 */
private void SetLocation()
{
    try {
        Log.d(TAG, "UI update initiated .............");
        if (null != mCurrentLocation) {
            onLocationUpdateListener.onLocationUpdate(mCurrentLocation);

            /**isLiveUpdate = true for Live update **/

            if (!isLiveUpdate) {
                fusedLocationProviderApi.removeLocationUpdates(googleApiClient,this);
            }
            googleApiClient.disconnect();

            //mCurrentLocation.getAccuracy()
            //mCurrentLocation.getProvider()

        } else {
            Log.d(TAG, "location is null ...............");
        }
    }catch (Throwable throwable)
    {
        throwable.printStackTrace();
    }
}

public Location getLocation(){
    return mCurrentLocation;
}
public static List<Address> getAddress(Double mLat, Double mLang, Context context)
{
    List<Address> addresses = null;
    try
    {
        Geocoder geocoder = new Geocoder(context, Locale.getDefault());
        addresses = geocoder.getFromLocation(mLat, mLang, 1);
    }catch (Exception e)
    {
        e.printStackTrace();
    }
    return  addresses;
}

/**
 * For receive location update
 */
public interface OnLocationUpdateListener {
     void onLocationUpdate(Location mCurrentLocation);
}

}

позвоните в этот класс обслуживания, как это..

    gpsController = new GPSController(getActivity());
    gpsController.setLocatonUpdateListener(this);
    if (gpsController != null)
        gpsController.onResumeUpdate();

    public void setLocatonUpdateListener(OnLocationUpdateListener onLocationUpdateListener) {
    this.onLocationUpdateListener = onLocationUpdateListener;
}

а также реализовать это в классе..

implements GPSController.OnLocationUpdateListener

@Override
public void onLocationUpdate(Location mCurrentLocation) {
    CURRENT_LET = String.valueOf(mCurrentLocation.getLatitude());// both string variable to store value
    CURRENT_LANG = String.valueOf(mCurrentLocation.getLongitude());

}

Эта реализация в Java работает в классе обслуживания после инициализации fusedLocationClient:

fusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
            @Override
            public void onComplete(@NonNull Task<Location> task) {
                Location last_known_loction = task.getResult();
                latitude = last_known_loction.getLatitude();
                longitude = last_known_loction.getLongitude();
            }
        });
Другие вопросы по тегам