Jak wyświetlić okno dialogowe włączania lokalizacji, takie jak mapy Google?

132

Korzystam z najnowszej wersji Usług Google Play (7.0) i postępowałem zgodnie z instrukcjami podanymi w ich przewodniku i włączyłem okno dialogowe lokalizacji, jak poniżej, które ma przycisk „nigdy”. Moja aplikacja wymaga lokalizacji obowiązkowo, więc nie chcę pokazywać użytkownikowi „nigdy”, ponieważ gdy użytkownik kliknie „nigdy”, nie mogę ponownie uzyskać lokalizacji ani poprosić o jej podanie.

Gdzie Google Maps ma tylko przycisk tak i nie bez przycisku nigdy, nie ma pojęcia, jak osiągnąć to samo?

Obraz mojej aplikacji wprowadź opis obrazu tutaj

Obraz mapy Google wprowadź opis obrazu tutaj

Mufri A
źródło

Odpowiedzi:

149

LocationSettingsRequest.Builder ma metodę setAlwaysShow(boolean show). Chociaż dokument wskazuje, że obecnie nic nie robi (aktualizacja 2015-07-05: zaktualizowana dokumentacja Google usunęła to sformułowanie), ustawienie builder.setAlwaysShow(true);umożliwi zachowanie Google Maps: wprowadź opis obrazu tutaj

Oto kod, dzięki któremu to działa:

if (googleApiClient == null) {
    googleApiClient = new GoogleApiClient.Builder(getActivity())
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    googleApiClient.connect();

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);

    //**************************
    builder.setAlwaysShow(true); //this is the key ingredient
    //**************************

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            final LocationSettingsStates state = result.getLocationSettingsStates();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    // All location settings are satisfied. The client can initialize location
                    // requests here.
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the user
                    // a dialog.
                    try {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(
                                getActivity(), 1000);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way to fix the
                    // settings so we won't show the dialog.
                    break;
            }
        }
    });
}

Z dokumentacji systemu Android

W przypadku Kotlin patrz tutaj: https://stackoverflow.com/a/61868985/12478830

Kai
źródło
1
@ MarianPaździoch na pewno nie musisz, ponieważ własny przykładowy kod Google w SettingsApi tego nie wymaga.
Kai
1
@Kai Tak, kod jest niezmodyfikowany na Nexusie 5. Korzystając z dzienników, widzę, że gdy usługi lokalizacyjne są początkowo wyłączone, zawsze trafia RESOLUTION_REQUIRED. Następnie, gdy akceptuję i włączam lokalizację, trafia SUCCESSi całkowicie pomija onActivityResult(). Naciśnięcie Nolub cofnięcie powoduje zniknięcie okna dialogowego na sekundę, a następnie ponowne załadowanie i uderzenie RESOLUTION_REQUIRED. Jedynym sposobem na pozbycie się tego okna dialogowego jest zaakceptowanie lub zamknięcie i ponowne otwarcie aplikacji.
pez
2
@pez testowany na Galaxy S4 z usługami Google Play 7.5.74 i działa, anulowanie nie powoduje wywołania RESOLUTION_REQUIRED. Proponuję zaktualizować usługi odtwarzania i spróbować ponownie. Jeśli to się nie powiedzie, rozpocznij nowe pytanie StackOverflow, aby sprawdzić, czy inni napotkali i rozwiązali ten problem.
Kai,
2
@Kai zadziałało dla mnie, ale co, jeśli użytkownik naciśnie nie Jak wyświetlić okno dialogowe ponownie lub dodać tam kod, jeśli naciśniesz nie, każda pomoc będzie bardzo mile widziana.
Gurpreet singh
1
UWAGA: Twojej aktywności launchModeNIE można ustawić na singleInstanceinaczej, to NIE zadziała. Okno dialogowe nigdy się nie pojawi i onActivityResultzostanie wywołane automatycznie. NIE MASZ android:launchMode="singleInstance"swojej aktywności w AndroidManifest. Nauczyłem się tego bardzo ciężko po 3 godzinach
ᴛʜᴇᴘᴀᴛᴇʟ
55

Chciałbym dodać kilka zmian w odpowiedzi kai dla tych, którzy szukają obsługi przycisków Tak / Nie.

Deklaruj tę stałą w swojej działalności

protected static final int REQUEST_CHECK_SETTINGS = 0x1;

zadzwoń settingsrequest()do swojego onStart ()

public void settingsrequest()
    {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        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();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        startLocationUpdates();
                        break;
                    case Activity.RESULT_CANCELED:
                        settingsrequest();//keep asking if imp or do whatever
                        break;
                }
                break;
        }
    }
Veer3383
źródło
1
wziąłem z oficjalnej dokumentacji: developers.google.com/android/reference/com/google/android/gms/… jeśli chcesz dodać tylko mapy, aby z tego skorzystać, musisz dodać te biblioteki (bez importowania całej biblioteki usług Play ): kompiluj 'com.google.android.gms: play-services-maps: 9.0.2' compile 'com.google.android.gms: play-services-location: 9.0.2'
MatPag
jak obsługiwać zdarzenie kliknięcia tego okna dialogowego i nigdy nie wolno mi pokazywać przycisku nigdy w oknie dialogowym
M.Yogeshwaran
usuń wiersz settingsrequest () z obudowy przełącznika w ActivityOnResult .. Czy o to pytasz ???
Veer3383
Jeśli nie kliknę żadnego przycisku w oknie dialogowym, nadal pojawia się to okno dialogowe. Usunąłem już wiersz settingsrequest () z przypadku przełącznika w ActivityOnResult .. to dlaczego jest on wyświetlany w sposób ciągły?
Asmi
Być może będziesz musiał wyczyścić projekt.
Veer3383
26

LocationServices.SettingsApi jest teraz przestarzałe, więc używamy SettingsClient

    LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setSmallestDisplacement(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new 
        LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);

Następnie sprawdź, czy aktualne ustawienia lokalizacji są prawidłowe. Utwórz zadanie LocationSettingsResponse:

        Task<LocationSettingsResponse> task=LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());

Następnie dodaj Listener

task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
            @Override
                    public void onComplete(Task<LocationSettingsResponse> task) {
                        try {
                            LocationSettingsResponse response = task.getResult(ApiException.class);
                            // All location settings are satisfied. The client can initialize location
                            // requests here.

                        } catch (ApiException exception) {
                            switch (exception.getStatusCode()) {
                                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                    // Location settings are not satisfied. But could be fixed by showing the
                                    // user a dialog.
                                    try {
                                        // Cast to a resolvable exception.
                                        ResolvableApiException resolvable = (ResolvableApiException) exception;
                                        // Show the dialog by calling startResolutionForResult(),
                                        // and check the result in onActivityResult().
                                        resolvable.startResolutionForResult(
                                                HomeActivity.this,
                                                101);
                                    } catch (IntentSender.SendIntentException e) {
                                        // Ignore the error.
                                    } catch (ClassCastException e) {
                                        // Ignore, should be an impossible error.
                                    }
                                    break;
                                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                    // Location settings are not satisfied. However, we have no way to fix the
                                    // settings so we won't show the dialog.
                                    break;
                            }
                        }
                    }
                });

Dodano onActivityResult

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) {
            case 101:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        Toast.makeText(HomeActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(HomeActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
                break;
        }
    }

Skorzystaj z linku SettingsClient

Arul Pandian
źródło
1
Sprawdź stackoverflow.com/a/53277287 @BadLoser Using SettingsClient
Ketan Ramani
Jak nazywa się zależność do zaimportowania? Nie można rozwiązać zadania symbolu.
Denis
Znalazłem to: wdrożenie „com.google.android.gms: usługi-odtwarzania-zadania: 16.0.1”
Denis
@Denis, implementation 'com.google.android.gms:play-services-location:16.0.0'zamiast tego mógłbym użyć .
CoolMind
25

Działa podobnie do map Google?
Kod źródłowy: https://drive.google.com/open?id=0BzBKpZ4nzNzUOXM2eEhHM3hOZk0

Dodaj zależności w pliku build.gradle:

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

LUB

compile 'com.google.android.gms:play-services-location:10.0.1'

wprowadź opis obrazu tutaj

public class LocationOnOff_Similar_To_Google_Maps extends AppCompatActivity {

    protected static final String TAG = "LocationOnOff";


    private GoogleApiClient googleApiClient;
    final static int REQUEST_LOCATION = 199;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.setFinishOnTouchOutside(true);

        // Todo Location Already on  ... start
        final LocationManager manager = (LocationManager) LocationOnOff_Similar_To_Google_Maps.this.getSystemService(Context.LOCATION_SERVICE);
        if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) {
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
            finish();
        }
        // Todo Location Already on  ... end

        if(!hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)){
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not Supported",Toast.LENGTH_SHORT).show();
        }

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) {
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not enabled",Toast.LENGTH_SHORT).show();
            enableLoc();
        }else{
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
        }
    }


    private boolean hasGPSDevice(Context context) {
        final LocationManager mgr = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (mgr == null)
            return false;
        final List<String> providers = mgr.getAllProviders();
        if (providers == null)
            return false;
        return providers.contains(LocationManager.GPS_PROVIDER);
    }

    private void enableLoc() {

        if (googleApiClient == null) {
            googleApiClient = new GoogleApiClient.Builder(LocationOnOff_Similar_To_Google_Maps.this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnected(Bundle bundle) {

                        }

                        @Override
                        public void onConnectionSuspended(int i) {
                            googleApiClient.connect();
                        }
                    })
                    .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(ConnectionResult connectionResult) {

                            Log.d("Location error","Location error " + connectionResult.getErrorCode());
                        }
                    }).build();
            googleApiClient.connect();

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30 * 1000);
            locationRequest.setFastestInterval(5 * 1000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);

            builder.setAlwaysShow(true);

            PendingResult<LocationSettingsResult> result =
                    LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(LocationOnOff_Similar_To_Google_Maps.this, REQUEST_LOCATION);

                                finish();
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            }
                            break;
                    }
                }
            });
        }
    }

}
Keshav Gera
źródło
to moja przyjemność
Keshav Gera
1
Zobacz post Odbiorcy transmisji bardzo przydatny i podobny do mnie stackoverflow.com/questions/15698790/…
Keshav Gera
Idealne rozwiązanie.
Lalit Sharma
Dzięki Lalit Sharma
Keshav Gera
Czy możesz zaktualizować link, jest teraz uszkodzony, zamiast tego opublikuj kod w GitHub
Manoj Perumarath
7

Ola Cabs korzysta z nowo wydanego interfejsu Settings API, aby osiągnąć tę funkcjonalność. Zgodnie z nowym interfejsem API użytkownik nie musi przechodzić do strony ustawień, aby włączyć usługi lokalizacyjne, zapewniając bezproblemową integrację dla tego samego. Przeczytaj poniżej, aby uzyskać więcej informacji:

https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi

Abhi
źródło
wygląda to tak samo jak odpowiedź veer3383. proszę poprawić mnie, jeśli się mylę
rakesh kashyap
@rakeshkashyap tak, to to samo
MatPag
Chciałem wiedzieć, czy można wykonać poniższe czynności: * ustawić limit czasu na uzyskanie lokalizacji. * sprawdź w API ustawień GPS, czy wszystkie wymagane czujniki są włączone i pokaż odpowiednio komunikat. * Jeśli to możliwe, jak ustawić limit czasu.? Nie udało mi się znaleźć takiego ustawienia podczas budowania API
rakesh kashyap
Witam, mam problem z załadowaniem mapy po raz drugi po włączeniu GPS ze stanu Off, proszę, niech ktoś mi pomoże: stackoverflow.com/questions/44368960/ ... Dzięki.
Jaimin Modi
3
SettingsAPIzostał wycofany, teraz używasz SettingsClient developers.google.com/android/reference/com/google/android/gms/…
Saik Caskey
7

Zależność

compile 'com.google.android.gms:play-services-location:10.0.1'

Kod

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    public static final int REQUEST_LOCATION=001;

    GoogleApiClient googleApiClient;

    LocationManager locationManager;
    LocationRequest locationRequest;
    LocationSettingsRequest.Builder locationSettingsRequest;
    Context context;


    PendingResult<LocationSettingsResult> pendingResult;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Toast.makeText(this, "Gps is Enabled", Toast.LENGTH_SHORT).show();

        } else {
            mEnableGps();
        }

    }

    public void mEnableGps() {
        googleApiClient = new GoogleApiClient.Builder(context)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        googleApiClient.connect();
        mLocationSetting();
    }

    public void mLocationSetting() {
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(1 * 1000);
        locationRequest.setFastestInterval(1 * 1000);

        locationSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);

        mResult();

    }

    public void mResult() {
        pendingResult = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, locationSettingsRequest.build());
        pendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
                Status status = locationSettingsResult.getStatus();


                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.

                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

                        try {

                            status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION);
                        } catch (IntentSender.SendIntentException e) {

                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.


                        break;
                }
            }

        });
    }


    //callback method
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) {
            case REQUEST_LOCATION:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        Toast.makeText(context, "Gps enabled", Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(context, "Gps Canceled", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
                break;
        }
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}
Francis
źródło
4

Możesz także dodać kilka żądań lokalizacji dla Buildera, aby uzyskać okno dialogowe „Użyj GPS, Wi-Fi i sieci komórkowych do lokalizacji” zamiast tylko „Użyj GPS do lokalizacji”

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY))
                .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY))
                .setAlwaysShow(true);

PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
Andrey Busik
źródło
W moim przypadku wystarczy użyć PRIORITY_HIGH_ACCURACY, aby uzyskać zdanie „Użyj GPS, Wi-Fi i sieci komórkowych do lokalizacji”. Ale to dziwne, że działa na prawdziwym urządzeniu, ale w symulatorze nie. W zdaniu symulatora zawsze na początku brak „Użyj GPS”, chociaż widzę, że urządzenie symulatora ma GPS.
mikep
2

W Kotlinie użyj tego kodu:

import android.app.Activity
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.PendingResult
import com.google.android.gms.common.api.Status
import com.google.android.gms.location.*

class MainActivity : AppCompatActivity() {
    private var googleApiClient: GoogleApiClient? = null
    private val REQUESTLOCATION = 199
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableLoc()
    }
    private fun enableLoc() {
        googleApiClient = GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
                override fun onConnected(bundle: Bundle?) {}
                override fun onConnectionSuspended(i: Int) {
                    googleApiClient?.connect()
                }
            })
            .addOnConnectionFailedListener {
            }.build()
        googleApiClient?.connect()
        val locationRequest = LocationRequest.create()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 30 * 1000.toLong()
        locationRequest.fastestInterval = 5 * 1000.toLong()
        val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest)
        builder.setAlwaysShow(true)
        val result: PendingResult<LocationSettingsResult> =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
        result.setResultCallback { result ->
            val status: Status = result.status
            when (status.statusCode) {
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                    status.startResolutionForResult(
                        this@MainActivity,
                        REQUESTLOCATION
                    )
                } catch (e: IntentSender.SendIntentException) {
                }
            }
        }
    }
    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            REQUESTLOCATION -> when (resultCode) {
                Activity.RESULT_OK -> Log.d("abc","OK")
                Activity.RESULT_CANCELED -> Log.d("abc","CANCEL")
            }
        }
    }
}
MMG
źródło
0

Proszę sprawdzić moje bardzo proste rozwiązanie, aby uzyskać lokalizację użytkownika na pierwszym planie.

  1. Okno dialogowe ustawień GPS
  2. Lokalizacja użytkownika z danymi na żywo.
  3. Klasa LocationUtility jest uwzględniająca cykl życia czynności, aby wstrzymać / wznowić aktualizacje lokalizacji.
  4. Lokalizacja z najnowszym FusedLocationProviderClient

https://github.com/Maqsood007/UserLocation-Android/blob/master/app/src/main/java/jetpack/skill/userlocation_android/utils/LocationUtility.kt

wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

Muhammad Maqsood
źródło
0

Nowa zaktualizowana odpowiedź Sierpień 2020 wprowadź opis linku tutaj

mój fragment jest jak ta aktualizacja, jeśli używasz w swojej działalności

 import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;


import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;

import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;

import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class FragmentSearch extends Fragment
{

    View SearchFragmentview;
    protected static final int REQUEST_CHECK_SETTINGS = 0x1;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        SearchFragmentview=inflater.inflate(R.layout.fragment_search,container,false);

           getLocationDialog();

        return  SearchFragmentview;

    }

    private void getLocationDialog()
    {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(getContext()).checkLocationSettings(builder.build());



        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>()
        {
            @Override
            public void onComplete(Task<LocationSettingsResponse> task)
            {
                try {
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    // All location settings are satisfied. The client can initialize location
                    // requests here.

                }
                catch (ApiException exception)
                {
                    switch (exception.getStatusCode())
                    {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the
                            // user a dialog.
                            try {
                                // Cast to a resolvable exception.
                                ResolvableApiException resolvable = (ResolvableApiException) exception;
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().


                                resolvable.startResolutionForResult(
                                      getActivity(),
                                        REQUEST_CHECK_SETTINGS);

                            }
                            catch (IntentSender.SendIntentException e)
                            {
                                // Ignore the error.
                            }
                            catch (ClassCastException e)
                            {
                                // Ignore, should be an impossible error.
                            }
                            break;
                           case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // Location settings are not satisfied. However, we have no way to fix the
                            // settings so we won't show the dialog.

                            break;
                    }
                }
            }
        });


    }



    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        switch (requestCode)
        {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode)
                {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made

                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to

                        break;
                    default:
                        break;
                }
                break;
        }
    }[enter image description here][2]



}
Edytuj odishę
źródło
0

GoogleApiClient jest przestarzały . Nowa implementacja w Kotlinie może wyglądać następująco.

Zależności

// Google Maps Location Services
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'

Kod

val locationRequest = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setInterval(30 * 1000)
    .setFastestInterval(5 * 1000)

val builder = LocationSettingsRequest.Builder()
    .addLocationRequest(locationRequest)
    .setAlwaysShow(true)

val pendingResult = LocationServices
    .getSettingsClient(activity)
    .checkLocationSettings(builder.build())

pendingResult.addOnCompleteListener { task ->
    if (task.isSuccessful.not()) {
        task.exception?.let {
            if (it is ApiException && it.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                (it as ResolvableApiException).startResolutionForResult(activity,
                    MainActivity.REQUEST_CODE_LOCATION)
            }
        }
    }
}
Ercan
źródło
Tę odpowiedź można również sprawdzić: stackoverflow.com/a/31816683/4308897
Ercan