2

現在のユーザーの場所を取得しようとしています。より良い結果を得るためにコードをリファクタリングしようとしましたが、精度に関してばかげた場所を取得し続けています.900〜600メートルです.

精度を 50m 以内にするために、より良い結果を得るにはどうすればよいですか?

これが私のコードです:

package com.agam.mapslocation;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;

public class MapsActivity extends Activity {

    private static final int ONE_MINUTE = 1000 * 60 * 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        final LocationManager locationManager = (LocationManager) this
                .getSystemService(Context.LOCATION_SERVICE);

        final EditText et = (EditText) findViewById(R.id.editText1);

        // Define a listener that responds to location updates
        LocationListener locationListener = new LocationListener() {
            public void onLocationChanged(Location l) {
                // Called when a new location is found by the network location
                // provider.
                Location gps = locationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                Location net = locationManager
                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

                Location bestLocation = null;
                bestLocation = isBetterLocation(gps, net);
                bestLocation = isBetterLocation(bestLocation, l);
                if(bestLocation!=null)
                    displayLocation(et, bestLocation);
            }

            public void onStatusChanged(String provider, int status,
                    Bundle extras) {

            }

            public void onProviderEnabled(String provider) {
                if (provider.equals(LocationManager.GPS_PROVIDER)) {
                    et.setText("GPS ON!");
                }
            }

            public void onProviderDisabled(String provider) {
            }
        };

        // Register the listener with the Location Manager to receive location
        // updates
        locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
                0, locationListener);
    }

    public static void displayLocation(View v, Location l) {
        ((EditText) v).setText(String.format(
                "Long:%s,\nLat:%s,\nAccu:%s,\nTime ago:%s,\nProvider:%s",
                l.getLongitude(), l.getLatitude(), l.getAccuracy(),
                new java.util.Date().getTime() - l.getTime(), l.getProvider()));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_maps, menu);
        return true;
    }

    /**
     * Determines whether one Location reading is better than the current
     * Location fix
     * 
     * @param location
     *            The new Location that you want to evaluate
     * @param currentBestLocation
     *            The current Location fix, to which you want to compare the new
     *            one
     */
    protected Location isBetterLocation(Location location,
            Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new location is always better than no location
            return location;
        }

        // Check whether the new location fix is newer or older
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > ONE_MINUTE;
        boolean isSignificantlyOlder = timeDelta < -ONE_MINUTE;
        boolean isNewer = timeDelta > 0;

        // If it's been more than two minutes since the current location, use
        // the new location
        // because the user has likely moved
        if (isSignificantlyNewer) {
            return location;
            // If the new location is more than two minutes older, it must be
            // worse
        } else if (isSignificantlyOlder) {
            return currentBestLocation;
        }

        // Check whether the new location fix is more or less accurate
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
                .getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;

        // Check if the old and new location are from the same provider
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());

        // Determine location quality using a combination of timeliness and
        // accuracy
        if (isMoreAccurate) {
            return location;
        } else if (isNewer && !isLessAccurate) {
            return location;
        } else if (isNewer && !isSignificantlyLessAccurate
                && isFromSameProvider) {
            return location;
        }
        return currentBestLocation;
    }

    /** Checks whether two providers are the same */
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }
}

注: 私は静的な場所に重点を置いています。たとえば、移動していないことが回答に役立つ可能性があるためです。

4

2 に答える 2

3

正確な位置を取得するには、次の 2 つの要素を考慮する必要があります。

  1. コード、例えば

    • 正しいロケーション プロバイダーの使用 (GPS とネットワーク)
    • アプリで適切な権限を持つ
  2. デバイス

    • 適切なセンサーがあること (すべての Android デバイスに GPS、Wifi、または電話機能があるわけではありません)
    • 適切なセンサーが有効になっている (たとえば、ユーザーが GPS をオフにしていない)
    • 適切な Google サービスがインストールされている (メーカーの決定)

これらについては以下で説明します。

コード

Android 開発者からのガイダンスに従っていることを確認してください( Bill Garyに感謝します) 。

ただし、デバイス自体に必要なハードウェアと構成がある場合にのみ、コードが機能することに注意してください。以下を参照してください。

デバイス

位置情報の修正で何が問題になっているのかを理解するには、デバイスがどのように位置を特定するかを理解することが非常に役立ちます。位置情報は、次のいくつかのテクノロジによって取得されます。

  1. GPSチップセット

    • 最も正確
    • 遅い
    • 窓の外または近くにいる必要がある
    • GPS チップセットがオンになっている必要があります
  2. WiFi で表示される MAC (Google などの中央 DB にクエリを実行することにより)

    • 多くの場合、驚くほど正確です (存在する WiFi の数と、それらが以前に見られたかどうかに応じて、10 ~ 100 m)
    • かなり速いです
    • Wi-Fiがオンになっている必要があります
    • インターネットへのデータ接続がオンになっている必要があります (WiFi である必要はありません)。
    • デバイスに Google サービスをインストールする必要があります (一部の安価なデバイスにはこれがない場合があります)。
  3. 使用している携帯電話のマストの場所 (ネットワーク プロバイダー)

    • 数百メートルから数キロメートルの精度
    • 多くの場合即時
    • テレフォニーがオンになっている必要があります

位置情報の修正を求める場合 (最後にキャッシュされたものを除く)、優れた GPS 位置情報プロバイダーは、実際には GPS 以外にも多くのことを調べます。

  1. GPSチップセットが有効になっている場合、GPS追跡を開始します

    • 数十秒後、修正が取得された後にのみ、LocationProvider は GPS 位置を返します。
    • その後、デバイスはデバイスの GPS 位置情報を表示可能な WiFi MAC/名前とともに Google に送信し、Google はこれを WiFi AP のデータベースに統合します。
  2. WiFi が有効になっている場合は、Wifi 環境のスキャンを開始します。

    • 数秒後、WiFi スキャンが完了すると、結果が Google のサーバーに送信されます
    • 1 秒ほど後に、サーバーが位置情報の修正を返します

多くの場合、Google マップでこれらの効果を確認できます。たとえば、開始すると、ネットワーク プロバイダーからの大まかな位置 (セル タワー) が表示され、数秒後に、より正確なエリア (WiFi) にズームインします。 )、そして最後に GPS 修正を取得する場合があります。

それは常に価値があります:

  • (ハードコーディングではなく) LocationProvider を選択するための正しい/一般的なアプローチの使用
  • 関連するハードウェア センサーが存在し、有効になっていることを確認する
  • Google マップが期待どおりにデバイスの位置を特定していることを確認します (デバイスに Google マップが付属していない場合は、Google サービスを利用しておらず、非常に基本的な GPS のみのプロバイダーを使用している可能性があります)。
  • GPS チップセットが疑わしい場合は、GPS アプリを使用して、その動作と機能の詳細を確認してください。 ja

編集

取得している基本的な結果から、ネットワーク プロバイダーからの結果しかないようです。したがって、次のようにします。

  • GPSがオンになっているかどうかを確認し、
  • GPS 受信機が修正できるかどうか (デバッグに GPS アプリを使用するなど) および
  • コードにデバッグを (おそらく logcat を介して) 入れて、 isBetterLocation() メソッドが別の場所ではなく 1 つの場所を決定する理由を確認します。
于 2013-01-09T00:27:41.600 に答える
0

できるだけ早く locationListeners を利用可能なすべてのロケーション プロバイダーに設定して、待機する必要があります。リスナーを設定すると、プロバイダーは、所有しているすべてのデータをすぐに提供するように求められます (minTime=0、minDistance=0)。最初の位置近似として getLastKnownLocation を使用します。その間、さまざまなプロバイダーからいくつかの位置データを取得し始めます。ケースに最も適したものを手動で選択する必要があります(最も正確だと思います)。できるだけ長く待ちます (待てば待つほど、より良い位置情報が得られる可能性があります)。待ち時間が終わったら、与えられた最高の場所を取り、それを使い始めてください。システムがより良い価値を提供できる場合は、引き続き位置情報の更新をリッスンし、位置推定を改善できます。

于 2013-01-08T20:37:35.273 に答える