最完整Android地图开发指南:Google Maps Samples全解析
引言:解决Android地图开发的3大痛点
你是否还在为这些问题困扰?集成Google Maps SDK时遭遇配置迷宫、定位功能权限处理复杂、自定义地图样式无从下手?本文将通过Google官方Android Samples项目(https://gitcode.com/gh_mirrors/an/android-samples),带你系统掌握从基础显示到高级功能的全流程实现方案。
读完本文你将获得:
- 5大核心功能模块的完整实现代码
- 3种定位方案的权限处理模板
- Java/Kotlin双语言示例对比分析
- 从示例到生产环境的迁移指南
- 10个高频场景的最佳实践
快速上手:10分钟启动第一个地图应用
环境准备
# 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/an/android-samples
cd android-samples/tutorials/java/MapWithMarker
# 使用Android Studio打开项目
./gradlew build
配置API密钥
- 在Google Cloud控制台创建项目并启用Maps SDK for Android
- 创建API密钥并限制Android应用使用
- 将密钥添加到
local.properties:MAPS_API_KEY=你的API密钥
核心功能模块详解
1. 基础地图显示(MapWithMarker)
布局文件(activity_maps.xml)
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Java实现
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
Kotlin实现
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
}
2. 当前位置获取与显示(CurrentPlaceDetailsOnMap)
权限配置(AndroidManifest.xml)
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
定位实现核心代码
private FusedLocationProviderClient fusedLocationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
checkLocationPermission();
}
private void getDeviceLocation() {
try {
if (checkSelfPermission(ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Task<Location> locationResult = fusedLocationClient.getLastLocation();
locationResult.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
Location location = task.getResult();
if (location != null) {
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15));
mMap.addMarker(new MarkerOptions().position(currentLatLng).title("当前位置"));
}
}
});
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
3. 地图叠加层与几何图形(Polygons)
// 添加多边形
Polygon polygon = mMap.addPolygon(new PolygonOptions()
.add(new LatLng(37.772, -122.214),
new LatLng(21.291, -157.821),
new LatLng(-18.142, 178.431),
new LatLng(-27.467, 153.027))
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
// 添加圆形
Circle circle = mMap.addCircle(new CircleOptions()
.center(new LatLng(37.772, -122.214))
.radius(10000) // 米
.strokeWidth(2)
.strokeColor(Color.GREEN)
.fillColor(Color.argb(70, 150, 50, 50)));
4. 地图样式自定义(StyledMap)
private void loadMapStyle() {
try {
boolean success = mMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.map_style_night));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
}
res/raw/map_style_night.json示例:
[
{
"featureType": "all",
"elementType": "geometry",
"stylers": [
{
"color": "#242f3e"
}
]
},
{
"featureType": "all",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#746855"
}
]
}
]
Java与Kotlin示例对比分析
| 功能模块 | Java实现 | Kotlin实现 | 核心差异 |
|---|---|---|---|
| 基础地图 | MapsActivity.java | MapsActivity.kt | Kotlin使用属性委托和空安全 |
| 定位功能 | 需要手动处理空值 | 使用lateinit和协程 | 协程简化异步操作 |
| 多边形绘制 | 匿名内部类监听 | Lambda表达式 | 代码更简洁 |
| 样式设置 | 异常处理繁琐 | 使用runCatching | 函数式错误处理 |
实战进阶:从示例到生产环境
性能优化建议
- 地图生命周期管理
override fun onResume() {
super.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
override fun onDestroy() {
super.onDestroy()
mapView.onDestroy()
}
- 批量添加标记
MarkerOptions markerOptions = new MarkerOptions();
for (LocationData data : locationList) {
markerOptions.position(new LatLng(data.lat, data.lng))
.title(data.name);
mMap.addMarker(markerOptions);
}
常见问题解决方案
| 问题 | 解决方案 | 示例代码 |
|---|---|---|
| 地图空白 | 检查API密钥和网络 | adb logcat | grep Google Maps |
| 定位失败 | 检查权限和Play服务 | 实现onRequestPermissionsResult |
| 内存泄漏 | 使用WeakReference | WeakReference<GoogleMap> mapRef = new WeakReference<>(mMap); |
学习路线图
总结与资源
通过本文学习,你已掌握Google Maps Android SDK的核心功能实现,包括基础地图显示、定位服务、图形绘制和样式自定义。建议继续深入官方文档和示例项目,探索导航、路线规划等高级功能。
相关资源:
- 完整示例代码:https://gitcode.com/gh_mirrors/an/android-samples
- API参考文档:https://developers.google.com/maps/documentation/android-sdk/reference
如果你觉得本文有帮助,请点赞收藏关注三连支持!下期将带来《Google Maps高级实战:自定义地图瓦片与实时轨迹》。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



