【问题标题】:How can I enable or disable the GPS programmatically on Android?如何在 Android 上以编程方式启用或禁用 GPS?
【发布时间】:2011-06-10 22:09:58
【问题描述】:

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

“出于安全/隐私原因,您不能,您必须转发到位置偏好屏幕并让用户启用/禁用它。”

我了解,但是我最近从市场上购买了Tasker,除了您可以使用它完成的许多其他事情外,您可以设置规则以在进入预定应用程序时自动启用 GPS,并在退出时禁用它(有关如何操作的教程,请参阅here,它可以正常工作!)并且此应用程序无法使用固件签名密钥进行签名,因为它适用于许多 android 版本和不同的设备,您甚至不需要扎根。

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

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

【问题讨论】:

  • 我想关闭再打开 GPS,这样我就可以对需要开启 GPS 的代码编写测试。没有模拟,因为 Android 让这些很痛苦

标签: android gps


【解决方案1】:

GPS 可以通过exploiting 电源管理器小部件中的一个错误来切换。请参阅此xda thread 进行讨论。

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

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.2.1 Android 手机上。很好的发现,本 H。
  • 这是一个非常糟糕的主意。一旦错误得到修复,您的漏洞利用将不再有效。最好将用户发送到设置应用程序。
  • 在 Android 2.3.6 中运行良好,但在 android 4.0.3 中无法运行。在 android 4.0.3 中启用或禁用的任何想法
  • 哈哈哈...这个漏洞在 4.2.2 中重新出现,看到它很惊讶..上帝!
【解决方案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 Documentation 。

这是为了帮助其他还在苦苦挣扎的人:

编辑:添加 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's no result 
         } 
    } 
} 

【讨论】:

  • 现在这个答案应该是被接受的。非常感谢阿克沙特!!
  • 需要 Google API 客户端集成,因此仅适用于特定用例的解决方案,不适合通用解决方案。
  • @DilroopSingh 你面临什么问题。?我正在使用相同的代码,并且效果很好。
  • 我们可以在不显示该builder的情况下实现这一目标吗?因为我需要打开gps而不显示任何警报。
  • @Punithapriya 那不可能。必须获得用户同意,因此必须显示该构建器。
【解决方案3】:

启用 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);

【讨论】:

  • GPS 会自动开启/关闭。
  • 这也有助于启用。 private void turnGPSOn(){ String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); if(!provider.contains("gps")){ //如果 gps 被禁用 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"));发送广播(戳); } }
  • 在 asamsung sII 上运行的 android 2.3.4 中,它会打开 gps 图标,而不会有效地激活 gps 传感器。但是,如果您选择以编程方式打开 GPS 传感器,它就会被识别。
  • android 4.0.4 - 仅启用 gps 通知。不是gps本身。所以它看起来像它,但实际上它不是
  • java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
【解决方案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) {}
}

【讨论】:

  • +1 用于提及此方法。它也应该与非 root 设备上的系统应用程序一起使用。
  • 这是正确的方法。适用于所有 Android 版本,无需任何技巧!
  • 关闭 gps 不起作用!!你能告诉我原因和可能的解决方案吗?
  • 现在 gps 正在完美关闭和打开,但 GPS 无法正常工作,即给出位置 lat long 0.0
  • 仅适用于系统aps
【解决方案5】:

而不是使用意图 Settings.ACTION_LOCATION_SOURCE_SETTINGS 您可以直接在您的应用中显示弹出窗口,例如 Google 地图和 Gps 上单击确定按钮,它们无需重定向到设置,只需使用我的代码即可

注意:如果Location没有打开,这行代码会自动打开对话框。这条线也用于谷歌地图

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

}
} 

注意:如果Location没有打开,这行代码会自动打开对话框。这条线也用于谷歌地图

【讨论】:

  • 这段代码运行良好,但不要忘记 gradle 文件中的位置权限和 playservice jar ...
【解决方案6】:

自 Android 4.4 版起,您无法以编程方式启用/禁用 gps。如果您尝试在this answer 上提出的代码,则会引发异常。

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

【讨论】:

  • 那么是评论还是解决方案?
  • @Shylendra Madda 没有启用 GPS 的解决方案。您只能调用相应的系统对话框。
【解决方案7】:

以上正确答案已经很老了,需要一些新的东西,所以这里是答案

与上次更新一样,我们支持 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());
        }
    }
}

如果有问题请联系我

【讨论】:

    【解决方案8】:

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

    样品在这里:Google Drive、Github、Sourceforge

    使用 2.3.5 和 4.1.2 Android 测试。

    【讨论】:

    【解决方案9】:

    已在另一个问题中开发了答案,但已关闭,我希望社区也可以尝试一下。

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

    见this comment

    此解决方案需要WRITE_SETTINGS 和WRITE_SECURE_SETTINGS 权限。

    【讨论】:

    • @milind ,假设我有一个根设备,我应该怎么做才能使用这个代码?我试图获得该应用程序的root权限,但没有帮助。它一直说“权限被拒绝:写入安全设置需要 android.permission.WRITE_SECURE_SETTINGS”
    • @android 阅读这篇文章的最后一句话。使用此方法需要 Manifest 中的android.permission.WRITE_SECURE_SETTINGS 权限。
    • 我知道。我已经添加了它。它告诉我,即使它已经在清单中。
    • 所以即使是有根设备也是不可能的?!
    【解决方案10】:

    也许在课堂上使用反射技巧android.server.LocationManagerService。

    另外,还有一个方法(从 API 8 开始)android.provider.Settings.Secure.setLocationProviderEnabled

    【讨论】:

    • 这个Settings.Secure 类看起来很有希望,但是我收到一个安全异常,说我需要android.permission.WRITE_SECURE_SETTINGS,即使将此权限(以及WRITE_SETTINGS)添加到我的清单中,我也会不断收到错误消息.但这似乎是继续搜索的好方法。谢谢:)
    • WRITE_SECURE_SETTINGS 有一个 protection level of systemOrSignature 您需要将该应用程序设为系统应用程序才能运行,which is also mentioned in this answer。
    【解决方案11】:

    这是Google Developers提供的最佳解决方案。只需在初始化GoogleApiClient后在onCreate的onResume中调用该方法即可。

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

    注意:如果Location没有开启,这行代码会自动打开对话框。 这条线也用于谷歌地图

     status.startResolutionForResult(
     MainActivity.this,
     PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    

    【讨论】:

    • 什么是 mLocationPermissionGranted?
    • 用于检查位置是否被授予权限。这是run time 授予的权限。
    • 如果您已经在 pre-lollipop 设备上授予权限,您也可以通过简单地将值设置为 true 来完成
    【解决方案12】:

    此代码适用于 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
    

    【讨论】:

      【解决方案13】:

      使用最新 API 的简短解决方案,来自 https://developer.android.com/training/location/change-location-settings.html。

      您将获得带有ok 按钮的漂亮Google AlertDialog,而无需进行任何设置。

      直截了当。我在 Fragment 中的代码:

      override fun onResume() {
              super.onResume()
              checkGPSEnabled()
          }
      
      private fun checkGPSEnabled() {
              val manager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager
              if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER).not()) {
                  turnOnGPS()
              }
          }
      
      private fun turnOnGPS() {
              val request = LocationRequest.create().apply {
                  interval = 2000
                  priority = LocationRequest.PRIORITY_HIGH_ACCURACY
              }
              val builder = LocationSettingsRequest.Builder().addLocationRequest(request)
              val client: SettingsClient = LocationServices.getSettingsClient(requireActivity())
              val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
              task.addOnFailureListener {
                  if (it is ResolvableApiException) {
                      try {
                          it.startResolutionForResult(requireActivity(), 12345)
                      } catch (sendEx: IntentSender.SendIntentException) {
                      }
                  }
              }.addOnSuccessListener {
                  //here GPS is On
              }
          }
      

      就是这样。只需复制和粘贴。您还需要: implementation 'com.google.android.gms:play-services-location:18.0.0' 并在清单中 &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;

      【讨论】:

        【解决方案14】:

        这个对我有用。

        在这个问题下,它比Rj0078's answer 更简单,但同样有效。

        它显示一个这样的对话框:

        (用 Kotlin 编写)

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

        【讨论】:

          【解决方案15】:

          自从发布此问题后情况发生了变化,现在有了新的 Google 服务 API,您可以提示用户启用 GPS:

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

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

          &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;

          另请观看此视频:

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

          【讨论】:

          • 谢谢。但是 Google Play Services 7 可以与旧的 android 版本一起使用吗? (API 14 - 23)
          【解决方案16】:

          这是一个更稳定的代码,适用于所有 Android 版本,也可能适用于新版本

          void checkGPS() {
              LocationRequest locationRequest = LocationRequest.create();
          
              LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
          
              SettingsClient settingsClient = LocationServices.getSettingsClient(this);
              Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(builder.build());
          
              task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
                  @Override
                  public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                      Log.d("GPS_main", "OnSuccess");
                      // GPS is ON
                  }
              });
          
              task.addOnFailureListener(this, new OnFailureListener() {
                  @Override
                  public void onFailure(@NonNull final Exception e) {
                      Log.d("GPS_main", "GPS off");
                      // GPS off
                      if (e instanceof ResolvableApiException) {
                          ResolvableApiException resolvable = (ResolvableApiException) e;
                          try {
                              resolvable.startResolutionForResult(ActivityMain.this, REQUESTCODE_TURNON_GPS);
                          } catch (IntentSender.SendIntentException e1) {
                              e1.printStackTrace();
                          }
                      }
                  }
              });
          }
          

          您可以在这里处理 GPS 状态变化

          @Override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          
              if(requestCode == Static_AppVariables.REQUESTCODE_TURNON_GPS) {
                  switch (resultCode) {
                      case Activity.RESULT_OK:
                          // GPS was turned on;
                          break;
                      case Activity.RESULT_CANCELED:
                          // User rejected turning on the GPS
                          break;
                      default:
                          break;
                  }
              }
          }
          

          【讨论】:

            【解决方案17】:

            您只需要从LocationManager 中删除LocationListener

            manager.removeUpdates(listener);
            

            【讨论】:

              【解决方案18】:

              使用此代码简单易用:

              权限:

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

              【讨论】:

                猜你喜欢
                • 2013-03-03
                • 1970-01-01
                • 2012-05-05
                • 1970-01-01
                • 2013-05-21
                • 1970-01-01
                • 2011-04-25
                • 1970-01-01
                相关资源
                最近更新 更多