WIP: GMaps Parser

This commit is contained in:
Piotr Dec 2023-08-13 23:17:13 +02:00
parent 307343c2eb
commit e5b2e811ce
5 changed files with 118 additions and 41 deletions

View file

@ -31,6 +31,9 @@ android {
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = '1.8'
} }
buildFeatures {
viewBinding true
}
} }
dependencies { dependencies {
@ -42,7 +45,8 @@ dependencies {
// implementation 'com.github.harry1453:android-bluetooth-serial:v1.1' // implementation 'com.github.harry1453:android-bluetooth-serial:v1.1'
// implementation 'io.reactivex.rxjava2:rxjava:2.1.12' // implementation 'io.reactivex.rxjava2:rxjava:2.1.12'
// implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' // implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'androidx.activity:activity-ktx:1.4.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.4'
implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0' implementation 'com.google.android.material:material:1.5.0'

View file

@ -20,6 +20,9 @@
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/> <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
<queries>
<package android:name="com.google.android.apps.maps" />
</queries>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
@ -29,6 +32,15 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Garmin" android:theme="@style/Theme.Garmin"
tools:targetApi="31"> tools:targetApi="31">
<service
android:name="me.trevi.navparser.service.NavigationListenerEmitter"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"> android:exported="true">

View file

@ -2,6 +2,7 @@ package eu.ztsh.garmin
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.PendingIntent
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager import android.bluetooth.BluetoothManager
@ -11,31 +12,84 @@ import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.widget.CompoundButton
import androidx.activity.result.ActivityResultCallback import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import eu.ztsh.garmin.databinding.ActivityMainBinding
import me.trevi.navparser.lib.NavigationData
import me.trevi.navparser.service.*
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
var navigating: Boolean = false
lateinit var garmin: Garmin lateinit var garmin: Garmin
private lateinit var binding : ActivityMainBinding
private val navDataModel: NavigationDataModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
bluetoothInit() bluetoothInit()
binding.enabledSwitch.setOnCheckedChangeListener {
_, isChecked ->
run {
navigating = isChecked
setNavigationData(NavigationData(true))
navDataModel.liveData.observe(this) { setNavigationData(it) }
Log.d(TAG, "OK")
}
} }
override fun onPause() {
super.onPause()
// bluetoothSerial.onPause()
} }
override fun onResume() { override fun onStart() {
super.onResume() super.onStart()
// bluetoothSerial.onResume()
startServiceListener()
checkNotificationsAccess()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
Log.d(TAG, "Got activity result: $intent, ${intent?.extras}, ${intent?.action}")
when (intent?.action) {
NOTIFICATIONS_ACCESS_RESULT -> {
intent.getBooleanExtra(NOTIFICATIONS_ACCESS_RESULT, false).also {
val notificationAccess = it
if (!notificationAccess) {
Log.e(TAG, "No notification access for ${NavigationListenerEmitter::class.qualifiedName}")
}
}
}
NAVIGATION_DATA_UPDATED -> {
// gotoFragment(R.id.NavigationFragment)
val navData = intent.getParcelableExtra<NavigationData>(NAVIGATION_DATA)
Log.d(TAG, "Got navigation data $navData")
navDataModel.data = navData
}
NAVIGATION_STARTED -> {
Log.d(TAG, "Started")
}
NAVIGATION_STOPPED -> {
Log.d(TAG, "Stopped")
}
}
} }
private fun bluetoothInit() { private fun bluetoothInit() {
@ -84,38 +138,30 @@ class MainActivity : AppCompatActivity() {
return true return true
} }
private inner class ConnectThread(val device: BluetoothDevice, val adapter: BluetoothAdapter) : Thread() { private fun startServiceListener() {
Log.d(TAG, "Start Service Listener")
private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) { setServiceListenerIntent(createPendingResult(100, Intent(), 0))
checkBt()
// device.createInsecureRfcommSocketToServiceRecord(UUID.fromString("7d00d7f5-921b-450c-8eda-26e1d4a15c61"))
device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
} }
override fun run() { fun stopServiceListener() {
// Cancel discovery because it otherwise slows down the connection. Log.d(TAG, "Stopping Service Listener")
checkBt() setServiceListenerIntent(null)
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. private fun setServiceListenerIntent(pendingIntent: PendingIntent?) {
fun cancel() { startService(serviceIntent(SET_INTENT).putExtra(PENDING_INTENT, pendingIntent))
try {
mmSocket?.close()
} catch (e: IOException) {
Log.e(Companion.TAG, "Could not close the client socket", e)
} }
private fun checkNotificationsAccess() {
startService(serviceIntent(CHECK_NOTIFICATIONS_ACCESS))
} }
private fun serviceIntent(action: String): Intent {
return Intent(applicationContext, NavigationListenerEmitter::class.java).setAction(action)
}
private fun setNavigationData(navData: NavigationData) {
Log.d(TAG, "Sending $navData")
garmin.send(navData)
} }
companion object { companion object {

View file

@ -0,0 +1,14 @@
package eu.ztsh.garmin
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import me.trevi.navparser.lib.NavigationData
class NavigationDataModel : ViewModel() {
private val mutableData = MutableLiveData<NavigationData>()
val liveData: LiveData<NavigationData> get() = mutableData
var data: NavigationData?
get() = mutableData.value
set(value) { mutableData.value = value }
}

View file

@ -6,13 +6,14 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView <androidx.appcompat.widget.SwitchCompat
android:text="Enabled"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" android:id="@+id/enabled_switch"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"/>
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>