安卓 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

浙公网安备 33010602011771号