1

我正在尝试创建一个应用程序,每 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 公里后)..

4

2 回答 2

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 语句组合成一个共同的主题。我不太确定它从哪里获取位置/新位置,如果它们是线程安全的,你可能应该为它们获取函数,加分。sendTask另外,这可能是关键,如果没有有效位置,您总是在执行,我怀疑这是您的关键错误。尝试用以下代码替换该代码:

if (location!=null 
    && ((location.getAccuracy() > newLocation.getAccuracy() + 100)
    && newLocation.distanceTo(location) > 1800)
{
    sendTask();
}
于 2013-01-30T20:17:14.250 回答
1

You have so much IF statements and so few elses, this make your bugs almost impossible to solve. First of all, you should write those else branches and put some kind of logger too, in order to know what is your code doing (since it's definitely not doing what you think it should do).

This way, you will be able to tell what the problem is:

  • No location.
  • Not enough accuracy.
  • Different location with same address.
  • ...
于 2013-01-30T20:28:08.013 回答