如何获取 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)
    }
}
}