Jak mogę programowo włączyć lub wyłączyć GPS w systemie Android?

158

Wiem, że pytanie o włączanie / wyłączanie GPS programowo na Android został już omówiony wiele razy , a odpowiedź jest zawsze taka sama:

„Nie możesz ze względów bezpieczeństwa / prywatności, musisz przekierować do ekranu preferencji lokalizacji i pozwolić użytkownikowi włączyć / wyłączyć to.”

Rozumiem, że jednak Niedawno kupiłem Tasker z rynku, a wśród wielu innych rzeczy, które można osiągnąć z nim, można ustawić reguły do automatycznej włączyć GPS na wejściu wcześniej ustalona aplikacje i wyłącz go na wyjeździe (patrz tutaj dla samouczek, jak to zrobić, i to po prostu działa!), a tej aplikacji nie można podpisać za pomocą klucza podpisywania oprogramowania układowego, ponieważ działa na wielu wersjach Androida i różnych urządzeniach i nie trzeba nawet być zrootowana.

Chciałbym to zrobić w mojej aplikacji. Oczywiście nie chcę naruszać prywatności użytkowników, więc najpierw zapytałbym użytkownika, czy chce go włączyć automatycznie za pomocą typowego pola wyboru „zapamiętaj moją decyzję”, a jeśli odpowie tak, włącz to.

Czy ktoś ma pomysł lub wskazówkę, jak Tasker to osiąga?

pokojówka450
źródło

Odpowiedzi:

161

GPS można przełączać, wykorzystując błąd w widżecie menedżera zasilania. zobacz ten wątek xda do dyskusji.

oto przykładowy kod, którego używam

private void turnGPSOn(){
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(!provider.contains("gps")){ //if gps is disabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); 
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
}

private void turnGPSOff(){
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(provider.contains("gps")){ //if gps is enabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
}

użyj poniższego, aby sprawdzić, czy istniejąca wersja widżetu kontroli zasilania to taka, która pozwoli ci przełączać GPS.

private boolean canToggleGPS() {
    PackageManager pacman = getPackageManager();
    PackageInfo pacInfo = null;

    try {
        pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
    } catch (NameNotFoundException e) {
        return false; //package not found
    }

    if(pacInfo != null){
        for(ActivityInfo actInfo : pacInfo.receivers){
            //test if recevier is exported. if so, we can toggle GPS.
            if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
                return true;
            }
        }
    }

    return false; //default
}
Ben H.
źródło
4
W czasie tego (mojego) komentarza, linki w tej odpowiedzi wydają się wskazywać, że błąd, który ten exploit został niedawno naprawiony. Chciałem tylko zwrócić uwagę, że exploit nadal wydaje się działać dobrze w moim własnym środowisku testowym, więc nie powinieneś rezygnować z próbowania tego ... po prostu upewnij się, że twój kod obsłuży wszelkie błędy, jeśli nie zadziała !
SilithCrowe
1
W chwili pisania tego komentarza ten exploit nadal działa na telefonie z Androidem 2.2.1. Niezłe znalezisko, Ben H.
Qix - MONICA BYŁA NIEPRAWIDŁOWO POSTĘPOWAŁA
38
To naprawdę zły pomysł. Gdy błąd zostanie naprawiony, Twój exploit przestanie działać. Lepiej po prostu wysłać użytkownika do aplikacji ustawień.
Edward Falk
1
Działa dobrze w systemie Android 2.3.6, ale nie działa w systemie Android 4.0.3. Każdy pomysł, aby włączyć lub wyłączyć w systemie Android 4.0.3
Krishna
5
hahaha ... ten exploit pojawił się ponownie w 4.2.2, Zaskoczony, że go widzę .. BÓG!
amithgc
70

Wszystkie te odpowiedzi są teraz niedozwolone. Oto poprawny:

Dla wszystkich, którzy wciąż szukają odpowiedzi:

Oto, jak robią to OLA Cabs i inne tego typu aplikacje.

Dodaj to do swojego onCreate

if (googleApiClient == null) {
    googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(Login.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(Login.this, 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;
            }
        }
    });
}

Oto implmentowane metody:

@Override
public void onConnected(Bundle arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onConnectionSuspended(int arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
    // TODO Auto-generated method stub

}

Oto dokumentacja Androida dla tego samego.

Ma to pomóc innym facetom, jeśli nadal walczą:

Edycja : dodanie komentarza Irfana Razy, aby uzyskać dodatkową pomoc.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == 1000) {
         if(resultCode == Activity.RESULT_OK){
             String result=data.getStringExtra("result"); 
         } if (resultCode == Activity.RESULT_CANCELED) {
             //Write your code if there's no result 
         } 
    } 
} 
Akszat
źródło
Teraz ta odpowiedź powinna być zaakceptowana. Wielkie dzięki Akshat !!
Gurpreet
2
Wymaga integracji z klientem Google API, stąd tylko rozwiązanie do konkretnych przypadków użycia, nie nadające się do rozwiązania ogólnego.
Cik,
@DilroopSingh z jakim problemem masz do czynienia.? Używam tego samego kodu i działa doskonale.
Akshat,
1
czy możemy to osiągnąć bez pokazywania tego budowniczego, ponieważ muszę włączyć GPS bez pokazywania żadnych alertów.
Punithapriya
3
@Punithapriya To niemożliwe. Zgoda użytkownika jest konieczna, a zatem musi zostać pokazany twórca.
Akshat
50

WŁĄCZ GPS:

Intent intent=new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

WYŁĄCZ GPS:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
Debugger
źródło
1
automatycznie GPS włączy / wyłączy się.
Debugger,
1
Pomaga to również włączyć. private void turnGPSOn () {String provider = Settings.Secure.getString (getContentResolver (), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); if (! provider.contains ("gps")) {// jeśli GPS jest wyłączony final Intent poke = new Intent (); poke.setClassName ("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); poke.addCategory (Intent.CATEGORY_ALTERNATIVE); poke.setData (Uri.parse ("3")); sendBroadcast (poke); }}
Debugger
w systemie Android 2.3.4 działającym na asamsung sII włącza ikonę GPS bez efektywnej aktywacji czujnika GPS. Jeśli jednak zdecydujesz się włączyć programowo czujnik GPS, zostanie on rozpoznany.
tony gil
24
Android 4.0.4 - włączone jest tylko powiadamianie GPS . nie sam GPS. więc wygląda na to, że jest włączony, ale w rzeczywistości tak nie jest
alex
14
java.lang.SecurityException: Permission Denial: niedozwolone na wysyłanie transmisji android.location.GPS_ENABLED_CHANGE
Abhi
28

Ten kod działa na telefonach ZROOTOWANYCH, jeśli aplikacja zostanie przeniesiona na /system/aps , i mają one następujące uprawnienia w manifeście :

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>

Kod

private void turnGpsOn (Context context) {
    beforeEnable = Settings.Secure.getString (context.getContentResolver(),
                                              Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    String newSet = String.format ("%s,%s",
                                   beforeEnable,
                                   LocationManager.GPS_PROVIDER);
    try {
        Settings.Secure.putString (context.getContentResolver(),
                                   Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                   newSet); 
    } catch(Exception e) {}
}


private void turnGpsOff (Context context) {
    if (null == beforeEnable) {
        String str = Settings.Secure.getString (context.getContentResolver(),
                                                Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        if (null == str) {
            str = "";
        } else {                
            String[] list = str.split (",");
            str = "";
            int j = 0;
            for (int i = 0; i < list.length; i++) {
                if (!list[i].equals (LocationManager.GPS_PROVIDER)) {
                    if (j > 0) {
                        str += ",";
                    }
                    str += list[i];
                    j++;
                }
            }
            beforeEnable = str;
        }
    }
    try {
        Settings.Secure.putString (context.getContentResolver(),
                                   Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                   beforeEnable);
    } catch(Exception e) {}
}
Nate Zaugg
źródło
5
+1 za wspomnienie o tej metodzie. Powinien również działać z aplikacją systemową na urządzeniu niezrootowanym.
AlexS
to jest właściwa droga. Działa na każdej wersji Androida, nie potrzebujesz żadnych sztuczek!
BQuadra
wyłączenie GPS nie działa !! czy możesz mi powiedzieć, dlaczego i możliwe rozwiązanie.
Shivansh,
teraz gps wyłącza się i włącza idealnie, ale GPS nie działa, tj. podaje lokalizację lat long 0.0
Shivansh
<używa-pozwolenia android: name = "android.permission.WRITE_SECURE_SETTINGS" /> tylko dla aps systemowych
sijo jose
23

Zamiast korzystać z ustawień intencji.ACTION_LOCATION_SOURCE_SETTINGS możesz bezpośrednio wyświetlać wyskakujące okienka w swojej aplikacji, takie jak Google Map i GPS po kliknięciu przycisku OK, nie ma potrzeby przekierowywania do ustawień, wystarczy użyć mojego kodu jako

Uwaga: ta linia kodu automatycznie otwiera okno dialogowe, jeśli lokalizacja nie jest włączona. Ten fragment linii jest również używany w Mapach Google

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


LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;

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

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    mGoogleApiClient.connect();

}

@Override
public void onConnected(Bundle bundle) {

    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(30 * 1000);
    mLocationRequest.setFastestInterval(5 * 1000);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest);
    builder.setAlwaysShow(true);

    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_LOCATION);
                    } catch (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
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    Log.d("onActivityResult()", Integer.toString(resultCode));

    //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(MainActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
                    break;
                }
                case Activity.RESULT_CANCELED:
                {
                    // The user was asked to change settings, but chose not to
                    Toast.makeText(MainActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
    }
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}
} 

Uwaga: ta linia kodu automatycznie otwiera okno dialogowe, jeśli lokalizacja nie jest włączona. Ten fragment linii jest również używany w Mapach Google

Czarny koń
źródło
1
ten kod działa dobrze, ale nie zapomnij o pozwoleniu na lokalizację i słoiku usługi odtwarzania w pliku gradle ...
Akash pasupathi
22

Od wersji Androida 4.4 nie można programowo włączać / wyłączać GPS. Jeśli wypróbujesz kod zaproponowany w tej odpowiedzi , zostanie uruchomiony wyjątek.

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
Amaury Medeiros
źródło
2
Czy to komentarz, czy też jakie jest rozwiązanie?
Shylendra Madda
@Shylendra Madda Nie ma rozwiązania umożliwiającego włączenie GPS. Możesz tylko wywołać odpowiednie okno dialogowe systemu.
Niesamowity styczeń
6

Aby programowo włączać i wyłączać GPS, potrzebujesz dostępu „root” i zainstalowanego BusyBox. Nawet z nimi zadanie nie jest trywialne.

Przykład jest tutaj: Dysk Google , Github , Sourceforge

Testowane na Androidach 2.3.5 i 4.1.2.

OGP
źródło
próbka nie jest już dostępna.
programista Androida
Oto najnowsze: rapidshare.com/files/1458124346/GPSToggler-20130222.7z Przypadkowo skasowałem starą wersję. BusyBox nie jest już wymagany.
OGP
nadal niedostępny. może użyć innej usługi przesyłania plików?
programista Androida,
Udostępniłem folder jako publiczny i zweryfikowany. Teraz można go pobrać. Również mój prywatny FTP tutaj: StackExchange: [email protected]
OGP
5

Powyższa poprawna odpowiedź jest bardzo stara, potrzebuje czegoś nowego, więc oto odpowiedź

Podobnie jak w ostatniej aktualizacji, mamy obsługę androidx, więc najpierw dołącz zależności w pliku build.gradle na poziomie aplikacji

implementation 'com.google.android.gms:play-services-location:17.0.0'

następnie dodaj w swoim pliku manifestu:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

nie zapomnij przyjąć zgody użytkownika na te uprawnienia, jeśli zwalniasz

teraz tutaj jest kod, po prostu go użyj

 protected void createLocationRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(5000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

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



    task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
        @Override
        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
            // All location settings are satisfied. The client can initialize
            // location requests here.
            // ...

            Toast.makeText(MainActivity.this, "Gps already open", 
                                          Toast.LENGTH_LONG).show();
            Log.d("location settings",locationSettingsResponse.toString());
        }
    });

    task.addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            if (e instanceof ResolvableApiException) {
                // Location settings are not satisfied, but this can be fixed
                // by showing the user a dialog.
                try {
                    // Show the dialog by calling startResolutionForResult(),
                    // and check the result in onActivityResult().
                    ResolvableApiException resolvable = (ResolvableApiException) e;
                    resolvable.startResolutionForResult(MainActivity.this,
                            REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException sendEx) {
                    // Ignore the error.
                }
            }
        }
    });
}


@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode==REQUEST_CHECK_SETTINGS){

        if(resultCode==RESULT_OK){

            Toast.makeText(this, "Gps opened", Toast.LENGTH_SHORT).show();
            //if user allows to open gps
            Log.d("result ok",data.toString());

        }else if(resultCode==RESULT_CANCELED){

            Toast.makeText(this, "refused to open gps", 
                                         Toast.LENGTH_SHORT).show();
            // in case user back press or refuses to open gps
            Log.d("result cancelled",data.toString());
        }
    }
}

jeśli coś pójdzie nie tak, skontaktuj się ze mną

Mratyunjay Tripathi
źródło
2

Odpowiedź została opracowana w innym pytaniu, ale została zamknięta i chciałbym, aby społeczność również ją wypróbowała.

boolean gpsStatus = locmanager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsStatus) {
    Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network,gps");
}

Zobacz ten komentarz

To rozwiązanie wymagałoby uprawnień WRITE_SETTINGSi WRITE_SECURE_SETTINGS.

gobernador
źródło
@milind, przypuśćmy, że mam zrootowane urządzenie, co powinienem zrobić, aby użyć tego kodu? Próbowałem uzyskać uprawnienia roota dla aplikacji, ale to nie pomogło. ciągle mówi „Odmowa uprawnień: zapisywanie w bezpiecznych ustawieniach wymaga android.permission.WRITE_SECURE_SETTINGS”
programista Androida
@android Przeczytaj ostatnie zdanie tego postu. Użycie tej metody będzie wymagało android.permission.WRITE_SECURE_SETTINGSpozwolenia w pliku Manifest.
gobernador
1
wiem . już to dodałem. mówi mi, że mimo że jest już w manifeście.
programista Androida
więc jest to niemożliwe nawet dla zrootowanych urządzeń ?!
programista Androida
2

Może dzięki sztuczkom refleksyjnym w klasie android.server.LocationManagerService .

Jest też metoda (od API 8) android.provider.Settings.Secure.setLocationProviderEnabled

Damian Kołakowski
źródło
3
Ta Settings.Secureklasa wydaje się obiecująca, jednak pojawia się wyjątek bezpieczeństwa mówiący, że potrzebuję android.permission.WRITE_SECURE_SETTINGS i nadal otrzymuję błąd, nawet dodając to uprawnienie (i WRITE_SETTINGS również) do mojego manifestu. Ale wydaje się, że to dobry sposób na dalsze poszukiwania. Dzięki :)
maid450
WRITE_SECURE_SETTINGSma poziom ochrony, zgodnie zsystemOrSignature którym musisz uczynić tę aplikację aplikacją systemową, aby działała, o czym również wspomniano w tej odpowiedzi .
Flow
2

To najlepsze rozwiązanie oferowane przez Google Developers. Po prostu wywołaj tę metodę w onResume z onCreate po zainicjowaniu GoogleApiClient.

private void updateMarkers() {
    if (mMap == null) {
        return;
    }

    if (mLocationPermissionGranted) {
        // Get the businesses and other points of interest located
        // nearest to the device's current location.
         mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).build();
        mGoogleApiClient.connect();
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(10000);
        locationRequest.setFastestInterval(10000 / 2);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);


        LocationSettingsRequest.Builder builder = new LocationSettingsRequest
                .Builder()
                .addLocationRequest(mLocationRequest);
        PendingResult<LocationSettingsResult> resultPendingResult = LocationServices
                .SettingsApi
                .checkLocationSettings(mGoogleApiClient, builder.build());

        resultPendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
                final Status status = locationSettingsResult.getStatus();
                final LocationSettingsStates locationSettingsStates = locationSettingsResult.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 this can 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,
                                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
                        } 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;
                }

            }
        });


        @SuppressWarnings("MissingPermission")
        PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
                .getCurrentPlace(mGoogleApiClient, null);
        result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
            @Override
            public void onResult(@NonNull PlaceLikelihoodBuffer likelyPlaces) {
                for (PlaceLikelihood placeLikelihood : likelyPlaces) {
                    // Add a marker for each place near the device's current location, with an
                    // info window showing place information.
                    String attributions = (String) placeLikelihood.getPlace().getAttributions();
                    String snippet = (String) placeLikelihood.getPlace().getAddress();
                    if (attributions != null) {
                        snippet = snippet + "\n" + attributions;
                    }

                    mMap.addMarker(new MarkerOptions()
                            .position(placeLikelihood.getPlace().getLatLng())
                            .title((String) placeLikelihood.getPlace().getName())
                            .snippet(snippet));
                }
                // Release the place likelihood buffer.
                likelyPlaces.release();
            }
        });
    } else {
        mMap.addMarker(new MarkerOptions()
                .position(mDefaultLocation)
                .title(getString(R.string.default_info_title))
                .snippet(getString(R.string.default_info_snippet)));
    }
}

Uwaga: ta linia kodu automatycznie otwiera okno dialogowe, jeśli Locationnie jest włączone. Ten fragment linii jest również używany w Mapach Google

 status.startResolutionForResult(
 MainActivity.this,
 PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
AMAN SINGH
źródło
Co to jest mLocationPermissionGranted ?
b devloper,
to jest do sprawdzenia, czy zezwolenie zostało udzielone, czy nie dla lokalizacji. to jest run timepozwolenie udzielone.
AMAN SINGH
możesz również przejść, ustawiając po prostu wartość true, jeśli już udzieliłeś pozwolenia na urządzeniu pre-lollipop
AMAN SINGH
2

Ten kod działa na telefonach ROOTED:

public class MainActivity extends AppCompatActivity {

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

        String[] cmds = {"cd /system/bin" ,"settings put secure location_providers_allowed +gps"};
        try {
            Process p = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                os.writeBytes(tmpCmd + "\n");
            }
            os.writeBytes("exit\n");
            os.flush();
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }
}

Aby wyłączyć GPS, możesz użyć tego polecenia

settings put secure location_providers_allowed -gps

Możesz również przełączać dokładność sieci za pomocą następujących poleceń: do włączenia użytkowania:

settings put secure location_providers_allowed +network

a do wyłączenia możesz użyć:

settings put secure location_providers_allowed -network
DarwinFernandez
źródło
1

Od czasu opublikowania tego pytania sytuacja się zmieniła, teraz dzięki nowemu interfejsowi API usług Google możesz monitować użytkowników o włączenie GPS:

https://developers.google.com/places/android-api/current-place

Musisz poprosić o pozwolenie ACCESS_FINE_LOCATION w swoim manifeście:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Obejrzyj także ten film:

https://www.youtube.com/watch?v=F0Kh_RnSM0w

Hooman
źródło
Dzięki. Ale usług Google Play 7 można używać ze starymi wersjami Androida? (API 14 - 23)
JCarlosR
1

Ten działa dla mnie.

Jest prostsza niż odpowiedź Rj0078 w tym pytaniu ( https://stackoverflow.com/a/42556648/11211963 ), ale ta również zadziałała.

Pokazuje takie okno dialogowe:

wprowadź opis obrazu tutaj

(Napisane w Kotlinie)

    googleApiClient = GoogleApiClient.Builder(context!!)
        .addApi(LocationServices.API).build()
    googleApiClient!!.connect()
    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)

    result =
       LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
    result!!.setResultCallback { result ->
        val status: Status = result.status
        when (status.statusCode) {
            LocationSettingsStatusCodes.SUCCESS -> {
               // Do something
            }
            LocationSettingsStatusCodes.RESOLUTION_REQUIRED ->
                try {
                    startResolutionForResult(),
                    status.startResolutionForResult(
                        activity,
                        REQUEST_LOCATION
                    )
                } catch (e: SendIntentException) {
                }
            LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                // Do something
            }
        }
    }
Marci
źródło
0

Musisz tylko usunąć LocationListenerfromLocationManager

manager.removeUpdates(listener);
sass
źródło
-1

Użyj tego kodu Prosty i łatwy dostęp:

Uprawnienia:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Postępuj zgodnie z tym kodem, aby uzyskać programowy dostęp do GPS:

LocationManager locationManager ;
 boolean GpsStatus ;


            GPSStatus();

            if(GpsStatus == true)
            {
                textview.setText("Your Location Services Is Enabled");
            }else
                {textview.setText("Your Location Services Is Disabled");}

            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);


    public void GPSStatus(){
    locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    GpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} 
Gaurav Lambole
źródło