diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDataComputer.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDataComputer.kt
index e31b356a1b8..02e942f2a09 100644
--- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDataComputer.kt
+++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDataComputer.kt
@@ -101,9 +101,9 @@ object OBDDataComputer {
FUEL_LEFT_DISTANCE(true,
listOf(OBD_FUEL_LEVEL_COMMAND),
{ data -> OBDValue(OBD_FUEL_LEVEL_COMMAND, data) }),
- FUEL_LEFT_LITERS(false,
- listOf(OBD_FUEL_LEVEL_COMMAND),
- { data -> OBDValue(OBD_FUEL_LEVEL_COMMAND, data) }),
+// FUEL_LEFT_LITERS(false,
+// listOf(OBD_FUEL_LEVEL_COMMAND),
+// { data -> OBDValue(OBD_FUEL_LEVEL_COMMAND, data) }),
FUEL_LEFT_PERCENT(false,
listOf(OBD_FUEL_LEVEL_COMMAND),
{ data -> OBDValue(OBD_FUEL_LEVEL_COMMAND, data) }),
@@ -231,7 +231,7 @@ object OBDDataComputer {
null
}
- FUEL_LEFT_LITERS,
+// FUEL_LEFT_LITERS,
FUEL_LEFT_PERCENT -> {
if (locValues.size > 0) {
locValues[locValues.size - 1].doubleValue
diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDispatcher.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDispatcher.kt
index 1db5df88e74..0ec4bb8d2c5 100644
--- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDispatcher.kt
+++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/obd/OBDDispatcher.kt
@@ -141,11 +141,17 @@ object OBDDispatcher {
readStatusListener = listener
}
- fun setReadWriteStreams(readStream: Source, writeStream: Sink) {
+ fun setReadWriteStreams(readStream: Source?, writeStream: Sink?) {
scope?.cancel()
inputStream = readStream
outputStream = writeStream
- startReadObdLooper()
+ if(readStream != null && writeStream != null) {
+ startReadObdLooper()
+ }
+ }
+
+ fun stopReading() {
+ setReadWriteStreams(null, null)
}
private fun consumeResponse(command: OBDCommand, result: String) {
diff --git a/OsmAnd/res/layout/fragment_obd_main.xml b/OsmAnd/res/layout/fragment_obd_main.xml
index becb38e24b8..20e47cbfd34 100644
--- a/OsmAnd/res/layout/fragment_obd_main.xml
+++ b/OsmAnd/res/layout/fragment_obd_main.xml
@@ -1,286 +1,238 @@
-
-
-
-
-
-
-
-
+ android:layout_height="@dimen/toolbar_height" />
-
+ android:layout_height="60dp"
+ android:orientation="horizontal">
+
+
-
+
+
+
+ android:layout_height="60dp"
+ android:orientation="horizontal"
+ android:visibility="gone">
+
-
+
+
+ android:layout_height="60dp"
+ android:orientation="horizontal">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+ android:layout_height="match_parent"
+ android:layout_marginLeft="@dimen/content_padding_half" />
+
-
+
-
-
+
+
+
-
+
diff --git a/OsmAnd/res/layout/fragment_vehicle_metrics_settings.xml b/OsmAnd/res/layout/fragment_vehicle_metrics_settings.xml
new file mode 100644
index 00000000000..1213a304148
--- /dev/null
+++ b/OsmAnd/res/layout/fragment_vehicle_metrics_settings.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index f8c7df1b00f..f12d45423ac 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -63,6 +63,7 @@
OBD
Vehicle Metrics
+ Vehicle Metrics settings
%
RPM
rpm
diff --git a/OsmAnd/res/xml/vehicle_metrics_settings.xml b/OsmAnd/res/xml/vehicle_metrics_settings.xml
new file mode 100644
index 00000000000..f0b6fc4500c
--- /dev/null
+++ b/OsmAnd/res/xml/vehicle_metrics_settings.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/plugins/odb/VehicleMetricsPlugin.kt b/OsmAnd/src/net/osmand/plus/plugins/odb/VehicleMetricsPlugin.kt
index bf921a7cd48..fa7e9bef95b 100644
--- a/OsmAnd/src/net/osmand/plus/plugins/odb/VehicleMetricsPlugin.kt
+++ b/OsmAnd/src/net/osmand/plus/plugins/odb/VehicleMetricsPlugin.kt
@@ -7,6 +7,7 @@ import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.graphics.drawable.Drawable
import android.view.View
+import android.widget.Toast
import net.osmand.Location
import net.osmand.PlatformUtil
import net.osmand.aidlapi.OsmAndCustomizationConstants
@@ -18,6 +19,7 @@ import net.osmand.plus.plugins.odb.dialogs.OBDMainFragment
import net.osmand.plus.settings.backend.ApplicationMode
import net.osmand.plus.settings.backend.OsmandSettings
import net.osmand.plus.settings.backend.preferences.CommonPreference
+import net.osmand.plus.settings.fragments.SettingsScreenType
import net.osmand.plus.utils.AndroidUtils
import net.osmand.plus.utils.BLEUtils
import net.osmand.plus.views.mapwidgets.MapWidgetInfo
@@ -31,10 +33,8 @@ import net.osmand.plus.widgets.ctxmenu.data.ContextMenuItem
import net.osmand.shared.data.KLatLon
import net.osmand.shared.obd.OBDCommand
import net.osmand.shared.obd.OBDDataComputer
-import net.osmand.shared.obd.OBDDataField
import net.osmand.shared.obd.OBDDataFieldType.*
import net.osmand.shared.obd.OBDDispatcher
-import net.osmand.shared.obd.OBDResponseListener
import okio.IOException
import okio.sink
import okio.source
@@ -62,21 +62,29 @@ class VehicleMetricsPlugin(app: OsmandApplication) : OsmandPlugin(app),
widgetsInfos.add(creator.createWidgetInfo(speedWidget))
val rpmWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_RPM)
widgetsInfos.add(creator.createWidgetInfo(rpmWidget))
- val airIntakeTempWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_AIR_INTAKE_TEMP)
+ val airIntakeTempWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_AIR_INTAKE_TEMP)
widgetsInfos.add(creator.createWidgetInfo(airIntakeTempWidget))
- val ambientAirTempWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_AMBIENT_AIR_TEMP)
+ val ambientAirTempWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_AMBIENT_AIR_TEMP)
widgetsInfos.add(creator.createWidgetInfo(ambientAirTempWidget))
- val batteryVoltageWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_BATTERY_VOLTAGE)
+ val batteryVoltageWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_BATTERY_VOLTAGE)
widgetsInfos.add(creator.createWidgetInfo(batteryVoltageWidget))
- val fuelLevelWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_LEVEL)
+ val fuelLevelWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_LEVEL)
widgetsInfos.add(creator.createWidgetInfo(fuelLevelWidget))
- val fuelLeftDistanceWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_LEFT_DISTANCE)
+ val fuelLeftDistanceWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_LEFT_DISTANCE)
widgetsInfos.add(creator.createWidgetInfo(fuelLeftDistanceWidget))
- val fuelConsumptionRateWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_CONSUMPTION_RATE)
+ val fuelConsumptionRateWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_CONSUMPTION_RATE)
widgetsInfos.add(creator.createWidgetInfo(fuelConsumptionRateWidget))
- val fuelTypeWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_TYPE)
+ val fuelTypeWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_FUEL_TYPE)
widgetsInfos.add(creator.createWidgetInfo(fuelTypeWidget))
- val engineCoolantTempWidget: MapWidget = createMapWidgetForParams(mapActivity, WidgetType.OBD_ENGINE_COOLANT_TEMP)
+ val engineCoolantTempWidget: MapWidget =
+ createMapWidgetForParams(mapActivity, WidgetType.OBD_ENGINE_COOLANT_TEMP)
widgetsInfos.add(creator.createWidgetInfo(engineCoolantTempWidget))
}
@@ -185,6 +193,36 @@ class VehicleMetricsPlugin(app: OsmandApplication) : OsmandPlugin(app),
}
}
+ @SuppressLint("MissingPermission")
+ fun getPairedOBDDevicesList(activity: Activity): List {
+ var deviceList = listOf()
+ if (BLEUtils.isBLEEnabled(activity) && AndroidUtils.hasBLEPermission(activity)) {
+ val bluetoothAdapter = BLEUtils.getBluetoothAdapter(activity)
+ bluetoothAdapter?.let { adapter ->
+ adapter.cancelDiscovery()
+ val pairedDevices = adapter.bondedDevices.toList()
+ deviceList = pairedDevices.filter { device ->
+ device.uuids?.any { parcelUuid -> parcelUuid.uuid == uuid } == true
+ }.map { it.name ?: "Unknown Device" }
+ }
+
+ } else {
+ Toast.makeText(activity, "Please, grant BLUETOOTH_SCAN permission", Toast.LENGTH_LONG)
+ .show()
+ }
+ return deviceList
+ }
+
+ fun disconnect() {
+ socket?.apply {
+ if (isConnected) {
+ close()
+ socket = null
+ OBDDispatcher.stopReading()
+ }
+ }
+ }
+
@SuppressLint("MissingPermission")
fun connectToObd(activity: Activity, name: String): Boolean {
if (connectedDevice == null) {
@@ -206,7 +244,7 @@ class VehicleMetricsPlugin(app: OsmandApplication) : OsmandPlugin(app),
val obdDevice: BluetoothDevice? =
pairedDevices.find { it.name == name }
connectedDevice = obdDevice
- connectToDevice()
+ connectToDevice(activity)
}
} else {
AndroidUtils.requestBLEPermissions(activity)
@@ -221,7 +259,7 @@ class VehicleMetricsPlugin(app: OsmandApplication) : OsmandPlugin(app),
}
@SuppressLint("MissingPermission")
- private fun connectToDevice() {
+ private fun connectToDevice(activity: Activity) {
try {
socket = connectedDevice?.createRfcommSocketToServiceRecord(uuid)
socket?.apply {
@@ -230,18 +268,39 @@ class VehicleMetricsPlugin(app: OsmandApplication) : OsmandPlugin(app),
val input = inputStream.source()
val output = outputStream.sink()
OBDDispatcher.setReadWriteStreams(input, output)
+ app.runInUIThread {
+ Toast.makeText(
+ activity,
+ "Connected to ${connectedDevice?.name ?: "Unknown device"}",
+ Toast.LENGTH_LONG).show()
+ }
}
}
} catch (error: IOException) {
LOG.error("Can't connect to device. $error")
+ app.runInUIThread {
+ Toast.makeText(
+ activity,
+ "Can\'t connect to ${connectedDevice?.name ?: "Unknown device"}",
+ Toast.LENGTH_LONG).show()
+ }
}
}
+ override fun getSettingsScreenType(): SettingsScreenType {
+ return SettingsScreenType.VEHICLE_METRICS_SETTINGS
+ }
+
+
@SuppressLint("MissingPermission")
fun getConnectedDeviceName(): String? {
return connectedDevice?.name
}
+ fun isConnected(): Boolean {
+ return socket?.isConnected == true
+ }
+
companion object {
private val LOG = PlatformUtil.getLog(VehicleMetricsPlugin::class.java)
}
@@ -257,6 +316,9 @@ class VehicleMetricsPlugin(app: OsmandApplication) : OsmandPlugin(app),
}
override fun updateLocation(location: Location) {
- OBDDataComputer.registerLocation(OBDDataComputer.OBDLocation(location.time, KLatLon(location.latitude, location.longitude)))
+ OBDDataComputer.registerLocation(
+ OBDDataComputer.OBDLocation(
+ location.time,
+ KLatLon(location.latitude, location.longitude)))
}
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/OBDMainFragment.kt b/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/OBDMainFragment.kt
index 8ccd7b4d14a..8954eb92602 100644
--- a/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/OBDMainFragment.kt
+++ b/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/OBDMainFragment.kt
@@ -1,5 +1,6 @@
package net.osmand.plus.plugins.odb.dialogs
+//import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.FUEL_LEFT_LITERS
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@@ -8,18 +9,18 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
+import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager
-import com.google.android.material.appbar.AppBarLayout
import net.osmand.plus.R
import net.osmand.plus.base.BaseOsmAndFragment
import net.osmand.plus.plugins.PluginsHelper
import net.osmand.plus.plugins.odb.VehicleMetricsPlugin
import net.osmand.plus.utils.AndroidUtils
+import net.osmand.plus.utils.ColorUtilities
import net.osmand.shared.obd.OBDDataComputer
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.BATTERY_VOLTAGE
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.FUEL_CONSUMPTION_RATE
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.FUEL_LEFT_DISTANCE
-import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.FUEL_LEFT_LITERS
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.FUEL_LEFT_PERCENT
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.FUEL_TYPE
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.RPM
@@ -29,10 +30,7 @@ import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.TEMPERATURE_COOLANT
import net.osmand.shared.obd.OBDDataComputer.OBDTypeWidget.TEMPERATURE_INTAKE
class OBDMainFragment : BaseOsmAndFragment() {
- private var appBar: AppBarLayout? = null
- private var responsesView: EditText? = null
private var deviceName: EditText? = null
- private var connectBtn: Button? = null
private var fuelLeftDistBtn: Button? = null
private var fuelLeftLitersBtn: Button? = null
private var fuelConsumptionBtn: Button? = null
@@ -75,9 +73,16 @@ class OBDMainFragment : BaseOsmAndFragment() {
return R.layout.fragment_obd_main
}
+ private fun setupToolbar(view: View) {
+ val toolbar = view.findViewById(R.id.toolbar)
+ toolbar.setTitleTextColor(ColorUtilities.getActiveButtonsAndLinksTextColor(app, nightMode))
+ toolbar.setNavigationIcon(AndroidUtils.getNavigationIconResId(app))
+ toolbar.setNavigationContentDescription(R.string.shared_string_close)
+ toolbar.setNavigationOnClickListener { v: View? -> requireActivity().onBackPressed() }
+ }
+
private fun setupUI(view: View) {
- appBar = view.findViewById(R.id.appbar)
- responsesView = view.findViewById(R.id.responses)
+ setupToolbar(view)
fuelLeftDistResp = view.findViewById(R.id.resp1)
fuelLeftLitersResp = view.findViewById(R.id.resp2)
fuelConsumptionResp = view.findViewById(R.id.resp3)
@@ -90,18 +95,6 @@ class OBDMainFragment : BaseOsmAndFragment() {
fuelLeftPersResp = view.findViewById(R.id.resp10)
tempAmbientResp = view.findViewById(R.id.resp11)
deviceName = view.findViewById(R.id.device_name)
- connectBtn = view.findViewById(R.id.connect)
- connectBtn?.setOnClickListener {
-// val devName = it
- val devName = "Android-Vlink"
- Thread {
- if (plugin?.connectToObd(requireActivity(), devName) == true) {
- addToResponses("Connected to ${plugin?.getConnectedDeviceName()}")
- } else {
- addToResponses("Can't connect to $devName")
- }
- }.start()
- }
fuelLeftDistBtn = view.findViewById(R.id.btn1)
fuelLeftLitersBtn = view.findViewById(R.id.btn2)
fuelConsumptionBtn = view.findViewById(R.id.btn3)
@@ -135,13 +128,6 @@ class OBDMainFragment : BaseOsmAndFragment() {
}
-
- override fun onDestroyView() {
- super.onDestroyView()
- appBar = null
- }
-
-
companion object {
val TAG = OBDMainFragment::class.java.simpleName
fun showInstance(manager: FragmentManager) {
@@ -156,27 +142,23 @@ class OBDMainFragment : BaseOsmAndFragment() {
}
}
- fun addToResponses(msg: String) {
- app.runInUIThread {
- responsesView?.setText("${responsesView?.text}\n***$msg")
- }
- }
-
private val widgets = mutableListOf()
override fun onStart() {
super.onStart()
OBDDataComputer.OBDTypeWidget.entries.forEach {
- widgets.add(OBDDataComputer.registerWidget(it, 0) )
+ widgets.add(OBDDataComputer.registerWidget(it, 0))
}
updateWidgets()
}
- private fun updateWidgets(){
+ private fun updateWidgets() {
widgets.forEach {
- updateWidgetsData(it.type, if(it.computeValue() == null) " - " else it.computeValue().toString())
+ updateWidgetsData(
+ it.type,
+ if (it.computeValue() == null) " - " else it.computeValue().toString())
}
- handler.postDelayed({updateWidgets()}, 100)
+ handler.postDelayed({ updateWidgets() }, 100)
}
override fun onStop() {
@@ -190,7 +172,7 @@ class OBDMainFragment : BaseOsmAndFragment() {
SPEED -> updateWidgetData(speedResp, result)
RPM -> updateWidgetData(rpmResp, result)
FUEL_LEFT_DISTANCE -> updateWidgetData(fuelLeftDistResp, result)
- FUEL_LEFT_LITERS -> updateWidgetData(fuelLeftLitersResp, result)
+// FUEL_LEFT_LITERS -> updateWidgetData(fuelLeftLitersResp, result)
FUEL_LEFT_PERCENT -> updateWidgetData(fuelLeftPersResp, result)
FUEL_CONSUMPTION_RATE -> updateWidgetData(fuelConsumptionResp, result)
TEMPERATURE_INTAKE -> updateWidgetData(tempIntakeResp, result)
diff --git a/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/VehicleMetricsSettingsFragment.kt b/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/VehicleMetricsSettingsFragment.kt
new file mode 100644
index 00000000000..eac6670016e
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/plugins/odb/dialogs/VehicleMetricsSettingsFragment.kt
@@ -0,0 +1,162 @@
+package net.osmand.plus.plugins.odb.dialogs
+
+import android.annotation.SuppressLint
+import android.graphics.Color
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.TextView
+import androidx.annotation.ColorRes
+import androidx.appcompat.widget.Toolbar
+import androidx.core.view.ViewCompat
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import net.osmand.plus.R
+import net.osmand.plus.base.BaseOsmAndFragment
+import net.osmand.plus.helpers.AndroidUiHelper
+import net.osmand.plus.plugins.PluginsHelper
+import net.osmand.plus.plugins.odb.VehicleMetricsPlugin
+import net.osmand.plus.utils.AndroidUtils
+import net.osmand.plus.utils.ColorUtilities
+
+class VehicleMetricsSettingsFragment : BaseOsmAndFragment() {
+ private var plugin: VehicleMetricsPlugin? = null
+
+ var recyclerView: RecyclerView? = null
+ var adapter: DeviceAdapter? = null
+ var emptyView: View? = null
+
+ private var items = listOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ plugin = PluginsHelper.getPlugin(
+ VehicleMetricsPlugin::class.java)
+ }
+
+ @SuppressLint("MissingPermission")
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ updateNightMode()
+ val view =
+ themedInflater.inflate(R.layout.fragment_vehicle_metrics_settings, container, false)
+ items = plugin!!.getPairedOBDDevicesList(requireActivity())
+ checkIfEmpty()
+ setupToolbar(view)
+ setupDeviceList(view)
+ updateConnectBtn(view)
+ // setupUI(view);
+ AndroidUtils.addStatusBarPadding21v(requireMyActivity(), view)
+ return view
+ }
+
+ private fun updateConnectBtn(view: View) {
+ val btn = view.findViewById