首页 > 解决方案 > getSystemService(Context.LOCATION_SERVICE) 调用后出错

问题描述

决定制作一个确定当前位置的应用程序。为此,我创建了“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?) {

    }

}

日志猫

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

标签: androidkotlingpslocation

解决方案


您正在尝试使用Activity尚未创建的实例。
看,你有两个Activity:MainActivityGPSLocation. MainActivity已经开始了,但是GPSLocation没有。在setLocation方法内部,您使用GPSLocation活动实例,但未启动onCreate此活动,未调用此活动的方法。要开始GPSLocation活动,您应该调用startActivity方法。线路GPSLocation(this)错了,永远不要创建活动本身的实例,总是调用startActivity方法。另外,我认为GPSLocation不应该扩展Activity.


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

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

推荐阅读