自定義工具類-----GPS、網路定位
阿新 • • 發佈:2019-01-11
程式碼依舊是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 -- 許可權已開啟")
}
}
}