0

我正在开发一个应该以固定间隔更新位置的 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;
}
4

1 回答 1

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

刷新问题

我不是 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);

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

double heading = 0;
double velocity = 0;

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

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

于 2013-03-17T08:41:38.247 回答