You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过位置设置对话框获取位置更新及代码问题排查

排查Google Maps风格位置功能的Fragment代码问题

我帮你梳理下代码里的问题,以及需要补充的逻辑,让按钮点击和权限请求正常工作:

核心问题分析

你的代码已经能触发位置设置对话框,但点击按钮无响应、权限请求后没动作,主要是这几个地方没处理到位:

  • onActivityResult 里只留了RESULT_OK和RESULT_CANCELED的空分支,没有对用户取消对话框的情况做Toast提示
  • 权限申请成功后,没有编写获取当前位置的逻辑
  • onRequestPermissionsResult 里的权限处理逻辑太简略,拒绝权限时没有反馈,授权成功也没触发位置获取

具体错误点&修正方案

1. 补全onActivityResult的取消逻辑

当用户点击“不了,谢谢”(对应RESULT_CANCELED)时,需要弹出Toast说明位置权限的必要性:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode){
        case REQUEST_RESOLVE_ERROR:
            switch(resultCode){
                case Activity.RESULT_OK:
                    // 用户同意开启位置,触发权限检查和位置获取
                    checkPermissionAndGetLocation();
                    break;
                case Activity.RESULT_CANCELED:
                    // 用户取消操作,显示提示
                    Toast.makeText(getActivity(), "启用位置服务才能使用地图相关功能哦", Toast.LENGTH_SHORT).show();
                    break;
            }
            break;
    }
}

2. 完善权限请求后的处理逻辑

在onRequestPermissionsResult里,要区分权限通过、拒绝的情况,通过后立即获取当前位置:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case ACCESS_FINE_LOCATION_CODE:
            if(grantResults.length > 0){
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 权限获取成功,开始获取当前位置
                    getCurrentLocation();
                } else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    // 权限被拒绝,提示用户
                    Toast.makeText(getActivity(), "需要位置权限才能获取当前位置", Toast.LENGTH_SHORT).show();
                }
            }
            break;
    }
}

3. 补充获取当前位置的方法

添加一个专门获取当前位置的方法,在权限通过后调用:

private void getCurrentLocation() {
    if (mGoogleApiClient.isConnected()) {
        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (location != null) {
                // 这里拿到了当前位置,可以做后续处理,比如显示经纬度
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
                Toast.makeText(getActivity(), "当前位置:" + latitude + ", " + longitude, Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getActivity(), "暂时无法获取位置,请稍后重试", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

4. 优化权限检查的逻辑

把原来分散的权限检查逻辑抽成单独方法,方便复用:

private void checkPermissionAndGetLocation() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_FINE_LOCATION_CODE);
        } else {
            // 已经有权限,直接获取位置
            getCurrentLocation();
        }
    } else {
        // 低于Android 6.0,直接获取位置
        getCurrentLocation();
    }
}

然后把onConnected里的逻辑改成调用这个方法:

@Override
public void onConnected(@Nullable Bundle bundle) {
    // 先检查位置设置是否开启
    settingsRequest();
}

修正后的完整代码片段

public class Home extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    GoogleApiClient mGoogleApiClient;
    LocationRequest locationRequest;
    private static final int ACCESS_FINE_LOCATION_CODE = 3310;
    private static final int REQUEST_RESOLVE_ERROR = 555;

    public Home() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mGoogleApiClient.connect();
        return view;
    }

    @Override
    public void onStart() {
        super.onStart();
        if (mGoogleApiClient != null && !mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        settingsRequest();
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(getActivity(), "位置服务连接暂停", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Toast.makeText(getActivity(), "位置服务连接失败", Toast.LENGTH_SHORT).show();
    }

    private void settingsRequest() {
        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);

        final PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult result) {
                Status status = result.getStatus();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        checkPermissionAndGetLocation();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        try {
                            status.startResolutionForResult(getActivity(), REQUEST_RESOLVE_ERROR);
                        } catch (IntentSender.SendIntentException e) {
                            e.printStackTrace();
                        }
                        break;
                }
            }
        });
    }

    private void checkPermissionAndGetLocation() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_FINE_LOCATION_CODE);
            } else {
                getCurrentLocation();
            }
        } else {
            getCurrentLocation();
        }
    }

    private void getCurrentLocation() {
        if (mGoogleApiClient.isConnected()) {
            if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                if (location != null) {
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();
                    Toast.makeText(getActivity(), "当前位置:" + latitude + ", " + longitude, Toast.LENGTH_LONG).show();
                    // 这里可以把位置传递给地图控件或做其他业务处理
                } else {
                    Toast.makeText(getActivity(), "暂时无法获取位置,请稍后重试", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case ACCESS_FINE_LOCATION_CODE:
                if (grantResults.length > 0) {
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        getCurrentLocation();
                    } else {
                        Toast.makeText(getActivity(), "需要位置权限才能获取当前位置", Toast.LENGTH_SHORT).show();
                    }
                }
                break;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_RESOLVE_ERROR:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        checkPermissionAndGetLocation();
                        break;
                    case Activity.RESULT_CANCELED:
                        Toast.makeText(getActivity(), "启用位置服务才能使用地图相关功能哦", Toast.LENGTH_SHORT).show();
                        break;
                }
                break;
        }
    }
}

额外注意事项

  • 确保在AndroidManifest.xml中添加了位置权限声明:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  • 如果需要持续获取位置更新,可以在getCurrentLocation之后添加位置监听逻辑,使用LocationServices.FusedLocationApi.requestLocationUpdates

内容的提问来源于stack exchange,提问作者Digvijay Singh Thakur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:37:55