857 Stimmen

Was ist der einfachste und zuverlässigste Weg, um den aktuellen Standort des Benutzers unter Android zu ermitteln?

El LocationManager API auf Android scheint für eine Anwendung, die nur gelegentlich eine grobe Annäherung an den Standort des Nutzers benötigt, etwas mühsam zu sein.

Die App, an der ich arbeite, ist eigentlich keine Standort-App, aber sie muss den Standort des Benutzers abfragen, um eine Liste von Geschäften in der Nähe anzeigen zu können. Sie muss sich nicht darum kümmern, ob der Benutzer sich bewegt oder so etwas.

Ich würde gerne Folgendes tun:

  1. Zeigt dem Benutzer eine Liste von Orten in der Nähe.
  2. Den Standort des Nutzers vorladen, so dass er zum Zeitpunkt, an dem ich ihn in Activity X, wird es verfügbar sein.
  3. Die Genauigkeit und die Häufigkeit der Aktualisierungen sind mir nicht besonders wichtig. Es reicht aus, wenn ich nur einen Standort erfasse, solange er nicht weit daneben liegt. Wenn ich schick sein will, aktualisiere ich den Standort vielleicht einmal alle paar Minuten oder so, aber das hat keine große Priorität.
  4. Funktioniert mit jedem Gerät, das entweder über ein GPS oder einen Netzwerkstandortanbieter verfügt.

Es scheint, dass es nicht so schwer sein sollte, aber es scheint mir, dass ich zwei verschiedene Standortanbieter (GPS und NETZWERK) einrichten und den Lebenszyklus jedes Anbieters verwalten muss. Und nicht nur das, ich muss denselben Code in mehreren Aktivitäten duplizieren, um Nr. 2 zu erfüllen. Ich habe versucht, mit getBestProvider() Ich habe in der Vergangenheit versucht, die Lösung auf einen einzigen Standortanbieter zu beschränken, aber das scheint Ihnen nur den besten "theoretischen" Anbieter zu liefern und nicht den Anbieter, der Ihnen tatsächlich die besten Ergebnisse liefert.

Gibt es eine einfachere Möglichkeit, dies zu erreichen?

1 Stimmen

Sie könnten eine einfache Bibliothek verwenden, die all die Dinge abstrahiert, die "unter der Haube" passieren müssen: github.com/delight-im/Android-SimpleLocation

0 Stimmen

Hier finden Sie die Antwort in Kotlin: stackoverflow.com/a/53800632/2201814

0 Stimmen

Sie können in Android verschmolzene Techniken zur Standorterfassung verwenden.

11voto

Parsania Hardik Punkte 4494

Ich habe eine ausführliche Anleitung geschrieben, die Folgendes behandelt aktueller Standort hier auf demonuts.de Hier finden Sie weitere Beschreibungen und können auch den gesamten Quellcode der Demo zum besseren Verständnis herunterladen.

Es gibt bereits viele Antworten, aber ich möchte den neuesten Weg zeigen, um den Standort mit Google API zu erhalten, so dass neue Programmierer die neue Methode verwenden können:

Fügen Sie zunächst Folgendes in die gradle-Datei ein

compile 'com.google.android.gms:play-services:8.4.0'

dann notwendige Schnittstellen implementieren

public class MainActivity  extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener

Instanzen deklarieren

  private GoogleApiClient mGoogleApiClient;
  private Location mLocation;
  private LocationManager locationManager;
  private LocationRequest mLocationRequest;

setzen Sie dies ein onCreate()

 mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

Zuletzt überschreiben Sie die notwendigen Methoden

 @Override
    public void onConnected(Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLocation == null){
            startLocationUpdates();
        }
        if (mLocation != null) {
            double latitude = mLocation.getLatitude();
            double longitude = mLocation.getLongitude();
        } else {
            // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
        }
    }

    protected void startLocationUpdates() {
        // Create the location request
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(UPDATE_INTERVAL)
                .setFastestInterval(FASTEST_INTERVAL);
        // Request location updates
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                mLocationRequest, this);
        Log.d("reque", "--->>>>");
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.i(TAG, "Connection Suspended");
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
    }

    @Override
    public void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }
    @Override
    public void onLocationChanged(Location location) {

    }

Vergessen Sie nicht, das GPS in Ihrem Gerät zu starten, bevor Sie die App ausführen.

10voto

Jhon Punkte 101

Tatsächlich können wir die beiden Anbieter (GPS & NETZWERK) nutzen. Und sie teilen sich einfach einen öffentlichen Hörer:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, (float) 10.0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 90 * 1000, (float) 10.0, listener);

Dies ist notwendig, weil die OnLocationChanged() Methode muss immer rechtzeitig aufgerufen werden.

7voto

krisDrOid Punkte 3139

Benutzen Sie den untenstehenden Code, er wird den besten verfügbaren Anbieter liefern:

String locCtx = Context.LOCATION_SERVICE; 

LocationManager locationMgr = (LocationManager) ctx.getSystemService(locCtx);

Criteria criteria  = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);

String provider = locationMgr.getBestProvider(criteria, true);

System.out.println("Best Available provider::::"+provider);

7voto

npinti Punkte 51030

Ich bin nicht sicher, ob die Standortbezogene Dienste den Standort über andere Infrastrukturen als GPS ermitteln kann, aber laut diesem Artikel scheint es möglich zu sein:

Anwendungen können auf jede der verschiedene Arten von Positionierungsmethoden verwenden.

Nutzung des Mobilfunknetzes: Die aktuelle Zell-ID kann verwendet werden, um die Base Transceiver Station (BTS) zu identifizieren (BTS), mit der das Gerät kommuniziert mit der das Gerät kommuniziert, und den Standort dieser BTS. Natürlich hängt die Genauigkeit dieser Methode von der Größe der Zelle ab, und kann recht ungenau sein. Eine GSM-Zelle kann zwischen 2 und 20 Kilometer im Durchmesser sein. Andere Techniken, die zusammen mit Zell-ID verwendet werden, können eine Genauigkeit von bis zu 150 Metern erreichen.

Einsatz von Satelliten: Die globale Positionierungssystem (GPS), das vom vom US-Verteidigungsministerium kontrolliert wird, verwendet eine Konstellation von 24 Satelliten die die Erde umkreisen. GPS bestimmt die die Position des Geräts durch Berechnung der Unterschiede in den Zeiten der Signale von verschiedenen Satelliten zum Empfänger Empfänger erreichen. GPS-Signale sind verschlüsselt, so dass muss das mobile Gerät ausgestattet sein mit einem GPS-Empfänger ausgestattet sein. GPS ist potentiell die genaueste Methode (zwischen 4 und 40 Metern, wenn das GPS Empfänger eine klare Sicht auf den Himmel hat), aber sie hat einige Nachteile: Die zusätzliche Hardware kann kostspielig sein, verbraucht verbraucht während des Betriebs Batterie und erfordert nach einem Kaltstart eine gewisse Aufwärmphase, um um die ersten sichtbaren Satelliten zu orten. Es leidet auch unter "Canyon-Effekten" in Städten, wo die Sichtbarkeit der Satelliten unregelmäßig ist.

Verwendung von Kurzstrecken Ortungsbaken: In relativ kleinen kleinen Gebieten, wie z.B. einem einzelnen Gebäude, kann ein lokales Netzwerk Standorte zusammen mit anderen Dienste anbieten. Zum Beispiel können entsprechend entsprechend ausgerüstete Geräte Bluetooth nutzen, um Kurzstreckenortung nutzen.

6voto

Matt W Punkte 676

Die empfohlene Vorgehensweise ist die Verwendung von LocationClient :

Legen Sie zunächst die Werte für das Aktualisierungsintervall des Standorts fest. Passen Sie diese an Ihre Bedürfnisse an.

private static final int MILLISECONDS_PER_SECOND = 1000;
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;

Haben Sie Ihre Activity implementieren GooglePlayServicesClient.ConnectionCallbacks , GooglePlayServicesClient.OnConnectionFailedListener et LocationListener .

public class LocationActivity extends Activity implements 
GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {}

Richten Sie dann eine LocationClient im onCreate() Methode Ihrer Activity :

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mLocationClient = new LocationClient(this, this, this);

    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
}

Fügen Sie die erforderlichen Methoden zu Ihrer Activity ; onConnected() ist die Methode, die aufgerufen wird, wenn die LocationClient verbindet. onLocationChanged() können Sie den aktuellsten Standort abrufen.

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.w(TAG, "Location client connection failed");
}

@Override
public void onConnected(Bundle dataBundle) {
    Log.d(TAG, "Location client connected");
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 
}

@Override
public void onDisconnected() {
    Log.d(TAG, "Location client disconnected");
}

@Override
public void onLocationChanged(Location location) {
    if (location != null) {
        Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude()));
    } else {
        Log.d(TAG, "Updated location NULL");
    } 
}     

Stellen Sie sicher, dass Sie die LocationClient Damit verbraucht es nur dann zusätzlichen Akku, wenn es unbedingt notwendig ist, und das GPS läuft nicht unendlich lange. Die LocationClient muss angeschlossen sein, um Daten von ihm zu erhalten.

public void onResume() {
    super.onResume();
    mLocationClient.connect();
}

public void onStop() {
    if (mLocationClient.isConnected()) {
        mLocationClient.removeLocationUpdates(this);
    }
    mLocationClient.disconnect();
    super.onStop();
}

Ermitteln Sie den Standort des Benutzers. Versuchen Sie zunächst mit der LocationClient Wenn das nicht klappt, greifen Sie auf die LocationManager .

public Location getLocation() {
    if (mLocationClient != null && mLocationClient.isConnected()) {
        return mLocationClient.getLastLocation();
    } else {
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        if (locationManager != null) {
            Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (lastKnownLocationGPS != null) {
                return lastKnownLocationGPS;
            } else {
                return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            }
        } else {
            return null;
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X