Intereting Posts

Слушатель мест работает с Сервисом, но не с IntentService

У меня есть приложение, где я пытаюсь периодически получать местоположение пользователя и отправлять его на сервер. У меня есть служба, AlarmManager с AlarmManager которая выполняется каждую минуту (для тестирования). Служба правильно находит местоположение пользователя и выводит координаты GPS. Когда есть блокировка GPS, я отменяю запрос местоположения и останавливаю службу. Когда я запрашиваю обновления местоположения, я запускаю Handler который выполняется через 20 секунд, этот Handler удаляет обновление местоположения и останавливает Service в случае, если блокировка не достигнута. Все это работает.

Ниже приведен код, который работает с использованием класса Service .

 public class TrackingService extends Service { private static final String TAG = TrackingService.class.getSimpleName(); LocationManager mlocManager; LocationListener mlocListener; NfcScannerApplication nfcscannerapplication; String carerID; Handler endServiceHandler; Runnable endServiceRunnable; @Override public void onCreate() { super.onCreate(); nfcscannerapplication = (NfcScannerApplication) getApplication(); mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); mlocListener = new MyLocationListener(); Log.e(TAG, "Service created and location manager and listener created"); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "in onDestroy in LocationService class"); mlocManager.removeUpdates(mlocListener); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener); Log.e(TAG, "requesting location updates"); enableMenuButtonsHandler(); endServiceHandler.postDelayed(endServiceRunnable,20 * 1000); } @Override public IBinder onBind(Intent intent) { return null; } private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { Log.e(TAG, "in TrackingService onlocationChanged and about to send lon/lat " + loc.getLongitude() + " " + loc.getLatitude()); DateTime dt = new DateTime(); DateTimeFormatter df3 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS"); String formattedNowTime3 = df3.print(dt); Log.e(TAG, "Time of location fix in TrackingServive = " + formattedNowTime3); Cursor c = nfcscannerapplication.loginValidate.queryAllFromCarer(); if (c.getCount() > 0) { if(c.moveToLast()){ carerID = c.getString(c.getColumnIndex(LoginValidate.C_CARER_ID)); } } Log.e(TAG, "carer ID = " + carerID); mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService)"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService"); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } }// end of MyLocationListener public void enableMenuButtonsHandler() { endServiceHandler = new Handler(); endServiceRunnable = new Runnable() { public void run() { endService(); } private void endService() { mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService) from the endService handler"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService from the endService handler"); } }; } }// end of service 

Проблема, с которой я столкнулась, – это когда у меня есть блокировка GPS, я хочу отправить на сервер длинные и лат-координаты. Я знаю, что я могу использовать AsyncTask из Service но я не хочу этого делать. Я бы предпочел использовать IntentService поскольку он работает в своем фоновом потоке. Таким образом, я могу выполнить сетевой вызов непосредственно из IntentService .

Следующий код реализует класс IntentService но он, похоже, не получает блокировку. GPS продолжает мигать на телефоне на неопределенный срок. Операторы протоколирования доходят до «запроса обновлений местоположения», после чего ничего не происходит.

Есть ли у кого-нибудь идеи, почему нет блокировки? Заранее спасибо.

 public class TrackingService extends IntentService { private static final String TAG = TrackingService.class.getSimpleName(); LocationManager mlocManager; LocationListener mlocListener; NfcScannerApplication nfcscannerapplication; String carerID; Handler endServiceHandler; Runnable endServiceRunnable; public TrackingService() { super("TrackingService"); } @Override protected void onHandleIntent(Intent intent) { nfcscannerapplication = (NfcScannerApplication) getApplication(); mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); mlocListener = new MyLocationListener(); Log.e(TAG, "Service created and location manager and listener created"); mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener); Log.e(TAG, "requesting location updates"); enableMenuButtonsHandler(); endServiceHandler.postDelayed(endServiceRunnable,20 * 1000); } private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { Log.e(TAG, "in TrackingService onlocationChanged and about to send lon/lat " + loc.getLongitude() + " " + loc.getLatitude()); DateTime dt = new DateTime(); DateTimeFormatter df3 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS"); String formattedNowTime3 = df3.print(dt); Log.e(TAG, "Time of location fix in TrackingServive = " + formattedNowTime3); Cursor c = nfcscannerapplication.loginValidate.queryAllFromCarer(); if (c.getCount() > 0) { if(c.moveToLast()){ carerID = c.getString(c.getColumnIndex(LoginValidate.C_CARER_ID)); } } Log.e(TAG, "carer ID = " + carerID); mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService)"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService"); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } }// end of MyLocationListener public void enableMenuButtonsHandler() { endServiceHandler = new Handler(); endServiceRunnable = new Runnable() { public void run() { endService(); } private void endService() { mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService) from the endService handler"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService from the endService handler"); } }; } }//end of trackingService 

[Edit1]

 public class TrackingService extends Service { private static final String TAG = TrackingService.class.getSimpleName(); LocationManager mlocManager; LocationListener mlocListener; NfcScannerApplication nfcscannerapplication; String carerID; Handler endServiceHandler; Runnable endServiceRunnable; @Override public int onStartCommand(Intent intent, int flags, int startId) { nfcscannerapplication = (NfcScannerApplication) getApplication(); mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); mlocListener = new MyLocationListener(); Log.e(TAG, "Service created and location manager and listener created"); mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener); Log.e(TAG, "requesting location updates"); enableMenuButtonsHandler(); endServiceHandler.postDelayed(endServiceRunnable, 20 * 1000); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "in onDestroy in LocationService class"); mlocManager.removeUpdates(mlocListener); } @Override public IBinder onBind(Intent intent) { return null; } private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { Log.e(TAG, "in TrackingService onlocationChanged and about to send lon/lat " + loc.getLongitude() + " " + loc.getLatitude()); DateTime dt = new DateTime(); DateTimeFormatter df3 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS"); String formattedNowTime3 = df3.print(dt); Log.e(TAG, "Time of location fix in TrackingServive = " + formattedNowTime3); Cursor c = nfcscannerapplication.loginValidate.queryAllFromCarer(); if (c.getCount() > 0) { if(c.moveToLast()){ carerID = c.getString(c.getColumnIndex(LoginValidate.C_CARER_ID)); } } Log.e(TAG, "carer ID = " + carerID); mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService)"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService"); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } }// end of MyLocationListener public void enableMenuButtonsHandler() { endServiceHandler = new Handler(); endServiceRunnable = new Runnable() { public void run() { endService(); } private void endService() { mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService) from the endService handler"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService from the endService handler"); } }; } }// end of service 

[Edit2]

 @Override public int onStartCommand(Intent intent, int flags, int startId) { nfcscannerapplication = (NfcScannerApplication) getApplication(); mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); mlocListener = new MyLocationListener(); Log.e(TAG, "Service created and location manager and listener created"); HandlerThread handlerThread = new HandlerThread("MyHandlerThread"); handlerThread.start(); Looper looper = handlerThread.getLooper(); Handler handler = new Handler(looper); mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener, looper); Log.e(TAG, "requesting location updates"); enableMenuButtonsHandler(); endServiceHandler.postDelayed(endServiceRunnable, 20 * 1000); return super.onStartCommand(intent, flags, startId); } 

[Edit3]

 public class TrackingService extends Service { private static final String TAG = TrackingService.class.getSimpleName(); LocationManager mlocManager; LocationListener mlocListener; NfcScannerApplication nfcscannerapplication; String carerID; Handler endServiceHandler; Runnable endServiceRunnable; HandlerThread handlerThread; Looper looper; @Override public int onStartCommand(Intent intent, int flags, int startId) { nfcscannerapplication = (NfcScannerApplication) getApplication(); mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); mlocListener = new MyLocationListener(); Log.e(TAG, "Service created and location manager and listener created"); Log.e(TAG, "creating handlerthread and looper"); handlerThread = new HandlerThread("MyHandlerThread"); handlerThread.start(); looper = handlerThread.getLooper(); mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener, looper); Log.e(TAG, "requesting location updates"); enableMenuButtonsHandler(); endServiceHandler.postDelayed(endServiceRunnable, 20 * 1000); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "in onDestroy in LocationService class"); mlocManager.removeUpdates(mlocListener); } @Override public IBinder onBind(Intent intent) { return null; } private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { Log.e(TAG, "in TrackingService onlocationChanged and about to send lon/lat " + loc.getLongitude() + " " + loc.getLatitude()); DateTime dt = new DateTime(); DateTimeFormatter df3 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS"); String formattedNowTime3 = df3.print(dt); Log.e(TAG, "Time of location fix in TrackingServive = " + formattedNowTime3); Cursor c = nfcscannerapplication.loginValidate.queryAllFromCarer(); if (c.getCount() > 0) { if(c.moveToLast()){ carerID = c.getString(c.getColumnIndex(LoginValidate.C_CARER_ID)); } } Log.e(TAG, "carer ID = " + carerID); nfcscannerapplication.loginWebservice.sendCarerLocation(carerID, formattedNowTime3, String.valueOf(loc.getLatitude()), String.valueOf(loc.getLongitude())); Log.e(TAG, "quiting handlerthread"); handlerThread.quit(); mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService)"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService"); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } }// end of MyLocationListener public void enableMenuButtonsHandler() { endServiceHandler = new Handler(); endServiceRunnable = new Runnable() { public void run() { endService(); } private void endService() { mlocManager.removeUpdates(mlocListener); Log.e(TAG, "removed updates(TrackingService) from the endService handler"); TrackingService.this.stopSelf(); Log.e(TAG, "called stopSelf on TrackingService from the endService handler"); Log.e(TAG, "quiting handlerthread from the endService handler"); handlerThread.quit(); } }; } }// end of service 

Как отмечает Панкадж Кумар, IntentService не является подходящим решением для случаев, когда выполняемая работа внутренне асинхронна. Как только onHandleIntent() вернется, ваш сервис будет уничтожен.

Используйте регулярную Service , зарегистрируйтесь для местоположений в onStartCommand() , используя HandlerThread для обработки результатов (чтобы вы могли передать ее Looper в requestLocationUpdates() ). Как только ваше местоположение будет получено или будет достигнут подходящий тайм-аут, выполните свою работу и вызовите stopSelf() в службе, чтобы закрыть его.