Android
Ortungsdienste via Popup aus eigener App aktivieren

Ziel: der Benutzer soll in einer App ähnlich wie bei Google Maps ein Popup angezeigt bekommen, um die Ortungsdienste zu aktivieren.

Die meisten Lösungen im Internet verzweigen den User auf das System Einstellungen Intend für Ortungsdienste. Ein gangbarer Weg, aber eben nicht ganz so schön.

Für die Popup Lösung muss der Ortungsdienst mittels GoogleApiClient aktivert unde eingebunden werden, anstatt dem LocationManager.
Der GoogleApiClient stellt außerdem Callbacks zur Verfügung, die auf Ortsänderungen reagieren können.
Man spart sich das Abfragen des aktuellen Orts in einem eigenen Thread – eine oft angeführte Lösung.

Los gehts, hier der Walkthrough, um die LocationServices richtig zu benutzen

Zunächst initialisieren wir den GoogelApiClient und bereiten unseren LocationRequest vor.
Um Ortungsereignisse zu verarbeiten, übergeben wir hier auch entsprechende Callbacks.

mGoogleApiClient = new GoogleApiClient.Builder(this)
 .addApi(LocationServices.API)
 .addConnectionCallbacks(this)
 .addOnConnectionFailedListener(this)
 .build();
mLocationRequest = new LocationRequest();
 mLocationRequest.setInterval(10000);
 mLocationRequest.setFastestInterval(5000);
 mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

Dazu erzeugen wir uns ein LocationSettingsRequest, dem wir unsere LocationRequest Config übergeben. Der Builder nimmt auch mehrere. Das ist wichtig, da der Ortungsdienst in dem Modus aktiviert wird, wir in dem/den LocationRequests angegeben. Das hat also direkte Auswirkung auf Genauigkeit und Stromverbrauch. Unser LocationRequest wurde mit PRIORITY_HIGH_ACCURACY erstellt.

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
           .addLocationRequest(mLocationRequest).setAlwaysShow(true);
// setAlwaysShow(true) entfernt die Möglichkeit "NIE" aus dem Popup.
//Würde der User "NIE" wählen, würde auch später nie mehr der System Setting Popup kommen.

Anschließend kommt der wichtige Teil. Hier wird die SettingApi bemüht, um die Einstellungen abzufragen. Im Callback wird dann wenn notwendig der Popup eingeblendet.

PendingResult<LocationSettingsResult> result =
        LocationServices.SettingsApi
             .checkLocationSettings(mGoogleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        //Ortungsdienst ist bereits aktiv.
                        text.setText(R.string.text_locating);
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Ortungsdienst nicht aktiv, anzeigen des Popup
                        // Dialogs durch startResolutionForResult
                        // Als Call back geben wir MapsActivity.this mit,
                        // wo die Methode onActivityResult implementiert ist.
                        try {
                            status.startResolutionForResult(
                                    MapsActivity.this,
                                    REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Ortungsdienste nicht aktiv, und es gibt auch keine Möglichkeit,
                        // die zu aktivieren. z.B. nicht vorhanden.
                        break;
                }
            }
        });

Abschließend behandeln wir das Ergebnis des Popup Dialogs in unserem Callback.

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // Der User hat den Ortungsdienst aktivert,
                        // also können wir die App vorbereiten.
                        connectLocationService();
                        break;
                    case Activity.RESULT_CANCELED:
                        // Der User hat den Ortungsdienst nicht aktiviert.
                        break;
                    default:
                        break;
                }
                break;
        }
}