栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 实现定位

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 实现定位

Android 实现定位 (kotlin描述)

​ 手机定位功能在人们的日常生活中,给人们(尤其是笔者这样的路痴)带来了极大的便利,而如今大部分安卓设备,已非复吴下阿蒙,不仅仅支持过去的GPS定位,还兼容了北斗、伽利略、GLONASS等全球卫星定位系统,以及网络定位技术。本文将介绍实时经纬度,以及海拔高度(波动较大,参考价值小)的获取。

确认手机是否开启“位置信息”

​ 当手机电量低,系统开启“省电模式”的时候,首当其冲的(多数情况下)就是“位置信息”功能,并且用户有的时候也会关闭系统的定位功能,届时所有app都无法获取定位信息,检查手机是否开启定位操作如下:

//这个是在Activity内的,context.getSystemService(LOCATION_SERVICE),不在Activity里面记得先拿到context
val mlocationManager=getSystemService(LOCATION_SERVICE) as LocationManager  
//以下是检查系统是否开启GPS权限,即“位置信息”。这个检查的是系统的,不是当前app是否获得权限,即使系统开启了定位,
//当前app仍然有可能没开,别搞混了
if (!mlocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
    //将前往“位置信息”开启的设置界面
    startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),0)
}
确认当前app是否具有定位权限:
val LOCATION_PERMISSION=1   //这个仅仅是跟后面返回时候的onRequestPermissionsResult配合,确认是不是自己的
                            //返回结果,取值的时候一定一定要取大等于0的,不然会翻车
//检查是否具有高精度的定位权限
val hasLocationPermission =checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
//如果权限获得,返回就会等于PackageManager.PERMISSION_GRANTED
if (hasLocationPermission != PackageManager.PERMISSION_GRANTED) {
    //requestPermissions是异步执行的,返回的结果会交到一个onRequestPermissionsResult方法里面处理
    //如果权限没获得就会弹窗请求获得权限
    requestPermissions(
        arrayOf(
            Manifest.permission.ACCESS_COARSE_LOCATION, //这里放要请求的权限列表
            Manifest.permission.ACCESS_FINE_LOCATION
        ),
        LOCATION_PERMISSION   //可能会多次调用权限获取弹窗,为了返回时候知道当前返回的是哪次请求,来做出不同的
    )                         //应对,这里传的requestCode就是用来区分不同的请求的
}
获取权限后的处理逻辑:
//这个跟上面那个方法↑↑↑是一一对应的。
//申请位置权限后,请求弹窗,用户请求的结果会在此返回,返回后刷新位置信息
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == LOCATION_PERMISSION) {//这个requestCode是用来区分此次返回是谁调用的
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "获取了权限", Toast.LENGTH_LONG).show()
            
            
            //成功获取定位权限后的刷新处理逻辑写在这
            
            
        }else{
            Toast.makeText(this, "你咋还拒绝了", Toast.LENGTH_LONG).show()
            
            
            //请求权限失败的处理逻辑写在这
            
            
        }
    }
}
设置查询条件:
val criteria = Criteria()
        // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细
        criteria.setAccuracy(Criteria.ACCURACY_FINE)
        // 设置是否要求速度
        criteria.speedRequired=false
//如果设置要求速度,那么就可以用:
//criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH)来设置速度的精度;
//Criteria.ACCURACY_HIGH:精度高,误差在100米内
//ACCURACY_MEDIUM精度中等,误差在100-500米之间
//ACCURACY_LOW精度低,误差大于500米
        // 设置是否允许运营商收费
        criteria.costAllowed=false
        // 设置是否需要方位信息
        criteria.bearingRequired=false
        // 设置是否需要海拔信息
        criteria.altitudeRequired=false
        // 设置对电源的需求
//Criteria.POWER_LOW:耗电低,Criteria.POWER_MEDIUM:中度耗电
//Criteria.POWER_HIGH:耗电高,但是精确度也高
        criteria.powerRequirement=Criteria.POWER_LOW

val bestProvider = mLocationManager.getBestProvider(criteria, true)

// 获取位置信息
        // 如果不设置查询要求,getLastKnownLocation方法传人的参数为LocationManager.GPS_PROVIDER
        val location = mLocationManager.getLastKnownLocation(bestProvider)
获取位置信息:

``

//获取位置Location对象
fun getLocation(locationManager: LocationManager): Location? {
    var location: Location? = null
    if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
        //没获得权限的处理逻辑写在这
        Toast.makeText(this, "无权限", Toast.LENGTH_LONG).show();
    } else if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        //没开GPS定位的处理逻辑写在这(可能开了数据/WiFi,则可以使用精度略低的网络定位)
        Toast.makeText(this, "没开GPS", Toast.LENGTH_LONG).show();
    } else {
        
       //如果是同时有GPS和网络定位的权限,但是当前用的是网络,就先试图切换回GPS,精度会比网络定位高
        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
        
        if (location == null) {//切换失败,基本上说明位置信息权限没开
               //则试图退而求其次通过网络来完成粗略定位
            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
            if (location == null) {   //连网络定位都没开(流量/WiFi都没开)
                //前往“设置”界面
                startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),0)
                Toast.makeText(this ,"请开启wifi或流量以实现网络定位",Toast.LENGTH_LONG).show();
            }
        }
    }
    return location
}

//获取经度: getLocation(locationManager)?.latitude
//获取纬度: getLocation(locationManager)?.longitude
//获取海拔: getLocation(locationManager)?.altitude

设置位置改变监听器:
val locationListener = object : LocationListener {
    override fun onLocationChanged(location: Location) {
        //位置改变的时候的处理逻辑写这
    }
  
     override fun onProviderEnabled(provider:String) {
         //从无定位权限,到有定位的切换过程,会触发这个函数。
         //provider有三个可能取值:LocationProvider.OUT_OF_SERVICE:在服务范围外
         //LocationProvider.TEMPORARILY_UNAVAILABLE:服务暂时不可用
         //LocationProvider.AVAILABLE:服务可用
     }
     override fun onProviderDisabled(provider:String) {
         //从有定位权限,到无定位的切换过程,会触发这个函数。
     }
}
把监听器放到LocationManager对象中:
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
val hasLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
        if ((locationManager != null) && ((hasLocationPermission == PackageManager.PERMISSION_GRANTED))) {
            locationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER,   //Provider类型:有四种:NETWORK_PROVIDER:网络定
                5000,        //刷新间隔         //位,GPS_PROVIDER:卫星定位,PASSIVE_PROVIDER:通过其他应用
                0F,       //                    //发出请求,被动更新。FUSED_PROVIDER:混合模式
                locationListener     //监听器
            )
        }

监听器在退出Activity时要删除:
override fun onPause() {
    super.onPause()
    if(locationManager!=null){
        locationManager.removeUpdates(locationListener)//去掉所有的更新状态的监听器 
    }
}

对应的,在进入Activity的时候,自然要把监听器加回来:

override fun onResume() {
   //挂上LocationListener, 在状态变化时刷新位置显示,因为requestPermissionss是异步执行的,所以要先确认是否有权限
    super.onResume()
    val hasLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
    if ((locationManager != null) && ((hasLocationPermission == PackageManager.PERMISSION_GRANTED))) {
        locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            5000,
            0F,
            locationListener
        )
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605758.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号