android : 位置 api 请求 wifi
android : location api asking for wifi
这很奇怪。我的意思是,我有强大的网络,并且 GPS 已打开,但它仍然需要 Wifi!!
我正在使用新位置 Api 和 class FusedLocationProviderClient
。
这是我检查位置设置是否启用的方式:
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
选项,并像Google地图一样正常工作?
事实上,Google地图使用优先级PRIORITY_HIGH_ACCURACY
而且还有一次,第一个设置对话框已经显示,它不会要求第二次打开 Wifi。
FusedLocationProvider
使用 GPS
和 WIFI
的组合来获取您的位置。尤其是要求平衡模式的时候,两者都需要,否则都不行(GPS
占电,不会只靠它平衡)。尝试最大精度,然后不太可能使用它。或者,如果您确实需要 GPS
.
,则只需使用 GPS
提供程序
PRIORITY_BALANCED_POWER_ACCURACY
此优先级将具有粗略的精度,即仅从 wi-fi、蜂窝网络或蓝牙而非 GPS 获取位置。
如果设备没有 SIM 卡,则它需要 Wi-Fi 才能获取位置,否则它将不会呼叫 onLocationChanged
直到无法获取位置。
通过以下解决方案,我可以跳过此 Wifi 设置对话框。这不是一个完美的解决方案,只是我找到完美解决方案之前的一种解决方法。
问题是,即使在设置对话框上单击 "Ok" 后,它返回的结果也是 Activity.RESULT_CANCELLED
。原因是,Wifi 仍处于关闭状态。因此,作为快速修复,检查结果 Activity.RESULT_CANCELLED
,如果我可以通过检查 LocationSettingStates
.
获取位置
您可以使用我的 MyLocationUtils.java 和 Base 类 LocationActivity.java
或 LocationFragment.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();
}
}
这很奇怪。我的意思是,我有强大的网络,并且 GPS 已打开,但它仍然需要 Wifi!!
我正在使用新位置 Api 和 class FusedLocationProviderClient
。
这是我检查位置设置是否启用的方式:
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
选项,并像Google地图一样正常工作?
事实上,Google地图使用优先级PRIORITY_HIGH_ACCURACY
而且还有一次,第一个设置对话框已经显示,它不会要求第二次打开 Wifi。
FusedLocationProvider
使用 GPS
和 WIFI
的组合来获取您的位置。尤其是要求平衡模式的时候,两者都需要,否则都不行(GPS
占电,不会只靠它平衡)。尝试最大精度,然后不太可能使用它。或者,如果您确实需要 GPS
.
GPS
提供程序
PRIORITY_BALANCED_POWER_ACCURACY
此优先级将具有粗略的精度,即仅从 wi-fi、蜂窝网络或蓝牙而非 GPS 获取位置。
如果设备没有 SIM 卡,则它需要 Wi-Fi 才能获取位置,否则它将不会呼叫 onLocationChanged
直到无法获取位置。
通过以下解决方案,我可以跳过此 Wifi 设置对话框。这不是一个完美的解决方案,只是我找到完美解决方案之前的一种解决方法。
问题是,即使在设置对话框上单击 "Ok" 后,它返回的结果也是 Activity.RESULT_CANCELLED
。原因是,Wifi 仍处于关闭状态。因此,作为快速修复,检查结果 Activity.RESULT_CANCELLED
,如果我可以通过检查 LocationSettingStates
.
您可以使用我的 MyLocationUtils.java 和 Base 类 LocationActivity.java
或 LocationFragment.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();
}
}