更新连续GPS位置的间隔值

时间:2013-03-14 12:24:12

标签: blackberry gps location location-provider

我正在开发一个应用程序,它应该以固定的时间间隔更新位置。可以从滑块选择/更改间隔值。它在1分钟,2分钟,5分钟,30分钟等之间变化。在第一次加载(Start App)时,位置间隔为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 个答案:

答案 0 :(得分: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);

这对位置监听器没有影响。它将继续使用原始间隔值进行更新,而不是新值。您必须使用新值setLocationListener()再次致电interval。使用您的代码,您可能应该再次致电startLocationUpdate()

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

刷新问题

我不是百分百肯定,但我的猜测是,在按下刷新按钮时使用的现有代码中,您更改为不同的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);

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

double heading = 0;
double velocity = 0;

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

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