From af676becb32d5ef02194623df92511fc375a09fe Mon Sep 17 00:00:00 2001 From: Trishun Date: Sun, 13 Aug 2023 23:26:10 +0200 Subject: [PATCH 01/62] Cleanup --- app/build.gradle | 9 - .../main/java/eu/ztsh/garmin/MainActivity.kt | 43 --- .../java/eu/ztsh/garmin/bt/BluetoothSerial.kt | 310 ------------------ 3 files changed, 362 deletions(-) delete mode 100644 app/src/main/java/eu/ztsh/garmin/bt/BluetoothSerial.kt diff --git a/app/build.gradle b/app/build.gradle index 7ad2bb2..8254840 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,19 +35,10 @@ android { dependencies { - // Notification parser - implementation 'com.github.3v1n0.GMapsParser:navparser:0.2.1' -// -// // Bluetooth serial -// implementation 'com.github.harry1453:android-bluetooth-serial:v1.1' -// implementation 'io.reactivex.rxjava2:rxjava:2.1.12' -// implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' - implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' -// testImplementation 'junit:junit:4.13.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/src/main/java/eu/ztsh/garmin/MainActivity.kt b/app/src/main/java/eu/ztsh/garmin/MainActivity.kt index 01b49a8..63e93a3 100644 --- a/app/src/main/java/eu/ztsh/garmin/MainActivity.kt +++ b/app/src/main/java/eu/ztsh/garmin/MainActivity.kt @@ -28,15 +28,6 @@ class MainActivity : AppCompatActivity() { setContentView(R.layout.activity_main) bluetoothInit() } - override fun onPause() { - super.onPause() -// bluetoothSerial.onPause() - } - - override fun onResume() { - super.onResume() -// bluetoothSerial.onResume() - } private fun bluetoothInit() { val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java) @@ -84,40 +75,6 @@ class MainActivity : AppCompatActivity() { return true } - private inner class ConnectThread(val device: BluetoothDevice, val adapter: BluetoothAdapter) : Thread() { - - private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) { - checkBt() -// device.createInsecureRfcommSocketToServiceRecord(UUID.fromString("7d00d7f5-921b-450c-8eda-26e1d4a15c61")) - device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")) - } - - override fun run() { - // Cancel discovery because it otherwise slows down the connection. - checkBt() - adapter.cancelDiscovery() - - mmSocket?.let { socket -> - // Connect to the remote device through the socket. This call blocks - // until it succeeds or throws an exception. - socket.connect() - - // The connection attempt succeeded. Perform work associated with - // the connection in a separate thread. -// manageMyConnectedSocket(socket) - } - } - - // Closes the client socket and causes the thread to finish. - fun cancel() { - try { - mmSocket?.close() - } catch (e: IOException) { - Log.e(Companion.TAG, "Could not close the client socket", e) - } - } - } - companion object { private const val TAG = "bt" } diff --git a/app/src/main/java/eu/ztsh/garmin/bt/BluetoothSerial.kt b/app/src/main/java/eu/ztsh/garmin/bt/BluetoothSerial.kt deleted file mode 100644 index 5167e61..0000000 --- a/app/src/main/java/eu/ztsh/garmin/bt/BluetoothSerial.kt +++ /dev/null @@ -1,310 +0,0 @@ -package eu.ztsh.garmin.bt - -import android.annotation.SuppressLint -import android.bluetooth.BluetoothAdapter -import android.bluetooth.BluetoothDevice -import android.bluetooth.BluetoothSocket -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.os.AsyncTask -import android.util.Log -import androidx.localbroadcastmanager.content.LocalBroadcastManager -import eu.ztsh.garmin.MainActivity -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.util.* - -class BluetoothSerial(var context: MainActivity, var messageHandler: MessageHandler, devicePrefix: String) { - var connected = false - var bluetoothDevice: BluetoothDevice? = null - var serialSocket: BluetoothSocket? = null - var serialInputStream: InputStream? = null - var serialOutputStream: OutputStream? = null - var serialReader: SerialReader? = null - var connectionTask: AsyncTask? = null - var devicePrefix: String - - /** - * Listens for discount message from bluetooth system and restablishing a connection - */ - private val bluetoothReceiver: BroadcastReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val action = intent.action - val eventDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) - if (BluetoothDevice.ACTION_ACL_DISCONNECTED == action) { - if (bluetoothDevice != null && bluetoothDevice == eventDevice) { - Log.i(BMX_BLUETOOTH, "Received bluetooth disconnect notice") - - //clean up any streams - close() - - //reestablish connect - connect() - LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(BLUETOOTH_DISCONNECTED)) - } - } - } - } - - init { - this.devicePrefix = devicePrefix.uppercase(Locale.getDefault()) - } - - fun onPause() { - context.unregisterReceiver(bluetoothReceiver) - } - - fun onResume() { - //listen for bluetooth disconnect - val disconnectIntent = IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED) - context.registerReceiver(bluetoothReceiver, disconnectIntent) - - //reestablishes a connection is one doesn't exist - if (!connected) { - connect() - } else { - val intent = Intent(BLUETOOTH_CONNECTED) - LocalBroadcastManager.getInstance(context).sendBroadcast(intent) - } - } - - /** - * Initializes the bluetooth serial connections, uses the LocalBroadcastManager when - * connection is established - */ - @SuppressLint("MissingPermission") - fun connect() { - if (connected) { - Log.e(BMX_BLUETOOTH, "Connection request while already connected") - return - } - if (connectionTask != null && connectionTask!!.status == AsyncTask.Status.RUNNING) { - Log.e(BMX_BLUETOOTH, "Connection request while attempting connection") - return - } - val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() - if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled) { - return - } - context.checkBt() - val pairedDevices: List = ArrayList(bluetoothAdapter.getBondedDevices()) - if (pairedDevices.isNotEmpty()) { - bluetoothAdapter.cancelDiscovery() - /** - * AsyncTask to handle the establishing of a bluetooth connection - */ -// connectionTask = object : AsyncTask() { -// var MAX_ATTEMPTS = 30 -// var attemptCounter = 0 -// protected override fun doInBackground(vararg params: Void): BluetoothDevice? { -// while (!isCancelled) { //need to kill without calling onCancel -// for (device in pairedDevices) { -// if (device.getName().uppercase(Locale.getDefault()).startsWith(devicePrefix)) { -// Log.i( -// BMX_BLUETOOTH, -// attemptCounter.toString() + ": Attempting connection to " + device.getName() -// ) -// try { -// serialSocket = try { -// // Standard SerialPortService ID -// val uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB") -// device.createRfcommSocketToServiceRecord(uuid) -// } catch (ce: Exception) { -// connectViaReflection(device) -// } -// -// //setup the connect streams -// serialSocket!!.connect() -// serialInputStream = serialSocket!!.inputStream -// serialOutputStream = serialSocket!!.outputStream -// connected = true -// Log.i(BMX_BLUETOOTH, "Connected to " + device.getName()) -// return device -// } catch (e: Exception) { -// serialSocket = null -// serialInputStream = null -// serialOutputStream = null -// Log.i(BMX_BLUETOOTH, e.message!!) -// } -// } -// } -// try { -// attemptCounter++ -// if (attemptCounter > MAX_ATTEMPTS) cancel(false) else Thread.sleep(1000) -// } catch (e: InterruptedException) { -// break -// } -// } -// Log.i(BMX_BLUETOOTH, "Stopping connection attempts") -// val intent = Intent(BLUETOOTH_FAILED) -// LocalBroadcastManager.getInstance(context).sendBroadcast(intent) -// return null -// } -// -// override fun onPostExecute(result: BluetoothDevice?) { -// super.onPostExecute(result) -// bluetoothDevice = result -// -// //start thread responsible for reading from inputstream -// serialReader = SerialReader() -// serialReader!!.start() -// -// //send connection message -// val intent = Intent(BLUETOOTH_CONNECTED) -// LocalBroadcastManager.getInstance(context).sendBroadcast(intent) -// } -// } -// connectionTask.execute() - } - } - - // see: http://stackoverflow.com/questions/3397071/service-discovery-failed-exception-using-bluetooth-on-android - @Throws(Exception::class) - private fun connectViaReflection(device: BluetoothDevice): BluetoothSocket { - val m = device.javaClass.getMethod( - "createRfcommSocket", *arrayOf?>( - Int::class.javaPrimitiveType - ) - ) - return m.invoke(device, 1) as BluetoothSocket - } - - @Throws(IOException::class) - fun available(): Int { - if (connected) return serialInputStream!!.available() - throw RuntimeException("Connection lost, reconnecting now.") - } - - @Throws(IOException::class) - fun read(): Int { - if (connected) return serialInputStream!!.read() - throw RuntimeException("Connection lost, reconnecting now.") - } - - @Throws(IOException::class) - fun read(buffer: ByteArray?): Int { - if (connected) return serialInputStream!!.read(buffer) - throw RuntimeException("Connection lost, reconnecting now.") - } - - @Throws(IOException::class) - fun read(buffer: ByteArray?, byteOffset: Int, byteCount: Int): Int { - if (connected) return serialInputStream!!.read(buffer, byteOffset, byteCount) - throw RuntimeException("Connection lost, reconnecting now.") - } - - @Throws(IOException::class) - fun write(buffer: ByteArray?) { - if (connected) serialOutputStream!!.write(buffer) - throw RuntimeException("Connection lost, reconnecting now.") - } - - @Throws(IOException::class) - fun write(oneByte: Int) { - if (connected) serialOutputStream!!.write(oneByte) - throw RuntimeException("Connection lost, reconnecting now.") - } - - @Throws(IOException::class) - fun write(buffer: ByteArray?, offset: Int, count: Int) { - serialOutputStream!!.write(buffer, offset, count) - throw RuntimeException("Connection lost, reconnecting now.") - } - - inner class SerialReader : Thread() { - var buffer = ByteArray(Companion.MAX_BYTES) - var bufferSize = 0 - override fun run() { - Log.i("serialReader", "Starting serial loop") - while (!isInterrupted) { - try { - - /* - * check for some bytes, or still bytes still left in - * buffer - */ - if (available() > 0) { - val newBytes = read(buffer, bufferSize, Companion.MAX_BYTES - bufferSize) - if (newBytes > 0) bufferSize += newBytes - Log.d(BMX_BLUETOOTH, "read $newBytes") - } - if (bufferSize > 0) { - val read = messageHandler.read(bufferSize, buffer) - - // shift unread data to start of buffer - if (read > 0) { - var index = 0 - for (i in read until bufferSize) { - buffer[index++] = buffer[i] - } - bufferSize = index - } - } else { - try { - sleep(10) - } catch (ie: InterruptedException) { - break - } - } - } catch (e: Exception) { - Log.e(BMX_BLUETOOTH, "Error reading serial data", e) - } - } - Log.i(BMX_BLUETOOTH, "Shutting serial loop") - } - -// companion object { -// } - } - - /** - * Reads from the serial buffer, processing any available messages. Must return the number of bytes - * consumer from the buffer - * - * @author jpetrocik - */ - fun interface MessageHandler { - fun read(bufferSize: Int, buffer: ByteArray?): Int - } - - fun close() { - connected = false - if (connectionTask != null) { - connectionTask!!.cancel(false) - } - if (serialReader != null) { - serialReader!!.interrupt() - try { - serialReader!!.join(1000) - } catch (ie: InterruptedException) { - } - } - try { - serialInputStream!!.close() - } catch (e: Exception) { - Log.e(BMX_BLUETOOTH, "Failed releasing inputstream connection") - } - try { - serialOutputStream!!.close() - } catch (e: Exception) { - Log.e(BMX_BLUETOOTH, "Failed releasing outputstream connection") - } - try { - serialSocket!!.close() - } catch (e: Exception) { - Log.e(BMX_BLUETOOTH, "Failed closing socket") - } - Log.i(BMX_BLUETOOTH, "Released bluetooth connections") - } - - companion object { - private const val BMX_BLUETOOTH = "BMXBluetooth" - var BLUETOOTH_CONNECTED = "bluetooth-connection-started" - var BLUETOOTH_DISCONNECTED = "bluetooth-connection-lost" - var BLUETOOTH_FAILED = "bluetooth-connection-failed" - private const val MAX_BYTES = 125 - } -} From 4fb4aacb8d3aef74987156ccfe96db496f137d08 Mon Sep 17 00:00:00 2001 From: Trishun Date: Sun, 13 Aug 2023 23:30:26 +0200 Subject: [PATCH 02/62] Bindings --- app/build.gradle | 3 +++ app/src/main/java/eu/ztsh/garmin/MainActivity.kt | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8254840..e16fba3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,6 +31,9 @@ android { kotlinOptions { jvmTarget = '1.8' } + buildFeatures { + viewBinding true + } } dependencies { diff --git a/app/src/main/java/eu/ztsh/garmin/MainActivity.kt b/app/src/main/java/eu/ztsh/garmin/MainActivity.kt index 63e93a3..5a2b495 100644 --- a/app/src/main/java/eu/ztsh/garmin/MainActivity.kt +++ b/app/src/main/java/eu/ztsh/garmin/MainActivity.kt @@ -5,7 +5,6 @@ import android.annotation.SuppressLint import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothManager -import android.bluetooth.BluetoothSocket import android.content.Intent import android.content.pm.PackageManager import android.os.Build @@ -15,17 +14,19 @@ import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat -import java.io.IOException -import java.util.* +import eu.ztsh.garmin.databinding.ActivityMainBinding @SuppressLint("MissingPermission") class MainActivity : AppCompatActivity() { lateinit var garmin: Garmin + private lateinit var binding : ActivityMainBinding + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) bluetoothInit() } From 38b9ff9a176ca189388c38ac3c09186a6c325f01 Mon Sep 17 00:00:00 2001 From: Trishun Date: Sun, 13 Aug 2023 23:49:19 +0200 Subject: [PATCH 03/62] Mapbox All-in-one template --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 13 ++++------- .../main/java/eu/ztsh/garmin/MainActivity.kt | 2 +- app/src/main/res/layout/activity_main.xml | 23 ++++++------------- app/src/main/res/values/strings.xml | 3 ++- settings.gradle | 13 +++++++++++ 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e16fba3..cf3f08a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,6 +38,7 @@ android { dependencies { + implementation "com.mapbox.navigation:ui-dropin:2.14.2" implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fce5820..9a87620 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,18 +8,15 @@ - - - - + + + + + - - + - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ba6212e..1c4d613 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ Garmin - \ No newline at end of file + pk.eyJ1IjoibWFwcy16dHNoIiwiYSI6ImNsbDl4YXU4cjA3eW8zcXMzbXdjYjNsN3oifQ.kbDCjthamXvXX_pAdsq3hQ + diff --git a/settings.gradle b/settings.gradle index a3c818f..2938a3f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,6 +13,19 @@ dependencyResolutionManagement { maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = "mapbox" + // Use the secret token you stored in gradle.properties as the password + password = MAPBOX_DOWNLOADS_TOKEN + } + } } } rootProject.name = "Garmin" From 49559993d8fa7363eab89d261eae85705f74d672 Mon Sep 17 00:00:00 2001 From: Trishun Date: Mon, 14 Aug 2023 00:05:09 +0200 Subject: [PATCH 04/62] Hide action bar --- app/src/main/res/values-night/themes.xml | 2 +- app/src/main/res/values/themes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 91b45eb..b521f31 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -1,6 +1,6 @@ -