如何在Tab Fragment中为Google Map设置当前经纬度
Tab Fragment中Google Map加载当前设备位置的解决方案
看起来你已经成功在Tab Fragment里显示Google Map了,现在卡在了把设备当前经纬度同步到地图上对吧?问题出在你把定位逻辑放在了单独的Location Activity里,和地图Fragment完全脱节了。下面我会帮你把定位功能直接整合到TabMap Fragment中,实现加载当前位置的效果:
第一步:重构TabMap Fragment,整合定位逻辑
把原来的TabMap代码替换成下面的版本,这里直接加入了FusedLocationProvider的定位逻辑,和地图功能绑定在一起:
public class TabMap extends Fragment implements OnMapReadyCallback, LocationCallback { GoogleMap mGoogleMap; MapView mMapView; View mView; FusedLocationProviderClient fusedLocationProviderClient; LocationRequest locationRequest; private static final int REQUEST_CODE = 1000; public TabMap() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_tab_map, container, false); return mView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mMapView = mView.findViewById(R.id.map); if (mMapView != null) { mMapView.onCreate(null); mMapView.onResume(); mMapView.getMapAsync(this); } // 初始化定位相关组件 buildLocationRequest(); fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireActivity()); // 检查并申请定位权限 checkLocationPermission(); } // 配置定位请求参数:高精度、5秒更新一次 private void buildLocationRequest() { locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(5000); locationRequest.setFastestInterval(3000); } // 检查定位权限,没有的话申请 private void checkLocationPermission() { if (ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) { ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE); } else { // 有权限就开始请求位置更新 requestLocationUpdates(); } } // 向系统请求位置更新 private void requestLocationUpdates() { if (ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } fusedLocationProviderClient.requestLocationUpdates(locationRequest, this, Looper.getMainLooper()); } @Override public void onMapReady(GoogleMap googleMap) { MapsInitializer.initialize(getContext()); mGoogleMap = googleMap; googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); // 开启地图自带的"我的位置"蓝点(可选,这一步已经能显示当前位置) if (ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } mGoogleMap.setMyLocationEnabled(true); } // 当获取到位置更新时回调 @Override public void onLocationResult(@NonNull LocationResult locationResult) { super.onLocationResult(locationResult); if (locationResult == null || mGoogleMap == null) { return; } Location currentLocation = locationResult.getLastLocation(); if (currentLocation != null) { LatLng currentLatLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()); // 手动添加当前位置的标记(如果不需要可以去掉) mGoogleMap.addMarker(new MarkerOptions().position(currentLatLng).title("我的位置")); // 移动相机到当前位置,放大到15级 CameraPosition cameraPosition = CameraPosition.builder() .target(currentLatLng) .zoom(15) .bearing(0) .build(); mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); // 如果只需要获取一次位置,这里可以停止更新;如果要持续跟踪就删掉这行 fusedLocationProviderClient.removeLocationUpdates(this); } } // 权限申请结果回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { requestLocationUpdates(); } } } // Fragment暂停时停止位置更新,避免耗电 @Override public void onPause() { super.onPause(); if (fusedLocationProviderClient != null) { fusedLocationProviderClient.removeLocationUpdates(this); } } }
第二步:确认布局文件(无需大改)
你的现有布局没问题,确保MapView的id是@+id/map即可:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TabMap" android:background="#DBDBDB"> <com.google.android.gms.maps.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="60dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="10dp"/> </FrameLayout>
第三步:检查权限和依赖配置
确保你的AndroidManifest.xml里有这些配置:
<!-- 定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Google Maps API Key(替换成你自己的) --> <meta-data android:name="com.google.android.geo.API_KEY" android:value="你的Google Maps API Key"/>
同时在Module级别的build.gradle里添加必要的依赖:
implementation 'com.google.android.gms:play-services-maps:18.1.0' implementation 'com.google.android.gms:play-services-location:21.0.1'
关键点说明
- 把原来单独的
LocationActivity里的定位逻辑移到了TabMapFragment,这样地图和定位直接关联,不用跨组件传递数据。 - 开启了
setMyLocationEnabled(true),地图会自动显示当前位置的蓝点,这一步其实已经能满足基本需求,手动添加标记是可选的。 - 如果需要持续跟踪位置(比如导航),删掉
onLocationResult里的removeLocationUpdates即可;如果只需要加载一次当前位置,保留这行代码更省电。 - 处理了权限申请的完整流程,确保用户授予权限后才会请求位置。
内容的提问来源于stack exchange,提问作者Hansi
相关产品推荐
相关产品推荐

