Cluster
This commit is contained in:
@@ -6,6 +6,10 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<!-- <uses-permission android:name="android.permission.READ_CONTACTS"/>-->
|
||||
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
|
||||
tools:ignore="MockLocation" />
|
||||
@@ -36,6 +40,12 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service
|
||||
android:name="com.kouros.navigation.car.navigation.NavigationService"
|
||||
android:enabled="true"
|
||||
android:foregroundServiceType="location"
|
||||
android:exported="true">
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.kouros.navigation.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.app.AppOpsManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.location.LocationManager
|
||||
import android.os.Bundle
|
||||
import android.os.Process
|
||||
import android.widget.Toast
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
@@ -41,19 +43,16 @@ import com.google.android.gms.location.LocationServices
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
||||
import com.kouros.navigation.car.TextToSpeechManager
|
||||
import com.kouros.navigation.car.navigation.NavigationService
|
||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||
import com.kouros.navigation.data.Constants.INSTRUCTION_DISTANCE
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import com.kouros.navigation.data.Constants.TILT
|
||||
import com.kouros.navigation.data.Constants.homeVogelhart
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.model.BaseStyleModel
|
||||
import com.kouros.navigation.model.MockLocation
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.model.SimulationType
|
||||
import com.kouros.navigation.model.simulate
|
||||
import com.kouros.navigation.model.simulationJob
|
||||
import com.kouros.navigation.model.test
|
||||
import com.kouros.navigation.model.testSingle
|
||||
import com.kouros.navigation.ui.app.AppViewModel
|
||||
import com.kouros.navigation.ui.app.appViewModel
|
||||
import com.kouros.navigation.ui.navigation.AppNavGraph
|
||||
@@ -80,10 +79,13 @@ import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
var navigationService: NavigationService? = null
|
||||
|
||||
var isBound: Boolean = false
|
||||
val routeData = MutableLiveData("")
|
||||
val routeModel = RouteModel()
|
||||
var tilt = TILT
|
||||
val useMock = false
|
||||
|
||||
val type = SimulationType.SIMULATE
|
||||
val stepData: MutableLiveData<StepData> by lazy {
|
||||
@@ -96,26 +98,21 @@ class MainActivity : ComponentActivity() {
|
||||
var lastLocation = location(0.0, 0.0)
|
||||
val observer = Observer<String> { newRoute ->
|
||||
if (newRoute.isNotEmpty()) {
|
||||
val repository = getSettingsRepository(applicationContext)
|
||||
val routingEngine = runBlocking { repository.routingEngineFlow.first() }
|
||||
routeModel.navState = routeModel.navState.copy(routingEngine = routingEngine)
|
||||
routeModel.startNavigation(newRoute)
|
||||
routeData.value = routeModel.curRoute.routeGeoJson
|
||||
// checkMock()
|
||||
startNavigation(newRoute)
|
||||
}
|
||||
}
|
||||
|
||||
// Monitors the state of the connection to the navigation service.
|
||||
private val serviceConnection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
val binder: NavigationService.LocalBinder = service as NavigationService.LocalBinder
|
||||
navigationService = binder.service
|
||||
isBound = true
|
||||
}
|
||||
|
||||
private fun checkMock() {
|
||||
if (useMock) {
|
||||
when (type) {
|
||||
SimulationType.SIMULATE -> simulate(routeModel, mock)
|
||||
SimulationType.TEST -> test(applicationContext, routeModel)
|
||||
|
||||
|
||||
SimulationType.TEST_SINGLE -> testSingle(applicationContext, routeModel, mock)
|
||||
else -> {}
|
||||
}
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
navigationService = null
|
||||
isBound = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,9 +124,7 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
private lateinit var locationManager: LocationManager
|
||||
private lateinit var fusedLocationClient: FusedLocationProviderClient
|
||||
private lateinit var mock: MockLocation
|
||||
private var loadRecentPlaces = false
|
||||
|
||||
lateinit var textToSpeechManager: TextToSpeechManager
|
||||
|
||||
var guidanceAudio = 0
|
||||
@@ -152,20 +147,10 @@ class MainActivity : ComponentActivity() {
|
||||
repository.guidanceAudioFlow.asLiveData().observe(this, Observer {
|
||||
guidanceAudio = it
|
||||
})
|
||||
|
||||
if (useMock) {
|
||||
checkMockLocationEnabled()
|
||||
}
|
||||
locationManager = getSystemService(LOCATION_SERVICE) as LocationManager
|
||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
|
||||
fusedLocationClient.lastLocation.addOnSuccessListener { _: android.location.Location? ->
|
||||
navigationViewModel.route.observe(this, observer)
|
||||
if (useMock) {
|
||||
mock = MockLocation(locationManager)
|
||||
mock.setMockLocation(
|
||||
homeVogelhart.latitude, homeVogelhart.longitude, 0F
|
||||
)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
getSettingsViewModel(applicationContext).routingEngine.first()
|
||||
@@ -183,6 +168,27 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
Log.i(TAG, "In onStart()")
|
||||
bindService(
|
||||
Intent(this, NavigationService::class.java),
|
||||
serviceConnection,
|
||||
BIND_AUTO_CREATE
|
||||
)
|
||||
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Log.i(TAG, "In onStop(). bound $isBound")
|
||||
if (isBound) {
|
||||
unbindService(serviceConnection)
|
||||
isBound = false
|
||||
navigationService = null
|
||||
}
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun StartScreen(
|
||||
@@ -206,10 +212,8 @@ class MainActivity : ComponentActivity() {
|
||||
// navigationViewModel.route.value = lastRoute
|
||||
//}
|
||||
val userLocationState = rememberUserLocationState(locationProvider)
|
||||
if (!useMock) {
|
||||
val locationState = locationProvider.location.collectAsState()
|
||||
updateLocation(locationState.value)
|
||||
}
|
||||
val step: StepData? by stepData.observeAsState()
|
||||
val nextStep: StepData? by nextStepData.observeAsState()
|
||||
|
||||
@@ -284,7 +288,7 @@ class MainActivity : ComponentActivity() {
|
||||
step,
|
||||
nextStep,
|
||||
{ stopNavigation {} },
|
||||
{ simulateNavigation() })
|
||||
{ })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,18 +350,21 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun startNavigation(newRoute: String) {
|
||||
val repository = getSettingsRepository(applicationContext)
|
||||
val routingEngine = runBlocking { repository.routingEngineFlow.first() }
|
||||
routeModel.navState = routeModel.navState.copy(routingEngine = routingEngine)
|
||||
routeModel.startNavigation(newRoute)
|
||||
routeData.value = routeModel.curRoute.routeGeoJson
|
||||
navigationService?.startNavigation()
|
||||
}
|
||||
fun stopNavigation(closeSheet: () -> Unit) {
|
||||
val latitude = routeModel.curRoute.waypoints[0][1]
|
||||
val longitude = routeModel.curRoute.waypoints[0][0]
|
||||
closeSheet()
|
||||
routeModel.stopNavigation()
|
||||
getSettingsViewModel(applicationContext).onLastRouteChanged("")
|
||||
if (useMock) {
|
||||
simulationJob?.cancel()
|
||||
mock.setMockLocation(latitude, longitude, 0F)
|
||||
}
|
||||
routeData.value = ""
|
||||
stepData.value = StepData("", "", 0.0, 0, 0, 0, 0.0)
|
||||
navigationService?.stopNavigation()
|
||||
}
|
||||
|
||||
fun textToSpeech() {
|
||||
@@ -368,37 +375,5 @@ class MainActivity : ComponentActivity() {
|
||||
lastStepIndex = currentStep.index
|
||||
}
|
||||
}
|
||||
|
||||
fun simulateNavigation() {
|
||||
simulate(
|
||||
routeModel = routeModel, mock = mock
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkMockLocationEnabled() {
|
||||
try {
|
||||
// Check if mock location is enabled for this app
|
||||
val appOpsManager = getSystemService(APP_OPS_SERVICE) as AppOpsManager
|
||||
val mode = appOpsManager.checkOp(
|
||||
AppOpsManager.OPSTR_MOCK_LOCATION, Process.myUid(), packageName
|
||||
)
|
||||
|
||||
if (mode != AppOpsManager.MODE_ALLOWED) {
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Please select this app as mock location app in Developer Options",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum class ExpandedType {
|
||||
HALF, FULL, COLLAPSED
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user