正在监听地理位置的不可阻挡的 Android 服务

Posted

技术标签:

【中文标题】正在监听地理位置的不可阻挡的 Android 服务【英文标题】:unstopable Android service which is listening geo location 【发布时间】:2012-04-04 12:08:23 【问题描述】:

我实现了用于监听用户位置的 android 服务:

public class ListenLocationService extends Service 
    IBinder mBinder = new LocalBinder();      
    public interface ILocationService      
          Location userLocation = new Location("");
          public void StartListenLocation();
          public void StopListenLocation();
          public Location getUserLocation();
        
    LocationManager locationManager;
    LocationListener locationListener;
    public class LocalBinder extends Binder implements ILocationService

        public void StopListenLocation()
            //so many attempts to stop service and no one helped
            locationManager.removeUpdates(locationListener);
            locationListener = null;
            stopSelf();
        

        public void StartListenLocation()
           
            locationManager = (LocationManager)ListenLocationService.this.getSystemService(Context.LOCATION_SERVICE);
            locationListener = new LocationListener() 

                public void onStatusChanged(String provider, int status, Bundle extras)                
                       

                public void onProviderEnabled(String provider)                      
                

                public void onProviderDisabled(String provider)                    
                

                public void onLocationChanged(Location location)                   
                    userLocation.set(location);
                
            ;
            //if I have only one requestLocationUpdates situation is the same

                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
                        400, 1, locationListener);
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
                        400, 1, locationListener);
            

        public Location getUserLocation()
            return userLocation;
        
    

    @Override
    public IBinder onBind(Intent intent) 
        return mBinder;
       


我在两个活动中绑定到此服务。在第一个活动中,我只是启动服务:

    private ServiceConnection mConnection = new ServiceConnection() 

        public void onServiceConnected(ComponentName className,
                IBinder service) 
            mService = (ILocationService) service; 
            mService.StartListenLocation();   
        

        public void onServiceDisconnected(ComponentName arg0) 
            Log.d("LOG","onServiceDisconnected");
        
    ;

    public void onCreate(Bundle savedInstanceState) 
...
        Intent intent = new Intent(this, ListenLocationService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
...

    @Override 
    public void onStop()
        super.onStop();
        unbindService(mConnection);
        mService.StopListenLocation();      
    

如果我在我的应用中仅启动第一个活动并关闭它然后服务停止 - GPS 标记从设备屏幕上消失。

但是,如果我进入第二个活动(我正在获取 userLocation)并在此之后关闭两者(使用 Android 后退按钮),那么 GPS 标记仍在我的屏幕上!

第二个活动的代码:

    private ServiceConnection mConnection = new ServiceConnection() 

        public void onServiceConnected(ComponentName className,
                IBinder service) 
            mService = (ILocationService) service;             
            userLocation = mService.getUserLocation();              
        

        public void onServiceDisconnected(ComponentName arg0) 
        
    ;

    @Override
    public void onCreate(Bundle savedInstanceState) 
...
    Intent intent = new Intent(this, ListenLocationService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
...

    @Override 
    public void onStop()
        super.onStop();
            unbindService(mConnection);
            mService.StopListenLocation();          

    

你可以看到我在两个 onStop() 方法中都写了 unbindService (最初我认为这就足够了),而且我正在使用以下代码调用 StopListenLocation 函数:

locationManager.removeUpdates(locationListener);
locationListener = null;
stopSelf();

如果只有第一个活动绑定到它,它会停止服务。但是,如果两个活动都被绑定,则服务不会在两个 onStop() 之后停止。我使用Log.d 来确保调用所有方法:onStop(), stopListenLocation(), onBind() 等。唯一的问题是永远不会调用onServiceDisconnected()

我想情况是我的服务启动了另一个系统服务来监听位置。我停止了我的服务,但是尽管有locationManager.removeUpdates(locationListener);,这个控制 GPS 的系统服务仍然可以工作。也许我的建议有误。

如何在两个活动都停止时停止 GPS?

【问题讨论】:

您确定服务仍在运行吗?在 bindService() 之后立即调用 unbindService() 将不会启动服务。如果是,那么您可能还有其他活动在其他地方绑定到服务。 我绝对确定该服务仍然有效,因为 GPS 标记出现在我的设备上并且仍然存在。除了我发布的这部分之外,我绝不会与服务交互。 尝试移动 unbindService(mConnection);调用 onServiceConnected() 并查看这是否正确地拆除了您正在运行的服务。 【参考方案1】:

BIND_AUTO_CREATE 并不一定意味着服务会在没有连接时自行终止,它只是意味着如果系统需要资源,它是第一件事。如果系统没有资源匮乏,它将让您的服务继续运行,因为如果您的活动再次需要该服务,则绑定到现有实例比从头开始创建它在时间上更便宜。

简而言之,它会继续“运行”,但不要担心 - 它不会消耗其他地方需要的任何东西。

编辑:还请注意,仅仅因为您未绑定服务并不意味着它将中断服务正在异步处理的任何正在运行的处理任务。所发生的只是你告诉操作系统你不再对结果感兴趣了。您必须在断开服务之前明确停止任何正在运行的任务,否则该任务将继续消耗 CPU 时间

【讨论】:

以上是关于正在监听地理位置的不可阻挡的 Android 服务的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重新启动服务器的情况下停止 Jenkins 上不可阻挡的僵尸作业?

看来人工智能不可阻挡,将和网络与计算机一样服务于各行各业!

北斗剑阵, 爬虫IP破封不可阻挡

位置为空融合位置提供者android

不可阻挡的脚本问题

停止位置侦听器服务 Android