目前,我正在开发需要一定方向的GPS应用程序。当我添加nmea
侦听器时,它仅被调用一次。我正在使用this和this链接。但是问题在于,nmea侦听器似乎只能运行一次。
class MainActivity : AppCompatActivity() {
private lateinit var locationManager: LocationManager
private var mOnNmeaMessageListener: OnNmeaMessageListener? = null
private var mLegacyNmeaListener: NmeaListener? = null
companion object {
private const val PERMISSION_REQUEST_CODE = 1
var counter = 0
}
private fun nmeaProgress(rawNmea: String) {
println("it is $rawNmea")
//Here is the sample protocol example of //$GPRMC,061244.00,A,4120.913656,N,06914.245043,E,1.0,118.8,040719,4.6,E,A*3F
val rawNmeaSplit = rawNmea.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (rawNmeaSplit[0].equals("\$GPRMC", ignoreCase = true)) {
counter++
val myString = rawNmeaSplit[0] + " , " + rawNmeaSplit[1] + " , " + rawNmeaSplit[2] + " , " +
rawNmeaSplit[3] + " , " + rawNmeaSplit[4] + " , " + rawNmeaSplit[5] + " , " +
rawNmeaSplit[6] + " , " + rawNmeaSplit[7] + " , " + rawNmeaSplit[8] + " , " +
rawNmeaSplit[9] + " , " + rawNmeaSplit[10] + " , " + rawNmeaSplit[11] + " , " + rawNmeaSplit[12] + ", $counter"
message.text = myString
val latitude = "Latitude: ${rawNmeaSplit[3]}"
val longitude = "Longitude: ${rawNmeaSplit[5]}"
val velocity = "Speed : ${rawNmeaSplit[7]}"
val deg = "Degree : ${rawNmeaSplit[8]}"
lat.text = longitude
lng.text = latitude
speed.text = velocity
degree.text = deg
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init()
}
private fun init() {
val msg = "Data not received yet"
lat.text = msg
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
@SuppressLint("MissingPermission")
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (grantResults.size != permissions.size) {
Toast.makeText(this, "Please grant all permission", Toast.LENGTH_SHORT).show()
finish()
} else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0.0f, locationListener)
addNmeaListener()
}
}
private val locationListener: LocationListener = object : LocationListener {
override fun onLocationChanged(location: Location?) {
//Will be implemented later
}
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
//
}
override fun onProviderEnabled(provider: String?) {
//
}
override fun onProviderDisabled(provider: String?) {
//
}
}
override fun onResume() {
super.onResume()
requestUpdate()
}
private fun requestUpdate() {
val list = arrayListOf<String>()
if (ContextCompat.checkSelfPermission(
applicationContext,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
list.add(Manifest.permission.ACCESS_FINE_LOCATION)
} else if (ContextCompat.checkSelfPermission(
applicationContext,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
list.add(Manifest.permission.ACCESS_COARSE_LOCATION)
}
val array = arrayOfNulls<String>(list.size)
list.toArray(array)
if (list.isEmpty()) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0.0f, locationListener)
//setNmeaListener()
addNmeaListener()
} else {
ActivityCompat.requestPermissions(
this,
array,
PERMISSION_REQUEST_CODE
)
}
}
private fun addNmeaListener() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
addNmeaListenerAndroidN()
} else {
addLegacyNmeaListener()
}
}
@SuppressLint("MissingPermission")
@RequiresApi(api = Build.VERSION_CODES.N)
private fun addNmeaListenerAndroidN() {
if (mOnNmeaMessageListener == null) {
mOnNmeaMessageListener = OnNmeaMessageListener { message, timestamp ->
nmeaProgress(message)
}
}
locationManager.addNmeaListener(mOnNmeaMessageListener)
}
@SuppressLint("MissingPermission")
private fun addLegacyNmeaListener() {
if (mLegacyNmeaListener == null) {
mLegacyNmeaListener = NmeaListener { timestamp, nmea ->
nmeaProgress(nmea)
}
}
locationManager.addNmeaListener(mLegacyNmeaListener)
}
override fun onPause() {
super.onPause()
locationManager.removeUpdates(locationListener)
removeNmeaListener()
}
private fun removeNmeaListener() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (mOnNmeaMessageListener != null) {
locationManager.removeNmeaListener(mOnNmeaMessageListener)
}
} else {
if (mLegacyNmeaListener != null) {
locationManager.removeNmeaListener(mLegacyNmeaListener)
}
}
}
}
请注意,轴承不是解决方案
更新
我现在已经测试过,问题更加明确。它正在工作,并且可以完美地获取数据。更新UI(将数据设置为相应的TextView
)时会出现问题。如果GPS没有正确设置位置,则将解析输入的数据并将其放入TextView中。但是,当通过GPS设置位置时,UI不会更新。如果GPS再次搜索位置,则UI更新正常。我通过添加静态计数器和日志进行检查
运行正常
欢迎任何帮助或建议。预先谢谢你
答案 0 :(得分:0)
现在我开始知道解决方案了。问题在于nmea协议。 GPRMC
在位置不固定时使用。位置固定后,GPRMC
不再使用,可以参考GNRMC
协议。但是,人们应该关心哪个位置服务正在设置其位置(GPS
,GLONASS
,GALILEO
?)。在这种情况下,我可以自由使用GNRMC
,因为它广泛可用。