每5分钟生成一个位置

时间:2013-01-30 20:03:44

标签: java android multithreading timer geolocation

我正在尝试创建一个应用程序,每隔5分钟将用户的位置发送到数据库,之后用户将能够看到它。限制很少:

  • 如果用户没有移动,请勿生成其他位置。我这样做是通过检查到当前位置的新位置距离是否超过1800M(我只使用精确度低于900的位置,因此可能的位置数量为1800)。

  • 如果我可以根据当前位置的准确度获得更好的位置,请使用它。

所以我现在将提供我的代码,我想知道你对它的看法以及是否可以做得更好,因为它不能很好地工作。如果你想要一个明确的问题:忽略我的代码,我该如何实现我提到的那两点。

以下是代码:

public void onStart(Intent intent, int startId) 
{
    ...
    this.timer.scheduleAtFixedRate(new Send(), d1, TEN_MINUTES/2);
}
...
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, TEN_MINUTES/2, 0, listener);

if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) 
    mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, TEN_MINUTES/2, 0, listener);
...
@Override
public void onLocationChanged(Location location) 
{
    handleLocation(location);
}
private void handleLocation(Location location) 
{
    if(isUsable(location))
    {
        this.isUsable = true;
        this.newLocation = location;
    }
}
public boolean isUsable(Location location)
{
    if (mGeocoderAvailable) 
    {
        this.address = reverseGeocode(location);
        return location.hasAccuracy() && location.getAccuracy() < 900 && !this.address.equals("");
    }
    return false;
}

class Send extends TimerTask
{
    boolean run = true;

    @SuppressWarnings("deprecation")
    public void run()
    {
        if(isUsable)
        {
            isUsable = false;
            if(newLocation != null)
            {
                if(location != null)
                {
                    if(location.getAccuracy() > newLocation.getAccuracy() + 100)
                        sendTask();
                    else
                        if(newLocation.distanceTo(location) > 1800)
                            sendTask();
                }
                else
                    sendTask();
            }
        }
    }
}

最重要的代码当然是Send类和定义约束的isUsable方法。

弹出的错误是重复相同的地址,不应该是因为这个条件应该涵盖这种情况:

if(newLocation.distanceTo(location) > 1800)

另一件事是我用我的手机驾驶我的车20公里,我的数据库中没有收到任何位置,只有当我完成驾驶(20公里后)时..

2 个答案:

答案 0 :(得分:1)

首先,您可能希望有一个可变的不确定性要求。

其次,这是启动计时器的命令。

public void onStart(Intent intent, int startId) 
{
    ...
    this.timer.scheduleAtFixedRate(new Send(), d1, TEN_MINUTES/2);
}

此命令不正确。在将其发送到计时器之前,您可能还想创建一个Send实例。

this.timer.scheduleAtFixedRate(new Send(), d1, 5, TimeUnits.MINUTES);

在您开始使用该应用程序之前,我建议您在测试环境中更频繁地测试它的关键部分。将时间设置为每10秒,并检查以确保它正常工作,数学正确,报告位置等。

最后,您的添加方法是:

if(newLocation != null)
{
    if(location != null)
    {
        if(location.getAccuracy() > newLocation.getAccuracy() + 100)
            sendTask();
        else
            if(newLocation.distanceTo(location) > 1800)
                sendTask();
    }
    else
        sendTask();
}

首先,在这种情况下你不应该使用else,你应该把所有的if语句组合成一个共同的主题。我不太确定它从哪里获取location / newLocation,你应该可以为它们获取函数,如果它们是线程安全的话可以获得奖励积分。此外,这可能是关键,如果没有有效的位置,你总是执行sendTask,我怀疑这是你的关键错误。尝试用以下代码替换该代码:

if (location!=null 
    && ((location.getAccuracy() > newLocation.getAccuracy() + 100)
    && newLocation.distanceTo(location) > 1800)
{
    sendTask();
}

答案 1 :(得分:1)

你有如此多的IF语句和如此少的缺点,这使得你的bug几乎无法解决。首先,您应该编写其他分支并添加某种记录器,以便知道您的代码在做什么(因为它肯定没有按照您认为的那样做)。

通过这种方式,您将能够分辨出问题所在:

  • 没有位置。
  • 准确度不够。
  • 具有相同地址的不同位置。
  • ...