如何使用FusedLocationApi获取当前位置?完善权限检查及定位代码
完善FusedLocationApi的位置获取逻辑(含权限请求)
我来帮你把这段代码补全,实现完整的位置获取流程——从权限请求到用FusedLocationApi拿到设备位置,一步步来:
第一步:补全权限请求逻辑
你已经写了权限检查的判断,现在在if块里添加权限请求代码,同时处理用户的权限选择回调:
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001; private void setInitialLocation() { // 检查位置权限是否已授予 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 请求缺失的位置权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); return; } // 权限已授予,直接执行位置获取逻辑 getCurrentLocation(); } // 处理权限请求的回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { // 检查是否所有请求的权限都被用户授予 boolean allPermissionsGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allPermissionsGranted = false; break; } } if (allPermissionsGranted) { // 权限通过,开始获取位置 getCurrentLocation(); } else { // 用户拒绝权限,提示用户需要权限才能继续 Toast.makeText(this, "需要位置权限才能获取当前位置", Toast.LENGTH_SHORT).show(); } } }
第二步:实现FusedLocationApi的位置获取逻辑
首先要初始化GoogleApiClient(依赖Google Play Services),然后连接服务并获取位置,同时处理连接异常和位置为空的情况:
private GoogleApiClient mGoogleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化GoogleApiClient buildGoogleApiClient(); } // 构建GoogleApiClient实例,绑定位置服务 protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(@Nullable Bundle bundle) { // GoogleApiClient连接成功,这里可以触发位置获取(也可以在setInitialLocation中调用) } @Override public void onConnectionSuspended(int i) { // 连接暂停,尝试重新连接 mGoogleApiClient.connect(); } }) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { // 连接失败,提示用户检查Google Play Services Toast.makeText(MainActivity.this, "Google Play Services连接失败", Toast.LENGTH_SHORT).show(); } }) .addApi(LocationServices.API) // 添加位置服务API .build(); } // 生命周期绑定:Activity启动时连接服务 @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } // 生命周期绑定:Activity停止时断开服务 @Override protected void onStop() { super.onStop(); if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } // 获取当前位置的核心方法 private void getCurrentLocation() { if (mGoogleApiClient.isConnected()) { try { // 获取最后已知位置 Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if (location != null) { // 成功获取到位置,处理坐标数据 double latitude = location.getLatitude(); double longitude = location.getLongitude(); Toast.makeText(this, "当前位置:" + latitude + ", " + longitude, Toast.LENGTH_LONG).show(); // 这里可以把位置数据传入你的业务逻辑 } else { // 没有获取到缓存位置,请求实时位置更新 requestLocationUpdates(); } } catch (SecurityException e) { // 理论上不会触发(已检查权限),但做异常兜底 e.printStackTrace(); Toast.makeText(this, "权限异常", Toast.LENGTH_SHORT).show(); } } else { // 服务未连接,先连接再获取位置 mGoogleApiClient.connect(); } } // 请求实时位置更新的方法 private void requestLocationUpdates() { LocationRequest locationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) // 高精度模式 .setInterval(10000) // 10秒更新一次 .setFastestInterval(5000); // 最快5秒更新一次 try { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, locationRequest, new LocationListener() { @Override public void onLocationChanged(Location location) { // 获取到实时位置更新 double latitude = location.getLatitude(); double longitude = location.getLongitude(); Toast.makeText(MainActivity.this, "更新位置:" + latitude + ", " + longitude, Toast.LENGTH_LONG).show(); // 获取到位置后可以停止更新 LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); } }); } catch (SecurityException e) { e.printStackTrace(); } }
第三步:添加必要依赖与权限声明
- 在
app/build.gradle中添加Google Play Services位置依赖:
dependencies { // 其他依赖... implementation 'com.google.android.gms:play-services-location:18.0.0' // 使用最新版本即可 }
- 在
AndroidManifest.xml中声明位置权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
额外说明
如果你的项目是基于较新的Android版本(比如Android 10+),需要后台位置权限的话,还需添加ACCESS_BACKGROUND_LOCATION权限,但前台获取位置一般不需要。另外,FusedLocationApi目前属于旧版API,Google推荐使用FusedLocationProviderClient,不过上面的代码完全兼容现有使用场景。
内容的提问来源于stack exchange,提问作者Faizan Abbas
相关产品推荐
相关产品推荐

