Android使用GoogleMap实现定位及定位回正

Posted Tobey_r1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android使用GoogleMap实现定位及定位回正相关的知识,希望对你有一定的参考价值。

android使用GoogleMap实现定位及定位回正

关于:

  本篇内容主要介绍如何使用GoogleMap定位当前设备位置以及定位marker的实时方向
  官方Map for Android SDK使用文档

效果图

  定位效果:

地图归正效果图(5Mb的gif太难搞了,所以画面失真很严重,看个大概就好了):

配置

  首先要去谷歌地图平台点击开始Get started创建一个新项目:

  新建项目:

  然后选择左侧API与服务点击库按钮,选择Maps SDK for Android:

  然后在进入的新的页面选择启用api:

  回到项目,选择左侧 API与服务 然后点击 凭据 按钮,在点击新建凭据,选择API密钥

  这里我生产的api密钥是未加限制的(谁都可以访问,正式开发的时候要根据需要添加类似Android应用的限制)

在Android studio添加对应配置

项目的build文件里添加如下:

 //maps
 //好像这个playservice和map使用需要target指定31+,还有min的制定
    implementation 'com.google.android.gms:play-services-maps:18.0.2'
    implementation 'com.google.android.gms:play-services-location:19.0.1'

修改Androidmanifest.xml文件:
  添加定位权限申请:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  添加map的私钥以及pay service版本:

 <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="$your map key" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

开始使用

  第一步,创建一个空白activity,并修改布局(activity_google_maps.xml):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".GoogleMapsActivity">
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:id="@+id/map"/>
    
</androidx.constraintlayout.widget.ConstraintLayout>

  修改GoogleMapsActivity文件如下:

class GoogleMapsActivity : AppCompatActivity(), OnMapReadyCallback 
    //viewbinding
    private lateinit var binding: ActivityGoogleMapsBinding
    
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        binding = ActivityGoogleMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val mapFragment : SupportMapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    

    @SuppressLint("MissingPermission")
    override fun onMapReady(googleMap: GoogleMap) 
        map = googleMap
        googleMap.mapType = GoogleMap.MAP_TYPE_HYBRID //地图模式为混合,权限请求参考Activity Result API
        percheckRegister.requestPermissions(arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION))
        //请求定位权限
            if (it)
               
            
        
    
    

  此时如果上面配置一切正常的话,效果如下:

实现定位及定位移动方向

  这里我也直接贴代码了,修改如下:

class GoogleMapsActivity : AppCompatActivity(), OnMapReadyCallback 

    private lateinit var binding: ActivityGoogleMapsBinding
    //定位client
    private lateinit var fusedLocationProviderClient: FusedLocationProviderClient

    private var map:GoogleMap? = null

    private var currentLocation : Location? = null
    //当前定位marker点
    private var currentMarker: Marker? = null


    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        binding = ActivityGoogleMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        val mapFragment : SupportMapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    

    @SuppressLint("MissingPermission")
    override fun onMapReady(googleMap: GoogleMap) 
        map = googleMap
        googleMap.mapType = GoogleMap.MAP_TYPE_HYBRID
        percheckRegister.requestPermissions(arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION))
            if (it)
                googleMap.isIndoorEnabled = true //不影响
                startLocationUpdates()
            
        
    

    @SuppressLint("MissingPermission")
    private fun startLocationUpdates()
        fusedLocationProviderClient.requestLocationUpdates(
            LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)//设置高精度
                .setInterval(3000), //3秒一次定位请求
        locationCallback,
        Looper.getMainLooper())
    
    //定位回调
    private val locationCallback = object : LocationCallback()
        override fun onLocationResult(locationResult: LocationResult) 
                for (location in locationResult.locations)
                    drawLocationMarker(location,LatLng(location.latitude,location.longitude))
                
        
    

    @SuppressLint("NewApi")
    private fun drawLocationMarker(location: Location, latLng: LatLng) 
        if (currentLocation == null)//第一次定位画定位marker
            currentMarker = map?.addMarker(MarkerOptions()
                .position( latLng)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_vehicle_location))
            )
            map?.moveCamera(CameraUpdateFactory.newLatLngZoom(
                latLng,14f
            ))
        else
            val deltaTime = location.time - currentLocation!!.time
            //有方位精度
            if (location.hasBearingAccuracy())
                if (deltaTime <= 0)
                    map?.animateCamera(CameraUpdateFactory.newCameraPosition(
                        CameraPosition.Builder()
                            .target(latLng)
                            .zoom(map?.cameraPosition!!.zoom)
                            .bearing(location.bearing)
                            .build()
                    ))
                else
                    map?.animateCamera(CameraUpdateFactory.newCameraPosition(
                        CameraPosition.Builder()
                            .target(latLng)
                            .zoom(map?.cameraPosition!!.zoom)
                            .bearing(location.bearing)
                            .build()
                    ), deltaTime.toInt(),null)
                
                currentMarker?.rotation = 0f
            else
                if (deltaTime <= 0)
                    map?.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,map?.cameraPosition!!.zoom))
                else
                    map?.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,map?.cameraPosition!!.zoom), deltaTime.toInt(), null)
                
                //设置marker的指针方向
                currentMarker?.rotation = location.bearing - (map?.cameraPosition?.bearing ?:0f)
            

        
        currentLocation = location
    

    private fun stopLocationUpdates()
        fusedLocationProviderClient.removeLocationUpdates(locationCallback)
    

    override fun onDestroy() 
        super.onDestroy()
        stopLocationUpdates()

    

文末

到此本篇结束,有问题欢迎批评指正,觉得不错的也请点个赞,谢谢

以上是关于Android使用GoogleMap实现定位及定位回正的主要内容,如果未能解决你的问题,请参考以下文章

iOS之集成GoogleMap定位搜索注意事项

html5地理定位基于啥原理

获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)

Android实现百度离线地图+gps定位

Android 高德地图的定位,周边搜索

android 百度地图系列之地图初始化及定位