【问题标题】:Update interval value for continuous GPS location更新连续 GPS 位置的间隔值
【发布时间】:2013-03-14 12:24:12
【问题描述】:

我正在开发一个应该以固定间隔更新位置的 BlackBerry 应用程序。可以从滑块选择/更改间隔值。它在 1 分钟、2 分钟、5 分钟、30 分钟等之间变化。在第一次加载(启动应用程序)时,定位间隔为 30 秒。之后,我将滑块值存储在持久存储中,并根据设置的间隔相应地更新位置。后台线程运行更新位置如下:

private boolean startLocationUpdate()
{
    boolean retval = false;
    try
    {
        LocationProvider locationProvider = LocationProvider.getInstance(null);
        if ( locationProvider == null )
        {
            Runnable showGpsUnsupportedDialog = new Runnable()
            {
                public void run()
                {
                    Dialog.alert("GPS is not supported on this platform, exiting...");
                    //System.exit( 1 );
                }
            };
            UiApplication.getUiApplication().invokeAndWait( showGpsUnsupportedDialog ); // Ask event-dispatcher thread to display dialog ASAP.
        }
        else
        {
            locationProvider.setLocationListener(new LocationListenerImpl(), interval, -1, -1);
            retval = true;
        }
    }
    catch (LocationException le)
    {
        System.err.println("Failed to instantiate the LocationProvider object, exiting...");
        System.err.println(le);
        System.exit(0);
    }
    return retval;
}

private class LocationListenerImpl implements LocationListener
{
    public void locationUpdated(LocationProvider provider, Location location)
    {
        if(location.isValid())
        {
            double longitude = location.getQualifiedCoordinates().getLongitude();
            double latitude = location.getQualifiedCoordinates().getLatitude();
            updateLocationScreen(latitude, longitude);
        }
    }
    public void providerStateChanged(LocationProvider provider, int newState)
    {
    }
}

private void updateLocationScreen(final double latitude, final double longitude)
{
    UiApplication.getUiApplication().invokeAndWait(new Runnable()
    {
        public void run()
        {
            double lat = latitude;
            double longi = longitude;
            lblLatitude.setText(Double.toString(lat));
            spacing.setText(", ");
            lblLongitude.setText(Double.toString(longi));
        }
    });
}  

除此之外,还有一个可用的“刷新”按钮,一旦单击该按钮就会立即开始获取位置更新。这个按钮调用一个方法是另一个类来获取位置。方法如下:

try {
    Criteria myCriteria = new Criteria();
    myCriteria.setCostAllowed(false);
    LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
    double heading = 0;
    double velocity = 0;

    try {
        Location myLocation = myLocationProvider.getLocation(6000);
        if(myLocation.isValid())
        {
            double longitude = myLocation.getQualifiedCoordinates().getLongitude();
            double latitude = myLocation.getQualifiedCoordinates().getLatitude();
        }
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                //Dialog.alert("Location Updated");
            }
        });
        setLocation(myLocation.getQualifiedCoordinates(),velocity,heading);
    } catch ( InterruptedException iex ) {
        System.out.println(iex.getMessage());
    } catch ( LocationException lex ) {
        System.out.println(lex.getMessage());
    }
} catch ( LocationException lex ) {
    System.out.println(lex.getMessage());
}

我面临的问题:

1) 间隔值不变。我通过从持久存储中选择值来实现更改:

if (PersistentStoreHelper.persistentHashtable.containsKey("gpsInterval"))
{
    String intervalValue=((String) PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
    MyScreen.interval=Integer.parseInt(intervalValue);
}

这永远不会为空,因为导航到此页面会插入一个 30 分钟的值。

2) 点击“刷新”按钮后,后台线程似乎被取消了。它不再以任何间隔值运行。

我读到只创建了一个位置提供程序实例,并且使用“刷新”它在获取位置后被取消,因此后台线程停止。 这是真的吗?如果是,我怎样才能达到我想要的结果。

编辑:gpsInterval 值读取如下:

if (PersistentStoreHelper.persistentHashtable.containsKey("gpsInterval"))
{
    String intervalValue=((String)PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
    interval=Integer.parseInt(intervalValue);
}
else
{
    interval=10;
}

【问题讨论】:

  • 几个问题:1) 你确定你正确地将gpsInterval 保存到持久存储中吗?您不显示该代码,仅显示读取它的代码。也许你没有在商店里打电话给commit()? 2)您显示将MyScreen.interval 设置为新值的代码。但仅仅设置该值本身不会改变任何东西。据我所知,该值用于startLocationUpdate() 方法。在用户使用滑块更改间隔后,您是否确保再次致电startLocationUpdate()
  • @Nate 感谢您的回复。 1)是的,我确定该值正在保存,因为我在调试时可以看到它。我已经编辑了我的问题以包含我用来读取值的代码。不过,我没有调用 commit()。这应该在哪里调用? 2) 我不再调用 startLocationUpdate() 方法。我的假设是 startLocationUpdate() 线程始终以选定的时间间隔在后台运行。不是这样吗?请帮忙。

标签: blackberry gps location location-provider


【解决方案1】:

保存间隔

因此,首先,请确保当您通过滑块让用户更改更新间隔时,将其正确保存到PersistentStore。代码应如下所示:

// NOTE: I would recommend persisting the slider value as an Integer, not a String,
//   but, the original code used String, so that's what this uses
hashtable.put("gpsInterval", (new Integer(intervalSlider.getValue())).toString());
PersistentObject po = PersistentStore.getPersistentObject(APP_BUNDLE_ID);
po.setContents(hashtable);
po.commit();

由于您没有发布该代码,我只是想确保它已正确保存到持久存储中。

更新位置提供者/监听器

的另一个问题是您使用以下代码在startLocationUpdate() 中启动位置更新:

locationProvider.setLocationListener(new LocationListenerImpl(), interval, -1, -1);

这使用了interval 变量在调用setLocationListener() 时的值。如果您稍后更新 interval 变量,

String intervalValue=((String) PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
MyScreen.interval=Integer.parseInt(intervalValue);

这对位置监听器没有影响。它将使用 original 间隔值不断更新,而不是新的。您必须再次调用setLocationListener(),新值interval。使用您的代码,您可能应该再次调用startLocationUpdate()

String intervalValue=((String) PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
MyScreen.interval=Integer.parseInt(intervalValue);
startLocationUpdate();

刷新问题

我不是 100% 确定,但我的猜测是,在按下 Refresh 按钮时使用的现有代码中,您正在 更改 到不同的LocationProvider 具有不同的标准。这可能是第一个被取消的原因。

尝试将您的startLocationUpdate() 方法更改为保存提供程序作为成员变量:

/** this is the one location provider used by this class! */
private LocationProvider _locationProvider;

private boolean startLocationUpdate()
{
    boolean retval = false;
    try
    {
        _locationProvider = LocationProvider.getInstance(null);

然后,在您的刷新代码中,使用 same 位置提供程序来获取当前位置:

double heading = 0;
double velocity = 0;

try {
    Location myLocation = _locationProvider.getLocation(6000);
    if(myLocation.isValid())

注意:如果你真的想setCostAllowed(false),那很好。在您分配_locationProvider 成员变量的第一次 时执行此操作。并将该提供程序/标准用于正常的定期位置更新和您的 Refresh 按钮处理程序。我认为关键是使用相同的提供者,而不是创建具有不同标准的新提供者。

【讨论】:

  • 感谢@Nate,非常详细的答案。考虑到我调用了另一个方法,例如 startLocationUpdate1() 而不是我提供新间隔的 startLocationUpdate(),这个调用会取消旧的 StartLocaionUpdate() 吗?类似于刷新按钮的东西会取消其他 LocationProvider...
  • @Sarah,是的,如果您阅读setLocationListener() 上的文档,您会看到设置监听器会删除旧监听器(可能有不同的interval)。因此,如果您有另一种方法再次调用setLocationListener(),那应该可以。我仍然建议不要使用setLocationUpdate()setLocationUpdate1()。只需制作一种将(int updateInterval) 作为参数的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
  • 2013-03-25
相关资源
最近更新 更多