Поток данных следующий:
- внешний приемник GNSS отправляет предложения nmea о своем текущем местоположении через TCP
- приложение принимает их и анализирует каждое из них в com.mapbox.common.location.Location объект
- пользовательский DeviceLocationProvider, который я назвал ВнешнийReceiverDeviceLocationProvider, запускается каждый раз, когда новое местоположение поступает от синтаксического анализатора.
- Вы указываете Mapbox использовать ExternalReceiverDeviceLocationProvider в качестве выбранного DeviceLocationProvider:
Код: Выделить всё
MapboxNavigationApp.setup {
NavigationOptions.Builder(this).locationOptions(LocationOptions.Builder().locationProviderFactory({
request - > ExpectedFactory.createValue(ExternalReceiverDeviceLocationProvider(this))
}, LocationOptions.LocationProviderType.REAL).build()).build()
}
- Если вы выполнили шаг 4, то LocationObserver Mapbox будет зарегистрирован в качестве наблюдателя для ExternalReceiverDeviceLocationProvider new локации. LocationObserver, в свою очередь, будет прослушиваться NavigationLocationProvider Mapbox в вашей активности, чтобы обновить шайбу местоположения.
Код: Выделить всё
class ExternalReceiverDeviceLocationProvider(context: Context) : DeviceLocationProvider {
val logger = Logger(context, "nmea_data ${Random.nextInt()}")
private val observers = mutableListOf()
private var lastLocation: Location? = null
private var isActive: Boolean = false
private lateinit var socket: Socket
private lateinit var reader: SentenceReader
init {
startNMEAReader()
}
private fun startNMEAReader() {
socket = Socket()
val locProv = this
CoroutineScope(Dispatchers.IO).launch {
try {
val address = InetSocketAddress("192.168.234.108", 6500)
socket.connect(address, 5000)
println("Connected to NMEA source")
val inputStream = socket.getInputStream()
reader = SentenceReader(inputStream)
reader.addSentenceListener(CustomGGAListener(locProv, logger))
reader.start()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun addLocationObserver(observer: LocationObserver) {
observers.add(observer)
if (!isActive) {
isActive = true
}
}
override fun addLocationObserver(observer: LocationObserver, looper: Looper) {
observers.add(observer)
if (!isActive) {
isActive = true
}
}
override fun getLastLocation(callback: GetLocationCallback): Cancelable {
callback.run(lastLocation)
return Cancelable {
}
}
override fun removeLocationObserver(observer: LocationObserver) {
observers.remove(observer)
if (observers.isEmpty()) {
isActive = false
stopNMEAReader()
}
}
override fun removeLocationUpdates(pendingIntent: PendingIntent) {
}
override fun requestLocationUpdates(pendingIntent: PendingIntent) {
}
override fun getName(): String? {
return "Custom Device Location Provider"
}
fun updateLocation(latitude: Double, longitude: Double) {
val newLocation = Location.Builder().latitude(latitude).longitude(longitude).build()
lastLocation = newLocation
notifyObservers(newLocation)
}
private fun notifyObservers(location: Location) {
observers.forEach { observer ->
observer.onLocationUpdateReceived(listOf(location))
}
}
private fun stopNMEAReader() {
reader.stop()
socket.close()
}
}
Код: Выделить всё
class CustomGGAListener(
private val locationProvider: ExternalReceiverDeviceLocationProvider,
private val logger: Logger
) : AbstractSentenceListener() {
override fun sentenceRead(gga: GGASentence) {
val pos: Position = gga.position
val latitude = pos.latitude
val longitude = pos.longitude
logger.writeToFile("Positions from u-blox: $latitude, $longitude")
// Notify the CustomDeviceLocationProvider with the new location
locationProvider.updateLocation(latitude, longitude)
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... n-provider
Мобильная версия