要看天氣的話,理想的操作應該是app打開就可以看到目前所在地的情況
那就需要再來了解一下如何取得手機所在位置
先用一個小專案練習
首先在build.gradle加入
implementation "com.google.android.gms:play-services-location:17.0.0"
[取得裝置位置]的權限 https://developers.google.com/maps/documentation/android-sdk/location?hl=zh-tw
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
因爲須要使用網路取得裝置位置
所以也要加入[取得網路的權限]
<uses-permission android:name="android.permission.INTERNET" />
建立一個檢查是否有提供位置權限的函數
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
}
若CheckPermission()回傳沒有提供位置權限,則須要請求權限
建立一個請求權限的函數
var PERMISSION_ID = 1000 //可隨意自訂一個唯一的整數
fun requestPermission(){
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION,android.Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_ID
)
}
debug用
可override onRequestPermissionsResult,以查看位置權限的取得狀態
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")
}
}
}
fun isLocationEnabled():Boolean{
//this function will return to us the state of the location service
//if the gps or the network provider is enabled then it will return true otherwise it will return false
var locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER)
}
lateinit var fusedLocationProviderClient: FusedLocationProviderClient
lateinit var locationRequest: LocationRequest
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
}
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)
textView.text = "You Current Location is : Long: "+ location.longitude + " , Lat: " + location.latitude + "\n" + getCityName(location.latitude,location.longitude)
}
}
}else{
Toast.makeText(this,"Please Turn on Your device Location",Toast.LENGTH_SHORT).show()
}
}else{
requestPermission()
}
}
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()
)
}
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())
textView.text = "You Last Location is : Long: "+ lastLocation.longitude + " , Lat: " + lastLocation.latitude + "\n" + getCityName(lastLocation.latitude,lastLocation.longitude)
}
}
在newLocation()這裡,雖然已做了檢查,編譯器還是有提示錯誤
請教學長說,這樣應該還是可以編譯過,或是照編譯器的提示給annotation忽略這個錯誤@SuppressLint("MissingPermission")
前面已經取得位置的經緯度,接着要把這部份轉換爲城市名稱
private 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 = Adress.get(0).adminArea
countryName = Adress.get(0).countryName
Log.d("Debug:", "Your City: " + cityName + " ; your Country " + countryName)
return cityName
}
目前已大致完成,若要檢查app是否有取得位置權限,可覆寫onRequestPermissionsResult,再到logcat查看
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")
}
}
}
還有很多詳細的不了解...,不過想要先在天氣app中加入這個功能
先用了再說,之後再研究各部分的用意吧
參考(裡面的function命名用大寫開頭,實測編譯器會有點問題,要改小寫)
https://www.youtube.com/watch?v=vard0CUTLbA
https://doctorcodetutorial.blogspot.com/2020/05/android-simplest-way-to-get-user.html
在模擬器中要取得位置,似乎要先到control中SET LOCATION加入
不過位置好像不會隨着電腦網路改變
使用模擬器取得位置有問題的話,先在模擬器開啓一次google map再run程式
https://oldgrayduck.blogspot.com/2016/06/android-studio.html
https://www.itranslater.com/qa/details/2121832870753862656