简体   繁体   English

位置侦听器来自服务,但不是IntentService

[英]Location listener works from a Service but not an IntentService

I have an app where I am trying to periodically get user location and send to server. 我有一个应用程序,我试图定期获取用户位置并发送到服务器。 I have a service attached to an AlarmManager which executes every minute (for testing). 我有一个连接到AlarmManager的服务,它每分钟执行一次(用于测试)。 The service finds the user location correctly and logs out the GPS co-ords. 该服务正确找到用户位置并注销GPS协议。 Once there is a GPS lock I cancel the location request and stop the service. 一旦有GPS锁定,我就取消位置请求并停止服务。 When I ask for location updates, I start a Handler that executes 20 seconds later, this Handler removes the location update and stops the Service in case no lock is achieved. 当我要求更新位置时,我启动一个20秒后执行的Handler ,此Handler删除位置更新并在没有锁定的情况下停止Service All this works. 这一切都有效。

Below is the code that works using the Service class. 下面是使用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 

The problem I am having is once I have a GPS lock, I want to send the long and lat co-ords to the server. 我遇到的问题是,一旦我有GPS锁定,我想将长和lat发送到服务器。 I know I can use AsyncTask from a Service but I don't want to do this. 我知道我可以从Service使用AsyncTask ,但我不想这样做。 I would prefer to use IntentService as it runs in its own background thread. 我更喜欢使用IntentService因为它在自己的后台线程中运行。 This way I can make network call directly from the IntentService . 这样我就可以直接从IntentService进行网络调用。

The following code implements the IntentService class but it doesn't seem to get a lock. 以下代码实现了IntentService类,但它似乎没有锁定。 The GPS keeps flashing on the phone indefinitely. GPS不断闪烁在手机上。 The logging statements get as far as 'requesting location updates', then nothing after that. 日志记录语句到“请求位置更新”,然后没有任何内容。

Has anyone any ideas why no lock is achieved? 有没有人知道为什么没有锁定? Thanks in advance. 提前致谢。

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] [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] [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] [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

As Pankaj Kumar notes, an IntentService is not an appropriate solution for cases where the work to be done is intrinsically asynchronous. 正如Pankaj Kumar指出的那样,对于要完成的工作本质上是异步的情况, IntentService不是一个合适的解决方案。 Once onHandleIntent() returns, your service is destroyed. 一旦onHandleIntent()返回,您的服务就会被销毁。

Use a regular Service , register for locations in onStartCommand() , using a HandlerThread for processing the results (so you can pass its Looper into requestLocationUpdates() ). 使用常规Service ,在onStartCommand()注册位置,使用HandlerThread处理结果(这样您就可以将其Looper传递给requestLocationUpdates() )。 Once your location is received, or a suitable timeout is reached, do your work and call stopSelf() on the service to shut it down. 收到您的位置或达到合适的超时后,请执行您的工作并在服务上调用stopSelf()以将其关闭。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM