getSystemService(Context.LOCATION_SERVICE) 调用后出错

Error after getSystemService(Context.LOCATION_SERVICE) call

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

应用程序启动并正常工作,直到我通过按下按钮("onButtonGPS" 函数)从这个 class 调用一个函数。

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

val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

据我了解,该错误表示系统服务在 "onCreate" 方法之前不可用。我尝试将此方法插入 class "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 个尚未创建的实例。
看,你有两个 ActivityMainActivityGPSLocationMainActivity 已启动,但 GPSLocation 未启动。在 setLocation 方法中您使用了 GPSLocation activity 的实例,但是这个 activity 没有启动,这个 activity 的 onCreate 方法没有叫。要启动 GPSLocation 活动,您应该调用 startActivity 方法。行 GPSLocation(this) 是错误的,从不创建 activity 本身的实例,总是调用 startActivity 方法。另外,我认为 GPSLocation 不应该扩展 Activity.


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

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