1

细节:

我有一项服务需要执行以下操作: - 不断监听 GPS 位置,以 50 米作为参数(工作正常)并将其发送到服务器 - 每 60 秒,如果没有读取 GPS 位置,开始监听网络位置并将其发送到服务器

这听起来可能很奇怪,但这是项目要求。因此,用户一直在使用 GPS 进行跟踪。当他停下来,或 GPS 未锁定,或在建筑物内时,每 60 秒开始一次快速的网络位置读取,并将此位置发送到服务器。由于该服务使用与主应用程序相同的线程,因此每个服务器更新都在其自己的线程中完成。另一个重要的事情是:每个位置读取应该一个接一个地发送,例如,如果用户正在开车,并且完成了多次读取,则每个位置都应该在前一个发送之后发送到服务器。这就是我决定使用 ScheduledExecutorService 的原因,因为我可以提交线程并且它们将一个接一个地执行。

这是代码:

private ScheduledExecutorService scheduleTaskExecutor;
Handler locationHandler = new Handler();
private Location lastNetworkLocation;

@Override
    public void onStartCommand() {
        scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();

        //prepare to execute Network reading every 60 seconds
        scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                    initNetworkReadings();

                    //usually a network location read is done almost instantly
                    //however after 5 seconds I check if a location has been read by the Network listener inside the locationRunnable
                    locationHandler.postDelayed(locationRunnable, 5000);
                } 

            }
        }, 60, 60, TimeUnit.SECONDS);

        locationRunnable = new Runnable() {
            @Override
            public void run() {
                    if (lastNetworkLocation !=null){
                         //send location to the server if valid
                    }
            lastNetworkLocation = null;
            }
        }
    }

    private void initNetworkReadings() {
        locationManager.removeUpdates(locationListenerNetwork);
        try {
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
        }

        if (isGpsEnabled) {
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        }
    }

    LocationListener locationListenerNetwork = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        lastNetworkLocation = location;
        // stop listening for Network locations
        locationManager.removeUpdates(locationListenerNetwork);
    }
    ...
    }

每次我读取 GPS 位置时,我都会将其添加到线程队列中:

scheduleTaskExecutor.submit(new Runnable() {
        @Override
        public void run() {
            updateLocationOnServer(readLocation);
        }
    });

我遇到的问题是网络位置侦听器永远不会被onLocationChanged()调用,当我像上面的代码一样在 Runnable 中使用它时。但是,如果我添加服务启动,initNetworkReadings()我会onLocationChanged()立即被解雇。所以我相信它与在 scheduleAtFixedRate 中使用有关。你认为这可能是什么问题?我对工作流程的看法有什么不好吗?

4

2 回答 2

1

如果您尝试使用 Handler 和 Runnable 而不是 scheduleAtFixedRate() 来设置 repitition 会怎样?

Handler h = new Handler();
Runnable run = new Runnable(){
    //Do your repeititive work here!
    h.postDelayed(run, 60 * 1000);
};
h.post(run);
于 2012-11-28T14:31:04.727 回答
0

同样的问题,我有一个检测位置的后台服务。如果网络可用,则使用网络,否则使用 gps。

它适用于许多智能手机(nexus s 4.1、galaxy nexus 4.2、galaxy note),但使用 Galaxy s3 jb (4.1) 网络位置永远不会上升任何位置。

与 gps 位置相同的代码,工作得很好。

于 2012-11-30T11:34:01.770 回答