繁体   English   中英

android:location api要求wifi

[英]android : location api asking for wifi

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

我正在使用新的位置Api和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选项,并像谷歌地图一样正常工作?

事实上,谷歌地图使用优先级PRIORITY_HIGH_ACCURACY ,仍然只显示第一个设置对话框,它不会要求第二次打开Wifi。

FusedLocationProvider使用GPSWIFI组合来获取您的位置。 特别是在要求平衡模式时,它需要或不能工作( GPS需要电源,因此它不会仅依靠它来实现平衡)。 尝试最大精度,然后不太可能使用它。 或者如果您真的想要GPS使用GPS提供商。

PRIORITY_BALANCED_POWER_ACCURACY

这个优先级将采用粗略的精度,仅从Wi-Fi,蜂窝网络或蓝牙获取位置,而不是从GPS获取。

如果设备没有SIM,它需要有Wi-Fi来获取位置,否则它将不会调用onLocationChanged直到无法获得位置。

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

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

您可以使用我的MyLocationUtils.java和Base类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();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM