Как включить или отключить GPS программно на Android?

Я знаю, что вопрос о включении/выключении GPS программно на android был обсуждался и , и ответ всегда один и тот же:

"Вы не можете по соображениям безопасности/конфиденциальности, вам нужно переслать на экран настроек местоположения и позволить пользователю включать/отключать его".

Я понимаю, что, однако, я недавно купил Tasker с рынка и, помимо всего прочего, с которым вы можете справиться, вы может устанавливать правила для автоматического включения GPS при входе в заранее определенные приложения и отключить его при выходе (см. здесь для руководства о том, как это сделать, и это просто работает!), и это приложение не может быть подписано с ключом подписи прошивки, поскольку оно работает во многих версиях Android и разных устройствах, и вам даже не нужно укореняться.

Я хотел бы сделать это в своем приложении. Конечно, я не хочу взорвать конфиденциальность пользователей, поэтому сначала спрошу пользователя, хочет ли он включить его автоматически с помощью стандартного флажка "запомнить мое решение", и если он ответит "да", включите его.

Есть ли у кого-нибудь идеи или подсказки о том, как Tasker достигает этого?

Ответ 1

GPS может быть переключен на с использованием ошибки в виджере диспетчера мощности. см. этот поток xda для обсуждения.

вот пример кода, который я использую

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);
    }
}

используйте следующую команду, чтобы проверить, есть ли существующая версия виджета управления мощностью, которая позволит вам переключать 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
}

Ответ 2

Все эти ответы теперь не разрешены. Вот правильный вариант:

Для всех тех, кто все еще ищет ответ:

Вот как это делают OLA Cabs и другие подобные приложения.

Добавьте это в свой 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;
            }
        }
    });
}

Это внедренные методы:

@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

}

Ниже приведена Android-документация.

Это поможет другим парням, если они все еще борются:

Изменить: добавление комментария Irfan Raza для получения дополнительной справки.

@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 no result 
         } 
    } 
} 

Ответ 3

ENABLE GPS:

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

ОТКЛЮЧЕН GPS:

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

Ответ 4

Этот код работает с телефонами ROOTED , если приложение перемещено на /system/aps, и они имеют следующие разрешения в манифесте:

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

код

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) {}
}

Ответ 5

Начиная с версии 4.0 Android, вы не можете включить/отключить gps программно. Если вы попробуете код, предложенный в этом ответе, будет запущено исключение.

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE

Ответ 6

Вместо того, чтобы использовать намерение Settings.ACTION_LOCATION_SOURCE_SETTINGS, вы можете напрямую отображать всплывающие окна в своем приложении, такие как Google Map и Gps, при нажатии кнопки "ОК", их нет необходимости перенаправлять на настройки, просто вам нужно использовать мой код как

Примечание. Эта строка кода автоматически открывает диалоговое окно, если Местоположение не включено. Эта часть строки также используется в Google Map

 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) {

}
} 

Примечание. Эта строка кода автоматически открывает диалоговое окно, если Местоположение не включено. Эта часть строки также используется в Google Map

Ответ 7

Чтобы включить или выключить GPS, вам необходим "root" доступ и BusyBox. Даже с теми, задача не тривиальна.

Пример здесь: Google Диск, Github, Sourceforge

Протестировано с 2.3.5 и 4.1.2 андроидами.

Ответ 9

Ответ был разработан в другом вопросе, но он был закрыт, и я хотел бы, чтобы сообщество также опробовало его.

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

Смотрите этот комментарий

Для этого решения потребуются разрешения WRITE_SETTINGS и WRITE_SECURE_SETTINGS.

Ответ 10

Это лучшее решение, предоставляемое Google Developers. Просто вызовите этот метод в onResume onCreate после инициализации GoogleApiClient.

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

    if (mLocationPermissionGranted) {
        // Get the businesses and other points of interest located
        // nearest to the device 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 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)));
    }
}

Примечание. Эта строка кода автоматически открывает диалоговое окно, если " Location не включено. Этот фрагмент строки также используется в Google Map

 status.startResolutionForResult(
 MainActivity.this,
 PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);

Ответ 11

Этот код работает на телефонах с 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();
        }
    }
}

Для отключения GPS вы можете использовать эту команду вместо

settings put secure location_providers_allowed -gps

Вы также можете переключать точность сети, используя следующие команды: для включения используйте:

settings put secure location_providers_allowed +network

а для выключения вы можете использовать:

settings put secure location_providers_allowed -network

Ответ 12

Все изменилось, так как этот вопрос был отправлен, теперь с новым API сервисов Google, вы можете предложить пользователям включить GPS:

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

Вам нужно будет запросить разрешение ACCESS_FINE_LOCATION в манифесте:

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

Также смотрите это видео:

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

Ответ 13

Вам просто нужно удалить LocationListener из LocationManager

manager.removeUpdates(listener);

Ответ 14

Используйте этот код просто и легко получить доступ:

Разрешения:

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

Следуйте этому коду для программного доступа к 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);
} 

Ответ 15

Над правильным ответом очень старый, нужно что-то новое, вот ответ

Как и в последнем обновлении, у нас есть поддержка androidx, поэтому сначала включите зависимость в файл уровня приложения build.gradle.

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

затем добавьте в свой файл манифеста:

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

не забудьте принять согласие пользователя на эти разрешения, если вы выпускаете

теперь вот код, просто используйте его

 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());
        }
    }
}

если что-то пойдет не так, пожалуйста, пинг меня