java - 每 5 分钟生成一个位置

标签 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 公里后)时才收到。

最佳答案

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

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

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

关于java - 每 5 分钟生成一个位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14612670/

相关文章:

java - JSoup:从元素获取文本时出现问题

android - 通过 Gmail 中的超链接发送地理 URI 不起作用

android - Maven 使用带有 ADT 的 Android 库项目

c# - 如何在不使用 Unity 协程的情况下在主线程上运行函数

Java/野蝇: Threads piling up/Eclipse shows one additional running thread for each request

java - jaxb 生成的 ObjectFactory 方法

java - 根据请求体中的数据转发http请求

java - 使用适用于 Cloudant DB 的 CloudantClient java API 时出现 HttpHostConnectException

当背景颜色为白色时,Android 通知图标颜色不会改变

c++ - tbb矩阵乘法栈溢出错误c++