如何在Android上以编程方式启用或禁用GPS?

问题描述 投票:143回答:14

我知道关于在an​​droid qazxsw poi qazxsw poi has been discussed上以编程方式打开/关闭GPS的问题,答案总是一样的:

“出于安全/隐私原因,你不能转发到位置首选项屏幕,让用户启用/禁用它。”

我明白,不过我最近从市场上购买了many,而且你可以用它完成许多其他事情,你可以设置规则,在输入预先确定的应用程序时自动启用GPS并在退出时禁用它(请参阅times如何做的教程,它只是工作!)和这个应用程序无法使用固件签名密钥签名,因为它适用于许多Android版本和不同的设备,你甚至不需要扎根。

我想在我的应用程序中执行此操作。当然,我不想破坏用户隐私,因此我首先会询问用户是否要使用典型的“记住我的决定”复选框自动启用它,如果他回答是,则启用它。

有没有人对Tasker如何实现这一点有任何想法或线索?

android gps
14个回答
160
投票

可以通过Tasker切换GPS电源管理器小部件中的错误。看到这个here进行讨论。

这是我使用的一些示例代码

exploiting

使用以下内容测试电源控件小部件的现有版本是否允许您切换gps。

xda thread

2
投票

这是WRITE_SECURE_SETTINGS提供的最佳解决方案。在初始化android.server.LocationManagerService之后,只需在onCreate的onResume中调用此方法。

android.provider.Settings.Secure.setLocationProviderEnabled

注意:如果Google Developers未打开,则此行代码会自动打开对话框。这条线也用于谷歌地图

GoogleApiClient

2
投票

此代码适用于ROOTED手机:

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

要关闭GPS,您可以使用此命令

Location

您还可以使用以下命令切换网络准确度:打开使用:

 status.startResolutionForResult(
 MainActivity.this,
 PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);

关闭你可以使用:

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

1
投票

自问题发布以来,情况发生了变化,现在使用新的Google Services API,您可以提示用户启用GPS:

settings put secure location_providers_allowed -gps

您需要在清单中请求ACCESS_FINE_LOCATION权限:

settings put secure location_providers_allowed +network

另请观看此视频:

settings put secure location_providers_allowed -network


0
投票

你只需要从https://developers.google.com/places/android-api/current-place中删除<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

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

0
投票

使用此代码简单易用:

权限:

LocationListener

请遵循此代码以编程方式访问GPS:

LocationManager

67
投票

现在不允许所有这些答案。这是正确的:

对于那些仍在寻找答案的人:

以下是OLA Cabs和其他类似应用程序的用法。

在你的onCreate中添加它

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

这些是实现的方法:

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
}

这是同样的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; } } }); }

这是为了帮助其他人,如果他们还在挣扎:

编辑:添加Irfan Raza的评论以获得更多帮助。

@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

}

49
投票

启用GPS:

Android Documentation

禁用GPS:

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

28
投票

如果应用程序移动到Intent intent=new Intent("android.location.GPS_ENABLED_CHANGE"); intent.putExtra("enabled", true); sendBroadcast(intent); ,此代码适用于ROOTED手机,并且它们在清单中具有以下权限:

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

/system/aps

22
投票

从Android 4.4版开始,您无法以编程方式启用/禁用gps。如果您尝试在qazxsw poi上提出的代码,将触发异常。

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

20
投票

而不是使用意图Settings.ACTION_LOCATION_SOURCE_SETTINGS您可以直接显示在您的应用程序中弹出如谷歌地图和Gps点击确定按钮他们不需要重定向到设置只需你使用我的代码作为

注意:如果未打开“位置”,则此行代码会自动打开对话框。这条线也用于谷歌地图

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

注意:如果未打开“位置”,则此行代码会自动打开对话框。这条线也用于谷歌地图


6
投票

要以编程方式打开或关闭GPS,您需要“root”访问并安装BusyBox。即使有这些,任务也不是微不足道的。

样本在这里:this answerjava.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE 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) { } }

测试2.3.5和4.1.2机器人。


2
投票

在另一个问题中提出了答案,但它已经关闭了,我希望社区也能尝试一下。

Google Drive

Github

此解决方案需要Sourceforgeboolean gpsStatus = locmanager.isProviderEnabled(LocationManager.GPS_PROVIDER); if (!gpsStatus) { Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network,gps"); } 权限。


2
投票

也许在课堂上使用反射技巧this comment

此外,有一种方法(自API 8)WRITE_SETTINGS

© www.soinside.com 2019 - 2024. All rights reserved.