Как создать фоновую службу с интервалом времени

В моем проекте мне нужно:

  1. Получите местоположение пользователя (широта и долгота).
  2. Отправьте его в мой API.
  3. Получите ответ.

Все это между 15 секундами. Я уже знаю, как это делать, но это должно быть фоном. Я использовал JobSchedule, который идеален и обрабатывает все: подключение, состояние сети и время, но проблема в том, что он несовместим со старыми версиями> 21! Лучшим подходом будет GCMNetworkManager в этих условиях (фоновый запрос и местоположение)? Спасибо!


person Nathiel Barros    schedule 04.08.2017    source источник
comment
Проверьте это: stackoverflow.com/questions/10420358/, см. последний ответ, это больше, чем вы хотите   -  person Vikrant    schedule 04.08.2017
comment
Для этой ссылки есть официальные образцы.   -  person santalu    schedule 04.08.2017


Ответы (1)


Вот как вы это делаете:

 <service
        android:name=".GeoLocationService"
        android:exported="false" />

Обслуживание:

import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;

public class GeoLocationService extends Service {

public static final String LOCATION_UPDATE = 
GeoLocationService.class.getSimpleName();
public static final String LOCATION_DATA = "location_data";

private static final String TAG = GeoLocationService.class.getSimpleName();
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 10000; // 30 Seconds
private static final float LOCATION_DISTANCE = 1f; // meters = 100 m

    public static void start(Context context) {
        context.startService(new Intent(context, GeoLocationService.class));
    }

    public static void stop(Context context) {
        context.stopService(new Intent(context, GeoLocationService.class));
    }

    private class LocationListener implements android.location.LocationListener {
        Location mLastLocation;

        public LocationListener(String provider) {
            mLastLocation = new Location(provider);
        }

        @Override
        public void onLocationChanged(Location location) {
            mLastLocation.set(location);

            Log.i(TAG, "Location Changed! " + location.getLatitude() + " " + location.getLongitude());
            Intent intent = new Intent(LOCATION_UPDATE);
            intent.putExtra(LOCATION_DATA, location);
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
        }

        @Override
        public void onProviderDisabled(String provider) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

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

    LocationListener[] mLocationListeners = new LocationListener[]{
            new LocationListener(LocationManager.GPS_PROVIDER),
            new LocationListener(LocationManager.NETWORK_PROVIDER)
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        initializeLocationManager();
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[1]);
        } catch (SecurityException ex) {

        } catch (IllegalArgumentException ex) {

        }
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[0]);
        } catch (SecurityException ex) {

        } catch (IllegalArgumentException ex) {

        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mLocationManager != null) {
            for (int i = 0; i < mLocationListeners.length; i++) {
                try {
                    if (checkLocationPermission()) {
                        mLocationManager.removeUpdates(mLocationListeners[i]);
                    }
                } catch (Exception ex) {

                }
            }
        }
    }

    private void initializeLocationManager() {
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
    }

    private boolean checkLocationPermission() {
        if (Build.VERSION.SDK_INT < 23)
            return true;

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            return false;
        }

        return ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    }
}

И в вашей деятельности:

private BroadcastReceiver mLocationUpdateMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Location location = intent.getParcelableExtra(GeoLocationService.LOCATION_DATA);
        //SEND LOCATION TO YOUR API HERE
    }
};

@Override
protected void onResume() {
    super.onResume();
    GeoLocationService.start(this);
    LocalBroadcastManager.getInstance(context).registerReceiver(mLocationUpdateMessageReceiver,
            new IntentFilter(GeoLocationService.LOCATION_UPDATE));
}


@Override
protected void onPause() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocationUpdateMessageReceiver);
    GeoLocationService.stop(this);
    super.onPause();
}
person Umair Adil    schedule 04.08.2017
comment
Я попытаюсь приспособиться к своей логике, потому что я использую FusedLocation вместо LocationManager! - person Nathiel Barros; 05.08.2017
comment
Я поменял и работает, единственная проблема, когда я звоню void stop, он не останавливает службу! - person Nathiel Barros; 05.08.2017