feat: add gps
This commit is contained in:
parent
56ec2b4263
commit
c1b2fc181b
7
.idea/copilot.data.migration.agent.xml
generated
7
.idea/copilot.data.migration.agent.xml
generated
@ -24,6 +24,10 @@
|
||||
<option value="a20448f7-57cd-4a40-89b1-460451412588" />
|
||||
<option value="484561a1-1c08-44cd-bcd3-a53895fc3851" />
|
||||
<option value="17ec376a-38fd-48ac-a4e1-52e9f7df3100" />
|
||||
<option value="a0c23b11-ba1e-4275-a3e4-38b3c8fdbe00" />
|
||||
<option value="3ac3800e-363e-4148-86b3-0d4f3b0a8b62" />
|
||||
<option value="5460190d-c8ff-4194-9316-a6298c7cb54b" />
|
||||
<option value="c640b33a-4bc6-4ee0-98ed-6a71e7270331" />
|
||||
</set>
|
||||
</value>
|
||||
</entry>
|
||||
@ -84,6 +88,9 @@
|
||||
<option value="file://$PROJECT_DIR$/app/build.gradle.kts" />
|
||||
<option value="file://$PROJECT_DIR$/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt" />
|
||||
<option value="file://$PROJECT_DIR$/app/src/main/java/id/ac/ubharajaya/panicbutton/NotificationSender.kt" />
|
||||
<option value="file://$PROJECT_DIR$/app/src/main/java/id/ac/ubharajaya/panicbutton/MainViewModel.kt" />
|
||||
<option value="file://$PROJECT_DIR$/app/src/main/java/id/ac/ubharajaya/panicbutton/MainScreen.kt" />
|
||||
<option value="file://$PROJECT_DIR$/app/src/main/AndroidManifest.xml" />
|
||||
</set>
|
||||
</entry>
|
||||
<entry key="bf5061b4-a1e9-4600-a273-ea8e51b2ce89" />
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
@ -34,5 +38,4 @@
|
||||
android:label="Detail Peta" />
|
||||
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
||||
@ -1,6 +1,7 @@
|
||||
package id.ac.ubharajaya.panicbutton
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
@ -11,16 +12,20 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
private val requestPermissionLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
||||
// result handled inline when requesting
|
||||
// Inform user about permission result
|
||||
if (isGranted) {
|
||||
// User granted permission
|
||||
// Ask user to press the panic button again to include location
|
||||
if (::viewModel.isInitialized) viewModel.dialogMessage = "Izin lokasi diberikan. Tekan kembali untuk menyertakan koordinat."
|
||||
} else {
|
||||
if (::viewModel.isInitialized) viewModel.dialogMessage = "Izin lokasi ditolak. Laporan akan dikirim tanpa koordinat."
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -33,8 +38,8 @@ class MainActivity : ComponentActivity() {
|
||||
startActivity(Intent(this, EvacuationMapsActivity::class.java))
|
||||
}
|
||||
|
||||
// onSendAlert will try to get location (if permission granted) and then call viewModel.sendAlert
|
||||
val onSendAlert = {
|
||||
@SuppressLint("MissingPermission")
|
||||
fun handleSendAlert() {
|
||||
// Check permission
|
||||
val fineGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|
||||
val coarseGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
|
||||
@ -44,28 +49,28 @@ class MainActivity : ComponentActivity() {
|
||||
requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
// After permission flow, user will need to press the button again to actually send with location
|
||||
viewModel.dialogMessage = "Izin lokasi dibutuhkan untuk menyertakan koordinat. Silakan tekan lagi setelah mengizinkan lokasi."
|
||||
return@let
|
||||
return
|
||||
}
|
||||
|
||||
// Try get last location asynchronously
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
try {
|
||||
val loc = fusedClient.lastLocation.await() // need extension await - we'll handle fallback
|
||||
// Try get last location asynchronously via Task listeners
|
||||
fusedClient.lastLocation
|
||||
.addOnSuccessListener { loc ->
|
||||
if (loc != null) {
|
||||
viewModel.sendAlert(loc.latitude, loc.longitude)
|
||||
} else {
|
||||
// fallback: send without coordinates
|
||||
viewModel.sendAlert()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
.addOnFailureListener {
|
||||
// If obtaining location fails, send without coordinates
|
||||
viewModel.sendAlert()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setContent {
|
||||
MaterialTheme {
|
||||
MainScreen(viewModel = viewModel, onOpenEvacMaps = openEvacMaps)
|
||||
MainScreen(viewModel = viewModel, onOpenEvacMaps = openEvacMaps, onSendAlert = ::handleSendAlert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@ -22,9 +22,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -91,17 +89,18 @@ fun MainScreen(viewModel: MainViewModel, onOpenEvacMaps: () -> Unit, onSendAlert
|
||||
}
|
||||
|
||||
// Dialog
|
||||
val dialogMessage = viewModel.dialogMessage
|
||||
if (!dialogMessage.isNullOrBlank()) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { viewModel.clearDialog() },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { viewModel.clearDialog() }) { Text("OK") }
|
||||
},
|
||||
title = { Text("🚨 Notifikasi", style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold)) },
|
||||
text = { Text(dialogMessage ?: "") }
|
||||
)
|
||||
}
|
||||
viewModel.dialogMessage
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?.let { msg ->
|
||||
AlertDialog(
|
||||
onDismissRequest = { viewModel.clearDialog() },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { viewModel.clearDialog() }) { Text("OK") }
|
||||
},
|
||||
title = { Text("🚨 Notifikasi", style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold)) },
|
||||
text = { Text(msg) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user