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

Я хочу, чтобы обновления местоположения отправлялись на сервер каждые 15 минут до временного интервала с телефона android на сервер. Лучшим вариантом является служба или диспетчер аварийных сигналов.

Если я запустил службу, могу ли я запустить асинтекс для отправки сообщений на сервер.?

Вот код, который я использовал:

@Override public void onStart(Intent intent, int startId) { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); listener = new MyLocationListener(); locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 4000, 0, listener); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener); } public class MyLocationListener implements LocationListener { public void onLocationChanged(final Location loc) { Log.i("**************************************", "Location changed"); if (isBetterLocation(loc, previousBestLocation)) { loc.getLatitude(); loc.getLongitude(); // // intent.putExtra("Latitude", loc.getLatitude()); // intent.putExtra("Longitude", loc.getLongitude()); // intent.putExtra("Provider", loc.getProvider()); // // sendBroadcast(intent); } } public void onProviderDisabled(String provider) { Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show(); } public void onProviderEnabled(String provider) { Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show(); } public void onStatusChanged(String provider, int status, Bundle extras) { } } } 

Я не знаю, как запустить службу фона каждые пятнадцать минут интервала. Я хочу начать aysnctask, когда я получаю свежие обновления местоположения. Лучшим вариантом является служба или диспетчер аварийных сигналов. Если я запустил службу, могу ли я запустить асинтекс для отправки сообщений на сервер.?

Обновленный ответ

Старый ответ не будет работать для приложений с таргетингом M или выше, потому что статический подключаемый приемник больше не будет получать трансляции .

Теперь лучшим вариантом является FusedLocationApi , который входит в состав Служб Google Play.

 compile 'com.google.android.gms:play-services-location:[version_here]' 

Создание обновлений местоположения IntentService

 /** * Handles location updates from FusedLocationProvider */ public final class LocationUpdateService extends IntentService { private static final String TAG = "LocationUpdateService"; public static final String ACTION_HANDLE_LOCATION = "ACTION_HANDLE_LOCATION"; public LocationUpdateService() { super(TAG); } @Override protected void onHandleIntent(final Intent intent) { if (intent != null) { final String action = intent.getAction(); if (action != null) { switch (action) { case ACTION_HANDLE_LOCATION: onActionHandleLocation(intent); break; default: Log.w(TAG, "onHandleIntent(), unhandled action: " + action); break; } } } } private void onActionHandleLocation(@NonNull final Intent intent) { if (!LocationResult.hasResult(intent)) { Log.w(TAG, "No location result in supplied intent"); return; } final LocationResult locationResult = LocationResult.extractResult(intent); if (locationResult == null) { Log.w(TAG, "LocationResult is null in supplied intent"); return; } // TODO send to server using a blocking request. // Remember that this is the background thread already } } 

Не забудьте добавить его в тег приложения Manifest

 <service android:name=".LocationUpdateService"/> 

Запросите разрешение на местоположение, подключитесь к GoogleApiClient, и теперь вы можете сделать следующее

 @NonNull private static PendingIntent createLocationServiceIntent(@NonNull final Context context) { final Intent intent = new Intent(context, LocationUpdateService.class); intent.setAction(LocationUpdateService.ACTION_HANDLE_LOCATION); return PendingIntent.getService(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); } public static void scheduleLocationUpdates(@NonNull final Context context, @NonNull final GoogleApiClient googleApiClient) { // Make sure you have permission, request if necessary if (googleApiClient.isConnected() && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) // ACCESS_COARSE_LOCATION, depending on what you want == PackageManager.PERMISSION_GRANTED) { LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, LocationRequest.create().setInterval(AlarmManager.INTERVAL_FIFTEEN_MINUTES), createLocationServiceIntent(context)); } } public static void unscheduleLocationUpdates(@NonNull final Context context, @NonNull final GoogleApiClient googleApiClient) { if (googleApiClient.isConnected()) { LocationServices.FusedLocationApi .removeLocationUpdates(googleApiClient, createLocationServiceIntent(context)); } } 

Старый ответ

AsyncTask предназначен для коротких фоновых операций, в основном, когда вы ожидаете в пользовательском интерфейсе. В этом случае вам лучше начать сервис с WakeLock . Но имейте в виду, что вы, вероятно, будете стекать батареи, делая это каждые 15 минут . Подумайте о том, чтобы не планировать аварийные сигналы, когда устройство не подключено к сети.

1) Зарегистрируйте статический BroadcastReceiver в манифесте, чтобы контролировать, подключено ли устройство. Действие Intent для сетевых событий в android sdk

2) Когда устройство подключается к Интернету, а места разрешены, запустите службу, которая будет содержать WakeLock, прослушивает одно обновление местоположения, отменяет регистрацию обновлений местоположения, отправляет местоположение на сервер, планирует AlarmManager , освобождает WakeLock и cals stopSelf (); Рассмотрите тайм-аут, если обновления местоположения не отправляются. Если достигнут тайм-аут, отмените регистрацию обновлений местоположения, зарегистрируйте следующий сигнал тревоги, освободите WakeLock и вызовите stopSelf.

3) Если вы получаете сеть, отключенную в приемнике, отмените все сигналы и остановите службу, если она запущена.

Пример кода для шага 2 по запросу

 public final class ConnectivityReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); final PendingIntent wakeupIntent = PendingIntent.getService(context, 0, new Intent(context, LocationUpdaterService.class), PendingIntent.FLAG_UPDATE_CURRENT); final boolean hasNetwork = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); if (hasNetwork) { // start service now for doing once context.startService(new Intent(context, LocationUpdaterService.class)); // schedule service for every 15 minutes alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_FIFTEEN_MINUTES, AlarmManager.INTERVAL_FIFTEEN_MINUTES, wakeupIntent); } else { alarmManager.cancel(wakeupIntent); } } } public final class LocationUpdaterService extends Service implements LocationListener { private enum State { IDLE, WORKING; } private static State state; private LocationManager locationManager; private WakeLock wakeLock; static { state = State.IDLE; } @Override public void onCreate() { super.onCreate(); final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "LocationUpdaterService"); } @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (state == State.IDLE) { state = State.WORKING; this.wakeLock.acquire(); // register location updates, not gonna code it you know } return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); state = State.IDLE; if (this.wakeLock.isHeld()) { this.wakeLock.release(); } } private void sendToServer(Location location) { // send to server in background thread. you might want to start AsyncTask here } private void onSendingFinished() { // call this after sending finished to stop the service this.stopSelf(); //stopSelf will call onDestroy and the WakeLock releases. //Be sure to call this after everything is done (handle exceptions and other stuff) so you release a wakeLock //or you will end up draining battery like hell } @Override public void onLocationChanged(Location location) { locationManager.removeUpdates(this); // you will want to listen for updates only once sendToServer(location); } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } } 

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