in this case, I have a problem with how to get NMEA message after we know how to get an NMEA message, the message looks like this
$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
and how to get an NMEA message to get $--RMC, $--GGA, $--GSA
if you curious how to get NMEA message you can look on this link maybe some people don't know how to get NMEA in the latest way, and I will explain it for the first, you need to add 2 permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
twice you need to make a class with implement 2 class it looks like this
class NmeaActivity : AppCompatActivity(), LocationListener, OnNmeaMessageListener {
}
and after that, you need to make 2 variable that is for the permission and for LocationManager
val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION_ID = 0x10
lateinit var locationManager : LocationManager
var datanmea = ""
third, you need to make a method to call NMEA listener and the location the method will look like this
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")
}
}
forth, you need to call onNmeaMessage()
to get the NMEA message we can get onNmeaMessage()
by implementing the OnNmeaMessageListener
without it we can't call the method and the code looks like this
override fun onNmeaMessage(nmeamessage: String?, timestamp: Long) {
Log.d(
"NMEA_APP",
javaClass.name + ":" + "[" + timestamp + "]" + nmeamessage+ ""
)
sendData(nmeamessage)
}
the message is on variable onNmeaMessage(nmeamessage: String?, timestamp: Long)
we just need the nmeamessage to get the message and to get process the message I send it to method sendData()
, if you want to show the NMEA message on TextView without processing the data you can append on Textview to show all message TextView.append(nmeamessage)
the sendData()
looks like this
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)
}
}
because we just focus in $ we need to cut the ,
after it we need to cut the $
and then we cut from the char 2 to 5 and if we found GGA, GSA, RMC we just add it on variable datanmea and the message in one row will append, because RMC is on the last place I will append on TextView after getting all the message
for the last step, you need to call initGPSgettingLogic()
on method onCreate()
and here is the complete code
@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)
}
}
}