代码依旧是kotlin编写,java类似
1、在清单文件里添加权限
<!--请求网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 这个权限用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2、新建工具类LocationUtils
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.util.Log
@SuppressLint("MissingPermission")
class LocationUtils private constructor(private val mContext: Context) {
private var locationManager: LocationManager? = null
private var locationProvider: String? = null
private var location: Location? = null
private val TAG = "LocationUtils -> baibai"
private var logStr: String? = null
/**
* LocationListern监听器
* 参数:地理位置提供器、监听位置变化的时间间隔、位置变化的距离间隔、LocationListener监听器
*/
private var locationListener: LocationListener = object : LocationListener {
/**
* 当某个位置提供者的状态发生改变时
*/
override fun onStatusChanged(provider: String, status: Int, arg2: Bundle) {
}
/**
* 某个设备打开时
*/
override fun onProviderEnabled(provider: String) {
}
/**
* 某个设备关闭时
*/
override fun onProviderDisabled(provider: String) {
}
/**
* 手机位置发生变动
*/
override fun onLocationChanged(location: Location) {
location.accuracy//精确度
Log.d(TAG, "手动位置发生变化 location ${location == null}")
setLog("手动位置发生变化 location ${location == null}")
setLocation(location)
}
}
init {
getLocation()
}
private fun getLocation() {
//1.获取位置管理器
locationManager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
//2.获取位置提供器,GPS或是NetWork
val providers = locationManager!!.getProviders(true)//如果是这个获得的是 [passive] 一个(返回的是有效的供应商列表)
// val providers = locationManager!!.allProviders//得到 [passive, gps, network] 三个(返回的是所有的供应商列表)
Log.d(TAG, providers.toString())
setLog(providers.toString())
locationProvider = when {
//如果设备rom没有添加相关服务,把这个分支去掉,即选择的是GPS定位
providers.contains(LocationManager.NETWORK_PROVIDER) -> {//如果是网络定位(基站或wifi)//baibai
Log.d(TAG, "当前是网络定位")
getLog("当前是网络定位")
LocationManager.NETWORK_PROVIDER
}
providers.contains(LocationManager.GPS_PROVIDER) -> {//如果是GPS定位
Log.d(TAG, "当前是GPS定位")
setLog("当前是GPS定位")
LocationManager.GPS_PROVIDER
}
providers.contains(LocationManager.PASSIVE_PROVIDER) -> {//如果是passive定位(即被动方式,是位置更新监测器)
Log.d(TAG, "当前是passive定位")
setLog("当前是passive定位")
LocationManager.PASSIVE_PROVIDER
}
else -> {
Log.d(TAG, "没有可用的位置提供器")
setLog("没有可用的位置提供器")
return
}
}
// 需要检查权限,否则编译报错,想抽取成方法都不行,还是会报错。只能这样重复 code 了。
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return
}
//3.获取上次的位置,一般第一次运行,此值为null
val location = locationManager!!.getLastKnownLocation(locationProvider)
Log.d(TAG, "工具类getLocation里的location是否为空: ${location == null}")
setLog("工具类getLocation里的location是否为空: ${location == null}")
if (location != null) {
setLocation(location)
}
// 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
locationManager!!.requestLocationUpdates(locationProvider, 0, 0f, locationListener)
}
private fun setLocation(location: Location) {
this.location = location
val address = "纬度:" + location.latitude + ", 经度:" + location.longitude
Log.d(TAG, address)
}
/**
* 获取经纬度
*/
fun showLocation(): Location? {
return location
}
/**
* 移除定位监听
*/
fun removeLocationUpdatesListener() {
// 需要检查权限,否则编译不过
if (Build.VERSION.SDK_INT >= 23 &&
ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return
}
if (locationManager != null) {
uniqueInstance = null
locationManager!!.removeUpdates(locationListener)
}
logStr = null
}
/**
* 测试log
*/
private fun setLog(log: String){
logStr += log + "\n"
// return logStr as String
}
fun getLog(): String{
return logStr as String
}
/**
* 静态
*/
companion object {
@SuppressLint("StaticFieldLeak")
@Volatile
private var uniqueInstance: LocationUtils? = null
/**
* 采用Double CheckLock(DCL)实现单例
*/
fun getInstance(context: Context): LocationUtils? {
if (uniqueInstance == null) {
synchronized(LocationUtils::class.java) {
if (uniqueInstance == null) {
uniqueInstance = LocationUtils(context)
}
}
}
return uniqueInstance
}
}
}
3、xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="定位" />
<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#3f30"
android:text="定位信息" />
<TextView
android:id="@+id/tv_log"
android:layout_width="match_parent"
android:layout_height="350px" />
<View
android:layout_width="match_parent"
android:layout_height="2px"
android:layout_margin="10px"
android:background="#666" />
<Button
android:id="@+id/btn_remove"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20px"
android:text="移除监听" />
<Button
android:id="@+id/btn_permission"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="检查权限" />
</LinearLayout>
4、在activity里引用
import android.Manifest
import android.app.Activity
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.util.Log
import android.view.View
import bai.bai.bai.demo.R
import bai.bai.bai.demo.location.LocationUtils
import kotlinx.android.synthetic.main.activity_location.*
import android.widget.Toast
/**
* 定位界面
*/
class LocationActivity : Activity(), View.OnClickListener {
private var LOCATION_CODE = 111
private var mLocationUtils: LocationUtils? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_location)
initListener()
}
private fun initListener() {
btn_location.setOnClickListener(this)
btn_remove.setOnClickListener(this)
btn_permission.setOnClickListener(this)
}
override fun onClick(v: View?) {
when (v!!.id) {
R.id.btn_location -> {//定位
mLocationUtils = LocationUtils.getInstance(this)
val location = mLocationUtils!!.showLocation()
tv_log.text = mLocationUtils!!.getLog()
if (location != null) {
val address = "纬度:" + location.latitude + ", 经度:" + location.longitude
tv_info.text = address
} else {
tv_info.text = "location为空"
}
}
R.id.btn_remove -> {//取消定位监听
if (mLocationUtils != null) mLocationUtils!!.removeLocationUpdatesListener()
tv_log.text = ""
tv_info.text = ""
}
R.id.btn_permission -> {//检查权限
checkPermission()
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
LOCATION_CODE -> {
if (grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// 权限被用户同意。
// 执形我们想要的操作
Log.d("baibai", "onRequestPermissionsResult === 弹窗已同意")
} else {
Log.d("baibai", "onRequestPermissionsResult === 弹窗未同意")
// 权限被用户拒绝了。
//若是点击了拒绝和不再提醒
//关于shouldShowRequestPermissionRationale
// 1、当用户第一次被询问是否同意授权的时候,返回false
// 2、当之前用户被询问是否授权,点击了false,并且点击了不在询问(第一次询问不会出现“不再询问”的选项),之后便会返回false
// 3、当用户被关闭了app的权限,该app不允许授权的时候,返回false
// 4、当用户上一次不同意授权,没有点击“不再询问”的时候,下一次返回true
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) || !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
//提示用户前往设置界面自己打开权限
Toast.makeText(this, "请前往设置界面打开权限", Toast.LENGTH_SHORT).show()
return
}
}
}
}
}
/**
* 获取权限(如果没有开启权限,会弹出对话框,询问是否开启权限)
*/
private fun checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//没有开启权限,请求权限
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), LOCATION_CODE)
Log.d("baibai", "permission -- 权限未开启")
} else {
Log.d("baibai", "permission -- 权限已开启")
}
}
}