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)「更新」ボタンをクリックすると、バックグラウンドスレッドがキャンセルされたように見えます。間隔値で実行されなくなりました。

作成されたロケーションプロバイダーのインスタンスは1つだけであり、「更新」を使用すると、ロケーションの取得後にキャンセルされ、バックグラウンドスレッドが停止することを読みました。これは本当ですか?はいの場合、どうすれば希望の結果を達成できますか。

編集: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();

そのコードを投稿しなかったので、永続ストアに正しく保存されていることを確認したかっただけです。

ロケーションプロバイダー/リスナーの更新

もう1つの問題、つまり問題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%確信はありませんが、 [更新]ボタンが押されたときに使用される既存のコードでは、異なる基準で別のコードに変更していると思います。それがおそらく最初のものがキャンセルされる理由です。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 に答える