【问题标题】:android : location api asking for wifiandroid : 位置 api 请求 wifi
【发布时间】:2018-07-10 03:30:08
【问题描述】:

这很奇怪。我的意思是,我有强大的网络,并且 GPS 已打开,但它仍然要求 Wifi !

我正在使用 FusedLocationProviderClient 类的新 Location Api。

这就是我检查位置设置是否启用的方式:

private void checkIfLocationSettingsAreEnabled() {
    LocationRequest locationRequest = new LocationRequest();
    locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(5000);

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

    SettingsClient client = LocationServices.getSettingsClient(context);
    Task<LocationSettingsResponse> locationSettingsResponseTask = client.checkLocationSettings(builder.build());
    locationSettingsResponseTask.addOnSuccessListener(locationSettingsResponse -> {
        getLastKnownLocation();
    });
    locationSettingsResponseTask.addOnFailureListener(e -> {
        if (e instanceof ResolvableApiException) {
            myLocationListener.onResolutionNeeded(e);
        } else {
            myLocationListener.onLocationFailure(e);
        }
    });
}

使用上面的代码,我可以得到下图:

但是,点击确定后,我再次拨打checkIfSettingsAreEnabled(),这会显示另一个弹出窗口,如下所示:

我想知道为什么启用 Wifi 是强制性的,即使我在没有 Wifi 连接的沙漠野生动物园中!

有什么方法可以跳过这个Wifi选项,并像谷歌地图一样正常工作?

事实上,谷歌地图使用优先级PRIORITY_HIGH_ACCURACY,仍然有一次,第一次设置对话框已经显示,第二次没有要求打开Wifi。

【问题讨论】:

    标签: android android-location


    【解决方案1】:

    FusedLocationProvider 使用GPSWIFI 的组合来获取您的位置。尤其是在要求平衡模式时,它需要两者或不起作用(GPS 需要电源,所以它不会仅仅依靠它来平衡)。尝试最大精度,然后不太可能使用它。或者,如果您确实需要 GPS,请使用 GPS 提供程序。

    【讨论】:

      【解决方案2】:

      PRIORITY_BALANCED_POWER_ACCURACY

      此优先级将采用粗略的精度,仅从 wi-fi、蜂窝网络或蓝牙获取位置,而不是从 GPS。

      如果设备没有 SIM 卡,它需要有 wi-fi 才能获取位置,否则它不会调用 onLocationChanged 直到无法获取位置。

      【讨论】:

      • 那么,有什么方法可以跳过 Wifi 设置对话框选项?
      【解决方案3】:

      通过以下解决方案,我可以跳过此 Wifi 设置对话框。这不是一个完美的解决方案,而只是一个解决方法,直到我找到完美的解决方案。

      问题是,即使在“设置”对话框中单击“确定”后,它仍返回结果为 Activity.RESULT_CANCELLED。原因是,Wifi 仍然关闭。因此,作为一个快速修复,检查结果Activity.RESULT_CANCELLED,如果我可以通过检查LocationSettingStates 获得位置。

      您可以使用我的 MyLocationUtils.java 和基类 LocationActivity.javaLocationFragment.java。快乐编码..!!

      获取位置

      MyLocationUtils.java:

      public class MyLocationUtils {
      
          public static final int REQUEST_CODE_LOCATION_SETTINGS = 123;
      
          private static final int INTERVAL_IN_MS = 10000;
          private static final int FASTEST_INTERVAL_IN_MS = 5000;
          private static final int MAX_WAIT_TIME_IN_MS = 5000;
          private static final int NUMBER_OF_UPDATES = 1;
      
          private final MyLocationListener myLocationListener;
          private final Context context;
          private FusedLocationProviderClient mFusedLocationProviderClient;
          private LocationCallback mLocationCallback = new LocationCallback() {
              @Override
              public void onLocationResult(LocationResult locationResult) {
                  super.onLocationResult(locationResult);
      
                  Location location = null;
                  if (locationResult.getLocations().size() > 0) {
                      location = locationResult.getLocations().get(0);
                  }
      
                  myLocationListener.onLocationSuccess(location);
      
                  stopContinuousLocation();
              }
          };
      
          public MyLocationUtils(Context context, MyLocationListener myLocationListener) {
              this.context = context;
              this.myLocationListener = myLocationListener;
      
              initializeFusedLocationProviderClient();
          }
      
          private boolean checkIfRequiredLocationSettingsAreEnabled(Context context) {
              LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
              return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
          }
      
          private void initializeFusedLocationProviderClient() {
              mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
          }
      
          public void stopContinuousLocation() {
              mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
          }
      
          public void getLocation() {
              checkIfLocationSettingsAreEnabled();
          }
      
          private void checkIfLocationSettingsAreEnabled() {
              if (checkIfRequiredLocationSettingsAreEnabled(context)) {
                  getLastKnownLocation();
              } else {
                  LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
                  builder.addLocationRequest(getLocationRequest());
                  builder.setAlwaysShow(true);
      
                  SettingsClient client = LocationServices.getSettingsClient(context);
                  Task<LocationSettingsResponse> locationSettingsResponseTask = client.checkLocationSettings(builder.build());
                  locationSettingsResponseTask.addOnSuccessListener(locationSettingsResponse -> {
                      // All location settings are satisfied. The client can initialize
                      // location requests here.
                      // ...
                      getLastKnownLocation();
                  });
                  locationSettingsResponseTask.addOnFailureListener(e -> {
                      if (e instanceof ResolvableApiException) {
                          myLocationListener.onResolutionNeeded(e);
                      } else {
                          myLocationListener.onLocationFailure(e);
                      }
                  });
              }
          }
      
          @SuppressLint("MissingPermission")
          private void getLastKnownLocation() {
              Task<Location> locationTask = mFusedLocationProviderClient.getLastLocation();
              locationTask.addOnSuccessListener(location -> {
                  // Got last known location. In some rare situations this can be null.
                  if (location != null) {
                      myLocationListener.onLocationSuccess(location);
                  } else {
                      startContinuousLocation();
                  }
              });
              locationTask.addOnFailureListener(myLocationListener::onLocationFailure);
          }
      
          @SuppressLint("MissingPermission")
          private void startContinuousLocation() {
              mFusedLocationProviderClient.requestLocationUpdates(getLocationRequest(), mLocationCallback, Looper.getMainLooper())
                      .addOnFailureListener(myLocationListener::onLocationFailure);
          }
      
          private LocationRequest getLocationRequest() {
              LocationRequest locationRequest = new LocationRequest();
              locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
              locationRequest.setInterval(INTERVAL_IN_MS);
              locationRequest.setFastestInterval(FASTEST_INTERVAL_IN_MS);
              locationRequest.setNumUpdates(NUMBER_OF_UPDATES);
              locationRequest.setMaxWaitTime(MAX_WAIT_TIME_IN_MS);
              return locationRequest;
          }
      
          public void resolveLocationSettings(FragmentActivity fragmentActivity, Exception exception) {
              ResolvableApiException resolvable = (ResolvableApiException) exception;
              try {
                  resolvable.startResolutionForResult(fragmentActivity, MyLocationUtils.REQUEST_CODE_LOCATION_SETTINGS);
              } catch (IntentSender.SendIntentException e1) {
                  e1.printStackTrace();
              }
          }
      
          public interface MyLocationListener {
      
              void onLocationSuccess(Location location);
      
              void onResolutionNeeded(Exception exception);
      
              void onLocationFailure(Exception exception);
          }
      }
      

      BaseLocationActivity.java:

      public abstract class LocationActivity extends AppCompatActivity {
      
          private MyLocationUtils myLocationUtils;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              myLocationUtils = new MyLocationUtils(this, new MyLocationUtils.MyLocationListener() {
                  @Override
                  public void onLocationSuccess(Location location) {
                      if (shouldBeAllowedToProceed())
                          LocationActivity.this.onLocationSuccess(location);
                  }
      
                  @Override
                  public void onResolutionNeeded(Exception exception) {
                      exception.printStackTrace();
                      if (shouldBeAllowedToProceed())
                          LocationActivity.this.onResolutionNeeded(exception);
                  }
      
                  @Override
                  public void onLocationFailure(Exception exception) {
                      exception.printStackTrace();
                      if (shouldBeAllowedToProceed())
                          LocationActivity.this.onLocationFailure(exception);
                  }
              });
          }
      
          protected void getLocation() {
              myLocationUtils.getLocation();
          }
      
          protected void resolveLocationSettings(Exception exception) {
              myLocationUtils.resolveLocationSettings(this, exception);
          }
      
          @Override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              if (requestCode == MyLocationUtils.REQUEST_CODE_LOCATION_SETTINGS) {
                  final LocationSettingsStates locationSettingsStates = LocationSettingsStates.fromIntent(data);
                  switch (resultCode) {
                      case Activity.RESULT_OK:
                          onResolveLocationSettingOk();
                          break;
                      case Activity.RESULT_CANCELED:
                          // The user was asked to change settings, but chose not to, 
                          // or on Android Oreo 8.1 Wifi Settings were not satisfied inspite of clicking OK, that results on Activity.RESULT_CANCELED
                          onResolveLocationSettingCancelled(locationSettingsStates);
                          break;
                      default:
                          break;
                  }
              }
          }
      
          protected abstract void onResolveLocationSettingOk();
      
          protected void onResolveLocationSettingCancelled(LocationSettingsStates locationSettingsStates) {
              if (locationSettingsStates.isLocationPresent() && locationSettingsStates.isLocationUsable()) {
                  onResolveLocationSettingOk();
              }
          }
      
          private boolean shouldBeAllowedToProceed() {
              return getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED);
          }
      
          public abstract void onLocationSuccess(Location location);
      
          public abstract void onResolutionNeeded(Exception exception);
      
          public abstract void onLocationFailure(Exception exception);
      
          @Override
          public void onDestroy() {
              super.onDestroy();
              myLocationUtils.stopContinuousLocation();
          }
      }
      

      LocationFragment.java:

      public abstract class LocationFragment extends Fragment {
      
          private MyLocationUtils myLocationUtils;
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              myLocationUtils = new MyLocationUtils(context, new MyLocationUtils.MyLocationListener() {
                  @Override
                  public void onLocationSuccess(Location location) {
                      if (shouldBeAllowedToProceed())
                          LocationFragment.this.onLocationSuccess(location);
                  }
      
                  @Override
                  public void onResolutionNeeded(Exception exception) {
                      exception.printStackTrace();
                      if (shouldBeAllowedToProceed())
                          LocationFragment.this.onResolutionNeeded(exception);
                  }
      
                  @Override
                  public void onLocationFailure(Exception exception) {
                      exception.printStackTrace();
                      if (shouldBeAllowedToProceed())
                          LocationFragment.this.onLocationFailure(exception);
                  }
              });
          }
      
          protected void resolveLocationSettings(FragmentActivity appCompatActivity, Exception exception) {
              myLocationUtils.resolveLocationSettings(appCompatActivity, exception);
          }
      
          @Override
          public void onActivityResult(int requestCode, int resultCode, Intent data) {
              if (requestCode == MyLocationUtils.REQUEST_CODE_LOCATION_SETTINGS) {
                  final LocationSettingsStates locationSettingsStates = LocationSettingsStates.fromIntent(data);
                  switch (resultCode) {
                      case Activity.RESULT_OK:
                          onResolveLocationSettingOk();
                          break;
                      case Activity.RESULT_CANCELED:
                          // The user was asked to change settings, but chose not to
                          onResolveLocationSettingCancelled(locationSettingsStates);
                          break;
                      default:
                          break;
                  }
              }
          }
      
          protected abstract void onResolveLocationSettingOk();
      
          protected void onResolveLocationSettingCancelled(LocationSettingsStates locationSettingsStates) {
              if (locationSettingsStates.isLocationPresent() && locationSettingsStates.isLocationUsable()) {
                  onResolveLocationSettingOk();
              }
          }
      
          public void getLocation() {
              myLocationUtils.getLocation();
          }
      
          private boolean shouldBeAllowedToProceed() {
              return getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED);
          }
      
          public abstract void onLocationSuccess(Location location);
      
          public abstract void onResolutionNeeded(Exception exception);
      
          public abstract void onLocationFailure(Exception exception);
      
          @Override
          public void onDestroy() {
              super.onDestroy();
              myLocationUtils.stopContinuousLocation();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-03
        • 2016-09-24
        • 1970-01-01
        • 2019-12-15
        • 2018-08-15
        • 1970-01-01
        • 1970-01-01
        • 2020-02-20
        相关资源
        最近更新 更多