安卓 Google Maps 的启用和制作步骤

1. main

在国内选择的SDK可以是高德、百度、腾讯、xxxx等,但在国外,你首选是谷歌,因此要进行Google地图的开发你首先要解决下面三个问题

VPN
Google账号
信用卡
American Express(美国运通卡)
Discover(美国发现卡)
JCB(Japan Credit Bureau,日本国际信用卡)
MasterCard(万事达)
VISA(维萨)

2. Android 谷歌地图

https://developers.google.cn/maps/documentation/android-sdk?hl=zh-cn

一、设置Google Cloud 项目
二、项目配置
① 设置SDK
② 配置API密钥
③ 配置AndroidManifest.xml
三、添加地图
四、定位当前
① 请求定位权限
② 我的位置控件
③ 获取当前位置
五、配置地图
① xml配置地图
② 代码配置地图
③ 地图点击事件
④ 管理Marker
六、地址位置编码
① 坐标转地址
② 地址转坐标
七、源码

3. 源码

这里zhi贴上GoogleMapActivity的完整代码:

@SuppressLint("NewApi")
class GoogleMapActivity : AppCompatActivity(), OnMapReadyCallback, Geocoder.GeocodeListener {
private lateinit var binding: ActivityGoogleMapBinding
// 地图
private lateinit var map: GoogleMap
// Places API 的入口点。
private lateinit var placesClient: PlacesClient
// 融合位置信息提供程序的入口点。
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
// 最后已知位置
private var lastKnownLocation: Location? = null
// 标记
private var marker: Marker? = null
// 地理编码器
private var geocoder: Geocoder? = null
// 地址结果
private var addressesLiveData: MutableLiveData<List<Address>>
  = MutableLiveData()
  companion object {
  private val TAG = GoogleMapActivity::class.java.simpleName
  // 默认缩放
  private const val DEFAULT_ZOOM = 15
  // 权限请求码
  private const val LOCATION_PERMISSION_REQUEST_CODE = 9527
  // 未授予位置权限时使用的默认位置(澳大利亚悉尼)和默认缩放。
  private val defaultLocation = LatLng(-33.8523341, 151.2106085)
  }
  override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  enableEdgeToEdge()
  binding = ActivityGoogleMapBinding.inflate(layoutInflater)
  setContentView(binding.root)
  ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
  val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
  v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
  insets
  }
  initView()
  }
  /**
  * 初始化视图
  */
  private fun initView() {
  // 构造 PlacesClient
  Places.initialize(applicationContext, BuildConfig.MAPS_API_KEY)
  placesClient = Places.createClient(this)
  // 构造 FusedLocationProviderClient。
  fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
  val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
  mapFragment.getMapAsync(this)
  }
  /**
  * 检查权限
  */
  private fun checkPermission() {
  // 检查当前是否拥有精确位置或粗略位置权限
  if (ContextCompat.checkSelfPermission(
  this,
  Manifest.permission.ACCESS_FINE_LOCATION
  ) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
  this,
  Manifest.permission.ACCESS_COARSE_LOCATION
  ) == PackageManager.PERMISSION_GRANTED
  ) {
  // 权限已授予,可以进行定位操作
  Log.d(TAG, "checkPermission: 权限已授予")
  configMap()
  } else {
  Log.d(TAG, "checkPermission: 请求权限")
  // 请求权限
  ActivityCompat.requestPermissions(
  this,
  arrayOf(
  Manifest.permission.ACCESS_FINE_LOCATION,
  Manifest.permission.ACCESS_COARSE_LOCATION
  ),
  LOCATION_PERMISSION_REQUEST_CODE
  )
  }
  }
  /**
  * 地图就绪
  */
  override fun onMapReady(googleMap: GoogleMap) {
  map = googleMap
  // 检查权限
  checkPermission()
  }
  /**
  * 地图配置
  */
  @SuppressLint("MissingPermission")
  private fun configMap() {
  Log.d(TAG, "configMap: 地图配置")
  // 初始化地理编码器
  geocoder = Geocoder(this)
  // 编码结果
  addressesLiveData.observe(this) { addresses ->
  // 获取地址信息
  if (!addresses.isNullOrEmpty()) {
  val address = addresses[0]
  Log.d(TAG, "Address: ${address.latitude} ${address.longitude} ${address.countryName} ${address.adminArea} ${address.locality} ${address.thoroughfare} ${address.subThoroughfare}")
  }
  }
  map.apply {
  isMyLocationEnabled = true // 地图上启用“我的位置”图层
  // 当前位置图标的点击事件
  setOnMyLocationButtonClickListener {
  Log.d(TAG, "configMap: 点击位置图标")
  // 移除标点
  marker?.remove()
  marker = null
  return@setOnMyLocationButtonClickListener false
  }
  // 定位后的蓝点点击事件
  setOnMyLocationClickListener { location ->
  Log.d(TAG, "configMap: 点击我的位置 $location")
  Toast.makeText(this@GoogleMapActivity, "Current location:\n$location", Toast.LENGTH_LONG).show()
  }
  // 地图点击事件
  setOnMapClickListener { latLng ->
  changeMapCenter(latLng)
  }
  // 地图设置
  uiSettings.apply {
  isZoomControlsEnabled = true // 显示缩放按钮
  isMyLocationButtonEnabled = true // 显示定位按钮
  isCompassEnabled = true // 显示指南针
  isMapToolbarEnabled = true // 显示地图工具栏
  isRotateGesturesEnabled = true // 允许旋转手势
  isScrollGesturesEnabled = true // 允许滚动手势
  isTiltGesturesEnabled = true // 允许倾斜手势
  isZoomGesturesEnabled = true // 允许缩放手势
  isScrollGesturesEnabledDuringRotateOrZoom = true // 允许在旋转或缩放时滚动手势
  isIndoorLevelPickerEnabled = true // 显示室内层选择器
  }
  }
  // 获取当前位置
  getCurrentLocation()
  }
  /**
  * 获取当前位置
  */
  @SuppressLint("MissingPermission")
  private fun getCurrentLocation() {
  Log.d(TAG, "getCurrentLocation: 获取当前位置")
  fusedLocationProviderClient.lastLocation.addOnCompleteListener { task ->
  // 获取当前位置未成功
  if (!task.isSuccessful) {
  Log.d(TAG, "Current location is null. Using defaults.")
  Log.e(TAG, "Exception: %s", task.exception)
  // 设置默认位置
  changeMapCenter(defaultLocation)
  return@addOnCompleteListener
  }
  lastKnownLocation = task.result
  if (lastKnownLocation == null) return@addOnCompleteListener
  // 移动地图到当前位置
  changeMapCenter(LatLng(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude))
  }
  }
  /**
  * 改变地图中心
  */
  private fun changeMapCenter(latLng: LatLng) {
  // 移除标点
  marker?.remove()
  // 添加标点
  marker = map.addMarker(MarkerOptions()
  .title("Marker") // 设置标题
  .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_google)) // 设置自定义图标
  .alpha(0.7f) // 设置透明度
  .position(latLng) // 设置位置
  )
  // 获取详细位置信息
  // getDetailAddress(latLng)
  // 获取默认经纬度的地址信息
  getDetailLatLng()
  // 地图中移动到经纬度处
  map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM.toFloat()))
  }
  /**
  * 获取默认经纬度的地址信息
  */
  private fun getDetailLatLng(address: String = "悉尼歌剧院") {
  if (Build.VERSION.SDK_INT >
  = Build.VERSION_CODES.TIRAMISU) {
  geocoder?.getFromLocationName(address, 1, this@GoogleMapActivity)
  } else {
  addressesLiveData.postValue(geocoder?.getFromLocationName(address, 1))
  }
  }
  /**
  * 获取详情位置信息,获取国内位置会出现异常
  */
  private fun getDetailAddress(latLng: LatLng) {
  if (Build.VERSION.SDK_INT >
  = Build.VERSION_CODES.TIRAMISU) {
  geocoder?.getFromLocation(latLng.latitude, latLng.longitude, 1, this@GoogleMapActivity)
  } else {
  addressesLiveData.postValue(geocoder?.getFromLocation(latLng.latitude, latLng.longitude, 1))
  }
  }
  /**
  * 权限请求结果
  */
  override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
    LOCATION_PERMISSION_REQUEST_CODE ->
    {
    // 如果请求被取消,则结果数组为空
    if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    // 权限被授予,可以进行定位操作
    Log.d(TAG, "onRequestPermissionsResult: 权限被授予")
    configMap()
    } else {
    // 权限被拒绝,无法进行定位操作
    Log.d(TAG, "onRequestPermissionsResult: 权限被拒绝")
    Toast.makeText(this, "拒绝将无法使用定位功能", Toast.LENGTH_SHORT).show()
    finish()
    }
    }
    }
    }
    /**
    * 地理编码结果,经纬度坐标转地址
    */
    override fun onGeocode(addresses: MutableList<Address>
      ) {
      addressesLiveData.postValue(addresses)
      }
      }

Reference

https://blog.csdn.net/qq_38436214/article/details/140985527

https://developers.google.cn/maps/documentation/android-sdk?hl=zh-cn

posted @ 2025-09-17 21:50  yxysuanfa  阅读(20)  评论(0)    收藏  举报