現在把取得所在位置的功能加入天氣app吧
先宣告須要的變數
class MainActivity : AppCompatActivity(), ILocationPublisher {
private var PERMISSION_ID = 1000
lateinit var fusedLocationProviderClient: FusedLocationProviderClient
companion object {
lateinit var myLocation: String
}
...
然後在onCreate()呼叫取得位置的函數
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
requestPermission()
getLastLocation()
...
各函數當然要準備好
private fun checkPermission(): Boolean {
if (
ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
return true
}
return false
}
private fun requestPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION
),
PERMISSION_ID
)
}
private fun isLocationEnabled(): Boolean {
var locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER
)
}
private fun getLastLocation() {
if (checkPermission()) {
if (isLocationEnabled()) {
fusedLocationProviderClient.lastLocation.addOnCompleteListener { task ->
var location: Location? = task.result
if (location == null) {
newLocationData()
} else {
Log.d("Debug:", "Your Location:" + location.longitude)
myLocation = getCityName(
location.latitude,
location.longitude
)
}
}
} else {
Toast.makeText(this, "Please Turn on Your device Location", Toast.LENGTH_SHORT)
.show()
}
} else {
requestPermission()
}
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
var lastLocation: Location = locationResult.lastLocation
Log.d("Debug:", "your last last location: " + lastLocation.longitude.toString())
myLocation = getCityName(
lastLocation.latitude,
lastLocation.longitude
)
}
}
@SuppressLint("MissingPermission")
private fun newLocationData() {
var locationRequest = LocationRequest()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = 0
locationRequest.fastestInterval = 0
locationRequest.numUpdates = 1
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
fusedLocationProviderClient!!.requestLocationUpdates(
locationRequest, locationCallback, Looper.myLooper()
)
}
fun getCityName(lat: Double, long: Double): String {
var cityName: String = ""
var countryName = ""
var geoCoder = Geocoder(this, Locale.getDefault())
var Adress = geoCoder.getFromLocation(lat, long, 3)
cityName = if (Adress.get(0).adminArea.contains("台")) {
Adress.get(0).adminArea.replace("台", "臺", false)
} else {
Adress.get(0).adminArea
}
countryName = Adress.get(0).countryName
Log.d("Debug:", "Your City: " + cityName + " ; your Country " + countryName)
return cityName
}
//debug用,查看位置權限的取得狀態
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == PERMISSION_ID) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("Debug:", "You have the Permission")
}
}
}
要注意練習時getCityName()原本是給getLastLocation()中的textView
現在改爲設給一個companion object的變數myLocation,因爲還要給fragment用
然後geoCoder取得的城市名"台南"跟opendata的城市名"臺南"有差別
所以也要處理一下
再來想將retrofit取得的各城市資料清單與myLocation當前位置比對後,一開app就可顯示目前位置的天氣
但不知道爲何寫在onCreate()一開始沒法先取得myLocation的值
不知道是否與網路有關,一定有哪裏怪怪的...須要再了解
override fun onCreate() {
...
WeatherApi
.retrofitService
.getWeather(key = "rdec-key-123-45678-011121314")
.enqueue(object : retrofit2.Callback<WeatherData> {
override fun onFailure(call: Call<WeatherData>, t: Throwable) {
//Use Timber
Log.e("fail", t.message)
}
override fun onResponse(
call: Call<WeatherData>,
response: Response<WeatherData>
) {
//api response..
Log.d("success", response.toString())
if (response.isSuccessful) {
response.body()?.records?.location?.forEach {
Log.d("api", it.toString())
weatherList.add(it)
}
weatherList.forEach { location ->
if (location.locationName.contains(myLocation)) {
setQueryResult(location)
}
}
}
}
})
}
畫面稍加整理後,最後像這樣