Compare commits
No commits in common. "dbfb08412d8399c746fd670b92688912a8aa59f2" and "df78dfe7ce9c11c08b4873590422cab47172f97f" have entirely different histories.
dbfb08412d
...
df78dfe7ce
8 changed files with 24 additions and 212 deletions
|
@ -17,7 +17,6 @@ import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.SynchronousQueue
|
import java.util.concurrent.SynchronousQueue
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
class Garmin(
|
class Garmin(
|
||||||
|
@ -48,14 +47,6 @@ class Garmin(
|
||||||
locations.start()
|
locations.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reconnect() {
|
|
||||||
Log.d(TAG, "reconnect pressed")
|
|
||||||
if (!connection.isConnecting.get()) {
|
|
||||||
Log.d(TAG, "reconnection enqueued")
|
|
||||||
context.runAsync { connection.tryConnect() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun close() {
|
fun close() {
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
@ -193,9 +184,7 @@ class Garmin(
|
||||||
|
|
||||||
private inner class ConnectThread : Thread() {
|
private inner class ConnectThread : Thread() {
|
||||||
|
|
||||||
val isConnecting = AtomicBoolean(false)
|
|
||||||
private val queue: SynchronousQueue<IntArray> = SynchronousQueue()
|
private val queue: SynchronousQueue<IntArray> = SynchronousQueue()
|
||||||
private val state = AtomicBoolean(false)
|
|
||||||
private var current: IntArray = intArrayOf()
|
private var current: IntArray = intArrayOf()
|
||||||
|
|
||||||
private val socket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
|
private val socket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
|
@ -203,37 +192,18 @@ class Garmin(
|
||||||
device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
|
device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryConnect() {
|
|
||||||
Log.d(TAG, "Connection requested")
|
|
||||||
if (!isConnecting.get()) {
|
|
||||||
Log.d(TAG, "Trying to connect...")
|
|
||||||
isConnecting.set(true)
|
|
||||||
context.checkBt()
|
|
||||||
// Cancel discovery because it otherwise slows down the connection.
|
|
||||||
adapter.cancelDiscovery()
|
|
||||||
try {
|
|
||||||
socket?.connect()
|
|
||||||
context.toastConnectionStatus(true)
|
|
||||||
sleep(3000)
|
|
||||||
readAll()
|
|
||||||
send(intArrayOf(0x07, 0x01)) // Set GPS to true
|
|
||||||
send(intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) // Clear screen
|
|
||||||
state.set(true)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.d(TAG, "Not connected", e)
|
|
||||||
context.toastConnectionStatus(false)
|
|
||||||
state.set(false)
|
|
||||||
}
|
|
||||||
queue.clear()
|
|
||||||
current = intArrayOf()
|
|
||||||
isConnecting.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
tryConnect()
|
// Cancel discovery because it otherwise slows down the connection.
|
||||||
while (true) {
|
context.checkBt()
|
||||||
if (state.get()) {
|
adapter.cancelDiscovery()
|
||||||
|
try {
|
||||||
|
socket?.connect()
|
||||||
|
context.setConnectionStatus(true)
|
||||||
|
sleep(3000)
|
||||||
|
readAll()
|
||||||
|
send(intArrayOf(0x07, 0x01)) // Set GPS to true
|
||||||
|
send(intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) // Clear screen
|
||||||
|
while (true) {
|
||||||
val newCurrent = queue.poll()
|
val newCurrent = queue.poll()
|
||||||
if (newCurrent == null) {
|
if (newCurrent == null) {
|
||||||
Log.d(TAG, "run (${currentThread().name}): Sleep...")
|
Log.d(TAG, "run (${currentThread().name}): Sleep...")
|
||||||
|
@ -242,9 +212,15 @@ class Garmin(
|
||||||
current = newCurrent
|
current = newCurrent
|
||||||
}
|
}
|
||||||
send(current)
|
send(current)
|
||||||
} else {
|
}
|
||||||
queue.clear()
|
} catch (e: IOException) {
|
||||||
sleep(2000)
|
Log.d(TAG, "Not connected", e)
|
||||||
|
context.setConnectionStatus(false)
|
||||||
|
while (true) {
|
||||||
|
// Just dequeue
|
||||||
|
// TODO: Add option to reconnect
|
||||||
|
queue.poll()
|
||||||
|
sleep(900)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,13 +253,9 @@ class Garmin(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendRaw(buff: IntArray) {
|
private fun sendRaw(buff: IntArray) {
|
||||||
try {
|
buff.forEach { socket!!.outputStream.write(it) }
|
||||||
buff.forEach { socket!!.outputStream.write(it) }
|
socket!!.outputStream.flush()
|
||||||
socket!!.outputStream.flush()
|
readAll()
|
||||||
readAll()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.d(TAG, "sendRaw: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import com.mapbox.navigation.base.options.NavigationOptions
|
import com.mapbox.navigation.base.options.NavigationOptions
|
||||||
import com.mapbox.navigation.core.MapboxNavigation
|
import com.mapbox.navigation.core.MapboxNavigation
|
||||||
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
|
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
|
||||||
|
@ -26,9 +25,6 @@ import com.mapbox.navigation.core.lifecycle.requireMapboxNavigation
|
||||||
import eu.ztsh.garmin.databinding.ActivityMainBinding
|
import eu.ztsh.garmin.databinding.ActivityMainBinding
|
||||||
import eu.ztsh.garmin.mapbox.MapControl
|
import eu.ztsh.garmin.mapbox.MapControl
|
||||||
import eu.ztsh.garmin.util.PermissionsHelper
|
import eu.ztsh.garmin.util.PermissionsHelper
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,15 +124,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runAsync(action: () -> Unit) {
|
fun setConnectionStatus(success: Boolean) {
|
||||||
lifecycleScope.launch {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
action()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toastConnectionStatus(success: Boolean) {
|
|
||||||
this.runOnUiThread {
|
this.runOnUiThread {
|
||||||
if (success) {
|
if (success) {
|
||||||
Toast.makeText(this, "Garmin connected", Toast.LENGTH_LONG).show()
|
Toast.makeText(this, "Garmin connected", Toast.LENGTH_LONG).show()
|
||||||
|
|
|
@ -59,6 +59,4 @@ class UI(b: ActivityMainBinding) {
|
||||||
val searchResultsView = b.searchResults
|
val searchResultsView = b.searchResults
|
||||||
val searchPlaceView = b.searchPlaces
|
val searchPlaceView = b.searchPlaces
|
||||||
val queryEditText = b.query
|
val queryEditText = b.query
|
||||||
|
|
||||||
val reconnect = b.reconnect
|
|
||||||
}
|
}
|
|
@ -22,7 +22,6 @@ import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSou
|
||||||
import com.mapbox.navigation.ui.maps.camera.lifecycle.NavigationBasicGesturesHandler
|
import com.mapbox.navigation.ui.maps.camera.lifecycle.NavigationBasicGesturesHandler
|
||||||
import com.mapbox.navigation.ui.maps.camera.state.NavigationCameraState
|
import com.mapbox.navigation.ui.maps.camera.state.NavigationCameraState
|
||||||
import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider
|
import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider
|
||||||
import eu.ztsh.garmin.Garmin
|
|
||||||
import eu.ztsh.garmin.MainActivity
|
import eu.ztsh.garmin.MainActivity
|
||||||
import eu.ztsh.garmin.UI
|
import eu.ztsh.garmin.UI
|
||||||
import eu.ztsh.garmin.mock.ReplayResources
|
import eu.ztsh.garmin.mock.ReplayResources
|
||||||
|
@ -106,12 +105,6 @@ class MapControl(
|
||||||
locationObserver = LocationObserver(this)
|
locationObserver = LocationObserver(this)
|
||||||
routeProgressObserver = routeControl.routeProgressObserver
|
routeProgressObserver = routeControl.routeProgressObserver
|
||||||
voiceInstructionsObserver = voiceControl.voiceInstructionsObserver
|
voiceInstructionsObserver = voiceControl.voiceInstructionsObserver
|
||||||
|
|
||||||
|
|
||||||
ui.reconnect.setOnClickListener {
|
|
||||||
Garmin.instance.reconnect()
|
|
||||||
ui.reconnect.showTextAndExtend(UI.BUTTON_ANIMATION_DURATION)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun routeToPoint(point: Point) {
|
fun routeToPoint(point: Point) {
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
package eu.ztsh.garmin.view
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.res.TypedArray
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import androidx.annotation.StyleRes
|
|
||||||
import androidx.annotation.UiThread
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
import com.mapbox.navigation.ui.components.R
|
|
||||||
import eu.ztsh.garmin.R.styleable.*
|
|
||||||
import com.mapbox.navigation.ui.components.databinding.ExtendableButtonLayoutBinding
|
|
||||||
import com.mapbox.navigation.ui.utils.internal.ExtendableButtonHelper
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapbox extendable generic.
|
|
||||||
*/
|
|
||||||
@UiThread
|
|
||||||
class ExtendableButton : ConstraintLayout {
|
|
||||||
|
|
||||||
private val binding = ExtendableButtonLayoutBinding.inflate(LayoutInflater.from(context), this)
|
|
||||||
private val helper = ExtendableButtonHelper(
|
|
||||||
binding.buttonText,
|
|
||||||
context.resources.getDimensionPixelSize(R.dimen.mapbox_button_size),
|
|
||||||
context.resources.getDimension(R.dimen.mapbox_recenterButton_minExtendedWidth),
|
|
||||||
)
|
|
||||||
private lateinit var expandedText: String
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param context Context
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(context: Context) : super(context)
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param context Context
|
|
||||||
* @param attrs AttributeSet?
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
|
||||||
initAttributes(attrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param context Context
|
|
||||||
* @param attrs AttributeSet?
|
|
||||||
* @param defStyleAttr Int
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet?,
|
|
||||||
defStyleAttr: Int
|
|
||||||
) : super(context, attrs, defStyleAttr) {
|
|
||||||
initAttributes(attrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows you to change the style of [ExtendableButton].
|
|
||||||
* @param style Int
|
|
||||||
*/
|
|
||||||
fun updateStyle(@StyleRes style: Int) {
|
|
||||||
val typedArray = context.obtainStyledAttributes(
|
|
||||||
style,
|
|
||||||
ExtendableButton
|
|
||||||
)
|
|
||||||
applyAttributes(typedArray)
|
|
||||||
typedArray.recycle()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke the function to show optional text associated with the view.
|
|
||||||
* @param duration for the view to be in the extended mode before it starts to shrink.
|
|
||||||
* @param text for the view to show in the extended mode.
|
|
||||||
*/
|
|
||||||
@JvmOverloads
|
|
||||||
fun showTextAndExtend(
|
|
||||||
duration: Long,
|
|
||||||
text: String = expandedText,
|
|
||||||
) {
|
|
||||||
if (!helper.isAnimationRunning) {
|
|
||||||
helper.showTextAndExtend(text, duration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initAttributes(attrs: AttributeSet?) {
|
|
||||||
val typedArray = context.obtainStyledAttributes(
|
|
||||||
attrs,
|
|
||||||
ExtendableButton,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
applyAttributes(typedArray)
|
|
||||||
typedArray.recycle()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyAttributes(typedArray: TypedArray) {
|
|
||||||
typedArray.getDrawable(ExtendableButton_btn_icon)
|
|
||||||
.also { binding.buttonIcon.setImageDrawable(it) }
|
|
||||||
|
|
||||||
typedArray.getDrawable(
|
|
||||||
R.styleable.MapboxRecenterButton_recenterButtonBackground,
|
|
||||||
)?.let { background ->
|
|
||||||
binding.buttonIcon.background = background
|
|
||||||
binding.buttonText.background = background
|
|
||||||
}
|
|
||||||
|
|
||||||
typedArray.getColorStateList(
|
|
||||||
R.styleable.MapboxRecenterButton_recenterButtonTextColor,
|
|
||||||
)?.let { binding.buttonText.setTextColor(it) }
|
|
||||||
|
|
||||||
typedArray.apply {
|
|
||||||
expandedText = getString(ExtendableButton_expanded_text) ?: "DUNNO"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -127,15 +127,4 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/routeOverview" />
|
app:layout_constraintTop_toBottomOf="@id/routeOverview" />
|
||||||
|
|
||||||
<eu.ztsh.garmin.view.ExtendableButton
|
|
||||||
android:id="@+id/reconnect"
|
|
||||||
app:btn_icon="@android:drawable/ic_menu_rotate"
|
|
||||||
app:expanded_text="@string/reconnect"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/recenter" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<declare-styleable name="ExtendableButton">
|
|
||||||
<attr name="expanded_text" format="string"/>
|
|
||||||
<attr name="btn_icon" format="reference"/>
|
|
||||||
</declare-styleable>
|
|
||||||
</resources>
|
|
|
@ -7,6 +7,4 @@
|
||||||
<string name="place_autocomplete_selection_error">Error happened during request</string>
|
<string name="place_autocomplete_selection_error">Error happened during request</string>
|
||||||
<string name="not_implemented_yet">Not implemented yet</string>
|
<string name="not_implemented_yet">Not implemented yet</string>
|
||||||
|
|
||||||
<string name="reconnect">Reconnect</string>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue