android - 位置监听器从服务工作,但不是 IntentService

标签 android service gps location intentservice

我有一个应用程序,我试图定期获取用户位置并发送到服务器。我有一个附加到 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 锁定,我想将经纬度坐标发送到服务器。我知道我可以使用 Service 中的 AsyncTask,但我不想这样做。我更愿意使用 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

[编辑1]

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 

[编辑2]

@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);
    }

[编辑3]

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

最佳答案

正如 Pankaj Kumar 指出的那样,IntentService 对于要完成的工作本质上是异步的情况来说不是合适的解决方案。一旦 onHandleIntent() 返回,您的服务就会被销毁。

使用常规 Service,在 onStartCommand() 中注册位置,使用 HandlerThread 处理结果(这样您就可以通过它Looper 进入 requestLocationUpdates())。收到您的位置信息或达到合适的超时时间后,执行您的工作并调用服务上的 stopSelf() 将其关闭。

关于android - 位置监听器从服务工作,但不是 IntentService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19978939/

相关文章:

java - 如何使用匿名身份验证将数据保存到Android中的Firestore数据库?

android - 尝试在空对象引用上调用虚拟方法 ' '

android - Android 位置管理器的实用程序

android - 如何每 5 秒将 Android GPS 坐标发送到 MySQL

iphone - 在 iOS4 上运行的 iPhone 4 或 3GS 上可以进行后台 GPS\位置记录吗

android - 如何在字段上启用规则的情况下在 MongoDB 缝合中插入文档

java - 跳转返回null

grails - 如何注入(inject)与 grails 中的任何域类无关的自定义服务?

javascript - 为什么我的输入变量属性未定义( Angular )

c# - System.Timers.Timer timer1_Elapsed 未触发!帮助!