Start LocationService

This commit is contained in:
2026-01-08 09:25:36 +01:00
parent a5f8746fc4
commit e2e87b90f0
3 changed files with 189 additions and 1 deletions

View File

@@ -31,6 +31,10 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<service android:name=".LocationService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="location"></service>
</application>
<uses-permission android:name="android.permission.INTERNET" />
@@ -39,5 +43,24 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
</manifest>

View File

@@ -0,0 +1,86 @@
package de.jadehs.strassenschadenpro2
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.os.Looper
import android.util.Log
import androidx.core.app.NotificationCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
class LocationService: Service() {
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationCallback: LocationCallback
private val channelID = "1"
private val notificationID = 1
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
locationCallback = object: LocationCallback() {
override fun onLocationResult(locationResult: LocationResult){
for (location in locationResult.locations){
val latitude = location.latitude
val longitude = location.longitude
Log.e("LocationService", "Location: $latitude, $longitude")
}
}
}
}
override fun onStartCommand(intent: Intent?,flags: Int,startId: Int): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val serviceChannel = NotificationChannel(
channelID,
"Location Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(NotificationManager::class.java)
manager?.createNotificationChannel(serviceChannel)
}
val notification = NotificationCompat.Builder(this, channelID)
.setContentTitle("Location Service")
.setContentText("Running...")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
startForeground(notificationID, notification)
val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY,60000).apply {
setMinUpdateIntervalMillis(30000)
}.build()
fusedLocationClient.requestLocationUpdates(locationRequest,locationCallback, Looper.getMainLooper())
return START_STICKY
}
}

View File

@@ -1,10 +1,17 @@
package de.jadehs.strassenschadenpro2
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -17,9 +24,11 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -28,7 +37,9 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.modifier.modifierLocalConsumer
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import de.jadehs.strassenschadenpro2.ui.theme.StrassenSchadenPro2Theme
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -36,9 +47,77 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
if (checkPermissions(this)) {
startForegroundService(Intent(this, LocationService::class.java))
} else {
RequestPermissions(
context = this,
onPermissionsGranted = {
startForegroundService(Intent(this, LocationService::class.java))
}
)
}
StrassenSchadenPro2Theme {
MainScreen(application=application)
}
}
}
}
fun checkPermissions(context: Context): Boolean {
// Check permissions to see if both permissions are granted.
// Coarse location permission.
val permissionCheckCoarseLocation = ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED
// Fine location permission.
val permissionCheckFineLocation = ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
//Notification permission
val permissionNotification = ContextCompat.checkSelfPermission(
context,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
return permissionCheckCoarseLocation && permissionCheckFineLocation && permissionNotification
}
fun showError(context: Context, message: String) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
@Composable
fun RequestPermissions(context: Context, onPermissionsGranted: () -> Unit) {
// Create an activity result launcher using permissions contract and handle the result.
val activityResultLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
// Check if both fine & coarse location permissions are true.
if (permissions.all { it.value }) {
onPermissionsGranted()
} else {
showError(context, "Location permissions were denied")
}
}
LaunchedEffect(Unit) {
activityResultLauncher.launch(
// Request both fine and coarse location permissions.
arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.POST_NOTIFICATIONS
)
)
}
}