首页 > 解决方案 > 无法从 Activity 中的 Intent 获取数据

问题描述

我对 Kotlin 和 Android 开发非常陌生,真的很想涉足它。我正在做一个项目来帮助我理解和有目的的工作。目标很简单,一个 android 应用程序可以在一个活动中获取用户的位置,然后将其传递给我打算使用它的下一个活动(以经度和纬度的形式)。但是,我已经尝试了几个小时来让数据作为额外的传递。显示的错误是空指针:

 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.getStringExtra(java.lang.String)' on a null object reference
    at com.tba.mypoint_ofinterest.LocationInfo.<init>(LocationInfo.kt:11)

与此相关的两个文件是:

  1. AddLocation.kt - 这是我获取用户位置的地方。然后用户按下一个按钮:“btn_accept”,然后我希望它转到 LocationInfo.kt 活动。
  2. LocationInfo.kt-这是我要接收位置数据的地方,也是不断抛出错误消息的地方。

这是 AddLocation.kt 代码:

import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.*
import kotlinx.android.synthetic.main.activity_add_location.*


class AddLocation : AppCompatActivity() {

    //variables needed for location grab
    lateinit var fusedLocationProviderClient: FusedLocationProviderClient
    lateinit var locationRequest: LocationRequest
    lateinit var locationCallback: LocationCallback
    var REQUEST_CODE = 1000
    lateinit var userLocation: Location

    //Deal with permissions
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_CODE -> {
                if (grantResults.size > 0) {
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
                        Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show()
                    else
                        Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

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

        //Check for permission!

        if (ActivityCompat.shouldShowRequestPermissionRationale(
                this,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            )
        )
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                REQUEST_CODE
            )
        else {
            buildLocationRequest()
            buildLocationCallback()

            //Create fused provider client
            fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

            //get location

            //start getting location
            btnGetLocation.setOnClickListener(View.OnClickListener {
                if (ActivityCompat.checkSelfPermission(
                        this,
                        android.Manifest.permission.ACCESS_FINE_LOCATION
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    ActivityCompat.requestPermissions(
                        this,
                        arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                        REQUEST_CODE
                    )
                    return@OnClickListener
                }
                fusedLocationProviderClient.requestLocationUpdates(
                    locationRequest, locationCallback,
                    Looper.myLooper()
                )
                //make the button invisible after clicked
                btnGetLocation.visibility = View.INVISIBLE
            })


        }
        //Listen for clicking add location then turn off GPS and proceed to next view
        btn_accept.setOnClickListener {
            if (ActivityCompat.checkSelfPermission(
                    this,
                    android.Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                    REQUEST_CODE
                )

            }
            fusedLocationProviderClient.removeLocationUpdates(locationCallback)
            locationCallback = object : LocationCallback() {
                override fun onLocationResult(p0: LocationResult?) {
                    userLocation = p0!!.locations.get(p0!!.locations.size - 1) //get last location
                }
            }
            var long = userLocation.longitude
            var lat = userLocation.latitude
            addInfo(long,lat)
        }
    }

    private fun buildLocationCallback() {
        locationCallback = object : LocationCallback() {
            override fun onLocationResult(p0: LocationResult?) {
                var location = p0!!.locations.get(p0!!.locations.size - 1) //get last location
                userLocation = location
                txtLocation.text =
                    location.latitude.toString() + "/" + location.longitude.toString() + "and accuracy" + location.accuracy.toString()
            }
        }
    }

    private fun buildLocationRequest() {
        locationRequest = LocationRequest()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 5000
        locationRequest.fastestInterval = 3000
        locationRequest.smallestDisplacement = 10f
    }

    //This gives intent and takes the GPS data to the next view to be combined with user input
    fun addInfo(long:Double,lat:Double) {

        val infoIntent: Intent = Intent(this, LocationInfo::class.java).apply {
            putExtra("LAT_DATA", lat)
            putExtra("LONG_DATA",long)
        }

        startActivity(infoIntent)
    }


    //Stop getting location data if back button is pressed
    override fun onSupportNavigateUp(): Boolean {
        fusedLocationProviderClient.removeLocationUpdates(locationCallback)
        return super.onSupportNavigateUp()
    }


}

这是 LocationInfo.kt 代码:

import android.content.Intent
import android.location.Location
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_location_info.*

class LocationInfo : AppCompatActivity() {
    val longitude = intent.getStringExtra("LONG_DATA")
    val latitude = intent.getStringExtra("LAT_DATA")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_location_info)
        btnSaveLocation.setOnClickListener{view ->saveInfo(view)}
       textView2.text = longitude.toString()+"/"+latitude.toString()
    }
    fun saveInfo(x: View?){
        val saveIntent: Intent = Intent(this,MainActivity::class.java)
        startActivity(saveIntent)
    }
}

我认为我并不真正了解如何正确使用意图,或者我在某处错误地标记了位置数据。欢迎任何建议,谢谢

标签: androidkotlinandroid-intent

解决方案


intent问题是您甚至在调用之前尝试访问onCreate(),结果intentnull.

按照这个,

    class LocationInfo : AppCompatActivity() {
       private lateinit var longitude:Double
       private lateinit var latitude:Double

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_location_info)
            btnSaveLocation.setOnClickListener{view ->saveInfo(view)}

             longitude = intent.getDoubleExtra("LONG_DATA",0.0)
             latitude = intent.getDoubleExtra("LAT_DATA",0.0)

           textView2.text = longitude.toString()+"/"+latitude.toString()
        }
        fun saveInfo(x: View?){
            val saveIntent: Intent = Intent(this,MainActivity::class.java)
            startActivity(saveIntent)
        }
    }

您应该访问方法Intent中的onCreate()


推荐阅读