如何获取 NMEA 消息 **RMC 或 **GGA 或 **GSA Android
How to get NMEA message **RMC or **GGA or **GSA Android
在这种情况下,在我们知道如何获取 NMEA 消息后,我遇到了如何获取 NMEA 消息的问题,消息如下所示
$GPGGA,073109.00,,,,,0,12,6.4,865.1,M,2.8,M,,*6B
$PGLOR,9,STA,073109.00,0.004,0.000,-2498,5,64,0,P,D,L,1,C,2,S,00100002,56,5,R,000833F4,TPEF,20,907631,LC,,,*64
$GPGSV,3,1,12,11,73,151,18,08,61,353,16,04,59,313,19,23,52,309,18*79
$GPGSV,3,2,12,01,37,182,15,22,34,193,15,27,31,019,26,03,31,220,15*77
$GPGSV,3,3,12,09,26,318,23,31,20,100,,14,16,146,19,16,04,027,*72
$GLGSV,2,1,07,68,43,211,15,81,34,040,21,69,33,280,15,67,12,163,18*69
$GLGSV,2,2,07,79,06,006,22,82,73,119,,83,34,192,*5D
$QZGSV,1,1,01,01,46,154,17*51
$GPGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*08
$GNGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*16
$GNGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*16
$QZGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*14
$IMGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*1B
$GPRMC,073109.00,V,,,,,,,240220,,,N*77
以及如何获取 NMEA 消息以获取 $--RMC、$--GGA、$--GSA
如果你好奇如何获取NMEA消息可以看看这个link可能有些人不知道如何获取最新的NMEA消息,我会解释一下
首先,您需要添加 2 个权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
你需要用工具 2 class 做两次 class 它看起来像这样
class NmeaActivity : AppCompatActivity(), LocationListener, OnNmeaMessageListener {
}
然后,您需要为权限和 LocationManager 创建 2 个变量
val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID = 0x10
lateinit var locationManager : LocationManager
var datanmea = ""
第三,您需要创建一个调用 NMEA 侦听器的方法,该方法的位置如下所示
private fun initGPSgettingLogic() {
this.locationManager =
this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val gpsEnabled: Boolean = locationManager.isProviderEnabled(
LocationManager.GPS_PROVIDER
)
if (gpsEnabled) { //GPS ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS ON :)")
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Permission is not granted
Log.d("NMEA_APP", javaClass.name + ":" + "Request Permission ")
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID)
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10000f, this)
locationManager.addNmeaListener(this)
} else { //GPS NOT ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS NOT ON")
}
}
第四,您需要调用 onNmeaMessage()
来获取 NMEA 消息我们可以通过实现 OnNmeaMessageListener
来获取 onNmeaMessage()
没有它我们无法调用该方法,代码看起来像这样
override fun onNmeaMessage(nmeamessage: String?, timestamp: Long) {
Log.d(
"NMEA_APP",
javaClass.name + ":" + "[" + timestamp + "]" + nmeamessage+ ""
)
sendData(nmeamessage)
}
消息在变量 onNmeaMessage(nmeamessage: String?, timestamp: Long)
上,我们只需要 nmeamessage 来获取消息并处理消息,我将它发送到方法 sendData()
,如果你想显示 NMEA 消息TextView 不处理您可以附加到 Textview 上的数据以显示所有消息 TextView.append(nmeamessage)
sendData()
看起来像这样
private fun sendData(nmea: String?) {
var data = nmea?.substringBefore(",")
var title = data?.substringAfter("$")
var gen = title?.substring(2,5)
if(gen == "GGA"){
datanmea = ""
datanmea += "$nmea\r\n"
}
if(gen == "GSA" || gen == "RMC"){
datanmea += "$nmea\r\n"
}
if(gen == "RMC"){
TextView.append(datanmea)
}
}
因为我们只关注 $ 我们需要在它之后剪切 ,
我们需要剪切 $
然后我们从 char 2 剪切到 5 如果我们找到 GGA,GSA , RMC 我们只需将它添加到变量 datanmea 上,一行中的消息将附加,因为 RMC 在最后一个地方我将在获取所有消息后附加到 TextView
对于最后一步,您需要在方法 onCreate()
上调用 initGPSgettingLogic()
这是完整的代码
@RequiresApi(Build.VERSION_CODES.N)
class NmeaActivity : AppCompatActivity(), LocationListener, OnNmeaMessageListener {
val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID = 0x10
lateinit var locationManager : LocationManager
var datanmea = ""
override fun onCreate(savedInstanceState: Bundle?) {
this.initGPSgettingLogic()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
) { // granted
this.initGPSgettingLogic()
} else { // denied,
}
return
}
}
}
private fun initGPSgettingLogic() {
this.locationManager =
this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val gpsEnabled: Boolean = locationManager.isProviderEnabled(
LocationManager.GPS_PROVIDER
)
if (gpsEnabled) { //GPS ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS ON :)")
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Permission is not granted
Log.d("NMEA_APP", javaClass.name + ":" + "Request Permission ")
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID)
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10000f, this)
locationManager.addNmeaListener(this)
} else { //GPS NOT ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS NOT ON")
}
}
override fun onLocationChanged(location: Location?) {
}
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
}
override fun onProviderEnabled(provider: String?) {
}
override fun onProviderDisabled(provider: String?) {
}
override fun onNmeaMessage(nmeamessage: String?, timestamp: Long) {
Log.d(
"NMEA_APP",
javaClass.name + ":" + "[" + timestamp + "]" + nmeamessage+ ""
)
sendData(nmeamessage)
}
private fun sendData(nmea: String?) {
var data = nmea?.substringBefore(",")
var title = data?.substringAfter("$")
var gen = title?.substring(2,5)
if(gen == "GGA"){
datanmea = ""
datanmea += "$nmea\r\n"
}
if(gen == "GSA" || gen == "RMC"){
datanmea += "$nmea\r\n"
}
if(gen == "RMC"){
TextView.append(datanmea)
}
}
}
在这种情况下,在我们知道如何获取 NMEA 消息后,我遇到了如何获取 NMEA 消息的问题,消息如下所示
$GPGGA,073109.00,,,,,0,12,6.4,865.1,M,2.8,M,,*6B
$PGLOR,9,STA,073109.00,0.004,0.000,-2498,5,64,0,P,D,L,1,C,2,S,00100002,56,5,R,000833F4,TPEF,20,907631,LC,,,*64
$GPGSV,3,1,12,11,73,151,18,08,61,353,16,04,59,313,19,23,52,309,18*79
$GPGSV,3,2,12,01,37,182,15,22,34,193,15,27,31,019,26,03,31,220,15*77
$GPGSV,3,3,12,09,26,318,23,31,20,100,,14,16,146,19,16,04,027,*72
$GLGSV,2,1,07,68,43,211,15,81,34,040,21,69,33,280,15,67,12,163,18*69
$GLGSV,2,2,07,79,06,006,22,82,73,119,,83,34,192,*5D
$QZGSV,1,1,01,01,46,154,17*51
$GPGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*08
$GNGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*16
$GNGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*16
$QZGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*14
$IMGSA,A,1,,,,,,,,,,,,,10.3,8.0,6.4*1B
$GPRMC,073109.00,V,,,,,,,240220,,,N*77
以及如何获取 NMEA 消息以获取 $--RMC、$--GGA、$--GSA
如果你好奇如何获取NMEA消息可以看看这个link可能有些人不知道如何获取最新的NMEA消息,我会解释一下 首先,您需要添加 2 个权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
你需要用工具 2 class 做两次 class 它看起来像这样
class NmeaActivity : AppCompatActivity(), LocationListener, OnNmeaMessageListener {
}
然后,您需要为权限和 LocationManager 创建 2 个变量
val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID = 0x10
lateinit var locationManager : LocationManager
var datanmea = ""
第三,您需要创建一个调用 NMEA 侦听器的方法,该方法的位置如下所示
private fun initGPSgettingLogic() {
this.locationManager =
this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val gpsEnabled: Boolean = locationManager.isProviderEnabled(
LocationManager.GPS_PROVIDER
)
if (gpsEnabled) { //GPS ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS ON :)")
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Permission is not granted
Log.d("NMEA_APP", javaClass.name + ":" + "Request Permission ")
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID)
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10000f, this)
locationManager.addNmeaListener(this)
} else { //GPS NOT ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS NOT ON")
}
}
第四,您需要调用 onNmeaMessage()
来获取 NMEA 消息我们可以通过实现 OnNmeaMessageListener
来获取 onNmeaMessage()
没有它我们无法调用该方法,代码看起来像这样
override fun onNmeaMessage(nmeamessage: String?, timestamp: Long) {
Log.d(
"NMEA_APP",
javaClass.name + ":" + "[" + timestamp + "]" + nmeamessage+ ""
)
sendData(nmeamessage)
}
消息在变量 onNmeaMessage(nmeamessage: String?, timestamp: Long)
上,我们只需要 nmeamessage 来获取消息并处理消息,我将它发送到方法 sendData()
,如果你想显示 NMEA 消息TextView 不处理您可以附加到 Textview 上的数据以显示所有消息 TextView.append(nmeamessage)
sendData()
看起来像这样
private fun sendData(nmea: String?) {
var data = nmea?.substringBefore(",")
var title = data?.substringAfter("$")
var gen = title?.substring(2,5)
if(gen == "GGA"){
datanmea = ""
datanmea += "$nmea\r\n"
}
if(gen == "GSA" || gen == "RMC"){
datanmea += "$nmea\r\n"
}
if(gen == "RMC"){
TextView.append(datanmea)
}
}
因为我们只关注 $ 我们需要在它之后剪切 ,
我们需要剪切 $
然后我们从 char 2 剪切到 5 如果我们找到 GGA,GSA , RMC 我们只需将它添加到变量 datanmea 上,一行中的消息将附加,因为 RMC 在最后一个地方我将在获取所有消息后附加到 TextView
对于最后一步,您需要在方法 onCreate()
initGPSgettingLogic()
这是完整的代码
@RequiresApi(Build.VERSION_CODES.N)
class NmeaActivity : AppCompatActivity(), LocationListener, OnNmeaMessageListener {
val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID = 0x10
lateinit var locationManager : LocationManager
var datanmea = ""
override fun onCreate(savedInstanceState: Bundle?) {
this.initGPSgettingLogic()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
) { // granted
this.initGPSgettingLogic()
} else { // denied,
}
return
}
}
}
private fun initGPSgettingLogic() {
this.locationManager =
this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val gpsEnabled: Boolean = locationManager.isProviderEnabled(
LocationManager.GPS_PROVIDER
)
if (gpsEnabled) { //GPS ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS ON :)")
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Permission is not granted
Log.d("NMEA_APP", javaClass.name + ":" + "Request Permission ")
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID)
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10000f, this)
locationManager.addNmeaListener(this)
} else { //GPS NOT ON
Log.d("NMEA_APP", javaClass.name + ":" + "GPS NOT ON")
}
}
override fun onLocationChanged(location: Location?) {
}
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
}
override fun onProviderEnabled(provider: String?) {
}
override fun onProviderDisabled(provider: String?) {
}
override fun onNmeaMessage(nmeamessage: String?, timestamp: Long) {
Log.d(
"NMEA_APP",
javaClass.name + ":" + "[" + timestamp + "]" + nmeamessage+ ""
)
sendData(nmeamessage)
}
private fun sendData(nmea: String?) {
var data = nmea?.substringBefore(",")
var title = data?.substringAfter("$")
var gen = title?.substring(2,5)
if(gen == "GGA"){
datanmea = ""
datanmea += "$nmea\r\n"
}
if(gen == "GSA" || gen == "RMC"){
datanmea += "$nmea\r\n"
}
if(gen == "RMC"){
TextView.append(datanmea)
}
}
}