1

ユーザーの場所を 5 分ごとにデータベースに送信するアプリケーションを作成しようとしています。その後、ユーザーはそれを見ることができます。いくつかの制約があります:

  • ユーザーが移動していない場合は、別の場所を生成しないでください。現在の場所までの新しい場所の距離が 1800M を超えているかどうかを確認することでこれを行います (精度が 900 未満の場所のみを使用するため、可能性のある場所の半径は 1800 です)。

  • 現在地の精度に基づいてより良い位置情報を取得できる場合は、それを使用します。

だから私は今私のコードを提供します.それについてどう思うか、そしてそれが完全に機能していないのでもっとうまくできるかどうか知りたいです. 明確な質問が必要な場合:私のコードを無視してください。私が言及した2つのポイントをどのように実装すればよいですか。

コードは次のとおりです。

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)

もう 1 つのことは、携帯電話で車を 20 km 運転しましたが、運転を終了したとき (20 km 後) にのみ、データベースに位置情報が表示されませんでした。

4

2 に答える 2

1

まず第一に、おそらく可変の不確実性要件が必要です。

次に、タイマーを開始するコマンドを次に示します。

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 ステートメントを 1 つの共通テーマに結合する必要があります。location/newLocation がどこから取得されているかはよくわかりません。スレッドセーフであれば、それらに関数を取得する必要があります。ボーナスポイントです。また、これはおそらく重要sendTaskです。有効な場所がない場合は常に実行されています。それが重要なバグだと思います。そのコードを次のコードに置き換えてみてください。

if (location!=null 
    && ((location.getAccuracy() > newLocation.getAccuracy() + 100)
    && newLocation.distanceTo(location) > 1800)
{
    sendTask();
}
于 2013-01-30T20:17:14.250 に答える
1

IF ステートメントが非常に多く、それ以外はほとんどないため、バグを解決することはほとんど不可能です。まず第一に、あなたのコードが何をしているのかを知るために、他のブランチを書き、ある種のロガーも置くべきです (なぜなら、それはあなたがすべきだと思っていることを絶対にしていないからです)。

このようにして、問題が何であるかを知ることができます。

  • 場所がありません。
  • 十分な精度がありません。
  • 同じ住所の別の場所.
  • ...
于 2013-01-30T20:28:08.013 に答える