在不需要用户访问设置的情况下,通过编程实现启用高精度或省电的位置模式。

21
我为什么要问这个问题:(也是在应用程序中尝试的原因)
当我们在Lollipop中使用Google Maps时会发生这种情况。即使位置已禁用,用户从Maps应用程序输入后,也会以高精度模式开启,而无需访问设置。
类似的功能可以用于启用蓝牙,在我的应用程序中启动操作; 用户需要做出选择,但不需要重定向到设置,使用:
startActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE));

现在我们知道可以在BluetoothAdapter中找到,但是我们知道没有LocationAdapter,所以我查看了gms->LocationServices下的基本上所有Location API referencesandroid.location.LocationManager但似乎还没有像ACTION_REQUEST_ENABLE这样的可用选项。

希望有其他方法可以达到同样的效果,并且更多人尝试过。

请注意:
context.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));不是那样工作的。

3个回答

23

更新3:

提示用户更改位置设置 如评论中@patrickandroid所述,第二次更新的链接失效了

Google示例;安卓位置和选项--代码参考。

更新2:

Google示例;代码参考。

本示例基于该存储库中包含的“LocationUpdates”示例,并允许用户使用位置对话框更新设备的位置设置。

使用SettingsApi确保设备的系统设置正确配置为应用程序的位置需求。


更新1:

Google Play服务,版本7.0(2015年3月)发布...

位置设置 - 虽然FusedLocationProviderApi结合多个传感器为您提供最佳位置,但应用程序接收的位置精度仍然在很大程度上取决于设备上启用的设置(GPS、wifi、飞行模式和其他设置)。使用新的SettingsApi类,您可以打开一个位置设置对话框,其中显示一个触摸控件,用户可以在不离开应用程序的情况下更改其设置。

使用公共接口SettingsApi

  • 确定设备上是否启用了相关系统设置以执行所需的位置请求。
  • 可选地,调用对话框,允许用户通过单击一次来启用必要的位置设置。


以下是以前的内容,仅供参考:
更新/回答
对于所有寻找此答案的人,Google Play服务7.0
它添加了检测地点和连接附近设备的API,改进了移动广告、健身数据、位置设置等等。

在Google Play服务7.0中,我们引入了一种标准机制来检查给定LocationRequest的必要位置设置是否已启用。如果有可能的改进,您可以显示一个一键控件,让用户在不离开应用程序的情况下更改其设置。

exactly this

此API提供了一个很好的机会,可以为用户提供更好的体验,特别是如果位置信息对您的应用程序的用户体验至关重要,就像Google Maps集成位置设置对话框时一样,他们看到了用户数量的大幅增加。

来源: Android开发者博客:Google Play服务7.0-到处都是地方!

SDK即将推出!
我们将在未来几天内推出Google Play服务7.0。一旦推出完成,我们将更新此博客文章、发布文档并提供SDK。

实现后将更新编程位置。


我需要下载新的SDK,你能添加链接吗? - Ando Masahashi
基本上您的 SDK 管理器 -> Extras -> Google Play Services,更新它就会包含在您的库项目中。 - Pararth
以上第一个链接已经失效。 - patrick-fitzgerald
@patrickandroid 谢谢,链接已更新,我还没看过代码。 - Pararth

22

根据@user2450263的笔记,以下是一些片段:

/**
 * Prompt user to enable GPS and Location Services
 * @param mGoogleApiClient
 * @param activity
 */
public static void locationChecker(GoogleApiClient mGoogleApiClient, final Activity activity) {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);
    builder.setAlwaysShow(true);
    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(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(
                                activity, 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;
            }
        }
    });
}

并像这样使用:

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

    locationChecker(mGoogleApiClient, MyActivity.this);

基本上,您的用户将收到如下提示,他们可以在不进入设置的情况下启用高精度模式的位置功能。 Turn on GPS


googleclient api 已经停用,是否有其他解决方案?另外我想在不进入设置界面的情况下打开 GPS 并获取经纬度,请指导我如何实现。 - Adnan haider

2

我有一个解决方案,已在Android 6.0.1 Marshmallow上测试。在按钮事件OnClick中调用该函数:

private void openGPSSettings() {
    //Get GPS now state (open or closed)
    boolean gpsEnabled = Settings.Secure.isLocationProviderEnabled(getContentResolver(), LocationManager.GPS_PROVIDER);

    if (gpsEnabled) {
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, 0);
    } else {
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, 3);
    }
}

在Android设备上,需要启用USB调试或进行Root。在adb shell中执行以下命令(如果设备未Root,则需从连接USB的计算机上执行):

pm grant com.example.application.test android.permission.WRITE_SECURE_SETTINGS

在应用程序清单中添加以下权限:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

7
并非所有的手机都已取得Root权限。这并不是一个可行的解决方案。 - PsyGik
这在没有系统根权限的安卓6设备上不起作用,对吧?而且该应用程序也需要是一个系统应用程序,对吧?我只是说针对安卓6及以上版本的情况。 - prom85
1
为什么不可行?对我来说可以。我需要在测试中切换位置模式,所以我在未root的Galaxy S6上安装了我的应用程序,运行“adb shell pm grant <my package> android.permission.WRITE_SECURE_SETTINGS”,它完成了任务(手机第一次弹出对话框,但随后模式始终切换到“高精度”模式)。 - waggledans
对于大多数Android应用程序来说,这不是可行的解决方案。 - patrick-fitzgerald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接