android - getSystemService(Context.LOCATION_SERVICE) 调用后出错

标签 android kotlin gps location

决定制作一个确定当前位置的应用程序。 为此,我创建了“GPSLocation”类,它负责处理与 GPS 相关的所有内容。

应用程序启动并正常工作,直到我通过按下按钮(“onButtonGPS”函数)调用此类中的函数。

在LogCat中可以看到错误发生在这一行:

val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

据我了解,该错误表明系统服务在“onCreate”方法之前不可用。我尝试将此方法插入到“GPSLocation”类中,并尝试了很多我在互联网上找到的其他方法,但问题无法解决。

MainActivity.kt

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.view.View

class MainActivity : AppCompatActivity() {

    val myGPSLocation = GPSLocation(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun onButtonGPS(view: View){
        myGPSLocation.setLocation()
    }
}

GPSLocation.kt

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.location.Criteria
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.widget.Toast

class GPSLocation(val myContext: Context) : AppCompatActivity(), LocationListener {


    val REQUEST_LOCATION = 2


    fun setLocation() {
        if (ActivityCompat.checkSelfPermission(myContext, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED
        && ActivityCompat.checkSelfPermission(myContext, Manifest.permission.ACCESS_COARSE_LOCATION)
        != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(myContext as Activity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION),
                REQUEST_LOCATION)
        }else{
            val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
            val criteria = Criteria()
            val provider = locationManager.getBestProvider(criteria, false)
            val location = locationManager.getLastKnownLocation(provider)
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0f, this)
            if (location != null){
                Toast.makeText(myContext, convertLocationToString(location.latitude, location.longitude), Toast.LENGTH_SHORT).show()
            }else{
                Toast.makeText(myContext, "Location not available!", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (requestCode == REQUEST_LOCATION) setLocation()
    }

    private fun convertLocationToString(latitude: Double, longitude: Double): String {
        val builder = StringBuilder()

        if (latitude < 0) builder.append("S ") else builder.append("N ")

        val latitudeDegrees = Location.convert(Math.abs(latitude), Location.FORMAT_SECONDS)
        val latitudeSplit = latitudeDegrees.split((":").toRegex()).dropLastWhile({it.isEmpty()}).toTypedArray()
        builder.append(latitudeSplit[0])
        builder.append("°")
        builder.append(latitudeSplit[1])
        builder.append("'")
        builder.append(latitudeSplit[2])
        builder.append("\"")
        builder.append("\n")

        if (longitude < 0) builder.append("W ") else builder.append("E ")

        val longitudeDegrees = Location.convert(Math.abs(longitude), Location.FORMAT_SECONDS)
        val longitudeSplit = longitudeDegrees.split((":").toRegex()).dropLastWhile({it.isEmpty()}).toTypedArray()
        builder.append(longitudeSplit[0])
        builder.append("°")
        builder.append(longitudeSplit[1])
        builder.append("'")
        builder.append(longitudeSplit[2])
        builder.append("\"")

        return builder.toString()
    }

    override fun onLocationChanged(p0: Location?) {
        setLocation()
    }

    override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {

    }

    override fun onProviderEnabled(p0: String?) {

    }

    override fun onProviderDisabled(p0: String?) {

    }

}

LogCat

04-02 23:07:04.529 17809-17809/com.example.testtskwheather E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.testtskwheather, PID: 17809
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
        at android.view.View.performClick(View.java:4633)
        at android.view.View$PerformClick.run(View.java:19330)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5356)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
        at android.view.View.performClick(View.java:4633)*
        at android.view.View$PerformClick.run(View.java:19330)*
        at android.os.Handler.handleCallback(Handler.java:733)*
        at android.os.Handler.dispatchMessage(Handler.java:95)*
        at android.os.Looper.loop(Looper.java:157)*
        at android.app.ActivityThread.main(ActivityThread.java:5356)*
        at java.lang.reflect.Method.invokeNative(Native Method)*
        at java.lang.reflect.Method.invoke(Method.java:515)*
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)*
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)*
        at dalvik.system.NativeStart.main(Native Method)*
     Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
        at android.app.Activity.getSystemService(Activity.java:4713)
        at com.example.testtskwheather.GPSLocation.setLocation(GPSLocation.kt:41)
        at com.example.testtskwheather.MainActivity.onButtonGPS(MainActivity.kt:84)
        at java.lang.reflect.Method.invokeNative(Native Method)*
        at java.lang.reflect.Method.invoke(Method.java:515)*
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)*
        at android.view.View.performClick(View.java:4633)*
        at android.view.View$PerformClick.run(View.java:19330)*
        at android.os.Handler.handleCallback(Handler.java:733)*
        at android.os.Handler.dispatchMessage(Handler.java:95)*
        at android.os.Looper.loop(Looper.java:157)*
        at android.app.ActivityThread.main(ActivityThread.java:5356)*
        at java.lang.reflect.Method.invokeNative(Native Method)*
        at java.lang.reflect.Method.invoke(Method.java:515)*
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)*
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)*
        at dalvik.system.NativeStart.main(Native Method)*
04-02 23:07:06.691 17809-17809/com.example.testtskwheather I/Process: Sending signal. PID: 17809 SIG: 9

最佳答案

您正在尝试使用尚未创建的Activity实例。
看,您有两个 Activity:MainActivityGPSLocationMainActivity 已启动,但 GPSLocation 尚未启动。在 setLocation 方法中,您使用 GPSLocation Activity 的实例,但该 Activity 未启动,未调用该 Activity 的 onCreate 方法。要启动 GPSLocation Activity ,您应该调用 startActivity 方法。 GPSLocation(this) 行是错误的,从不创建 Activity 本身的实例,总是调用 startActivity 方法。另外,我认为 GPSLocation 不应该扩展 Activity


如果您需要摆脱崩溃,请使用此行:

val locationManager = myContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager

关于android - getSystemService(Context.LOCATION_SERVICE) 调用后出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55483626/

相关文章:

java - 验证点是否在 3D 空间中的圆锥体内

android - 在 Android Studio 中打开时 Android Emulator 发出奇怪的声音

java - 将 java.util.function.Function 转换为 Kotlin 的函数式接口(interface)类型

ios - Kotlin Multi-platform Mobile 代码与 iOS 平台上编译的 Swift 代码不同吗?

kotlin - 在kotlin中使用elvis运算符时如何否定 bool 表达式?

android - 如何在 Android 上的 exif 数据中保存 GPS 坐标?

php - 从邮政编码php获取gps坐标

android - 以编程方式创建按钮或在 xml 中创建按钮之间是否存在性能差异?

android - 根据第一个自动完成 TextView 的值更新第二个自动完成 TextView

objective-c - 在 iPhone 屏幕上绘制罗盘方位