diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm
index 0a36505..1459877 100644
Binary files a/app/release/baselineProfiles/0/app-release.dm and b/app/release/baselineProfiles/0/app-release.dm differ
diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm
index 0123e74..a3e9a08 100644
Binary files a/app/release/baselineProfiles/1/app-release.dm and b/app/release/baselineProfiles/1/app-release.dm differ
diff --git a/app/release/ver1.apk b/app/release/ver1.1.apk
similarity index 88%
rename from app/release/ver1.apk
rename to app/release/ver1.1.apk
index e55c495..1b6d1ec 100644
Binary files a/app/release/ver1.apk and b/app/release/ver1.1.apk differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fbd0327..010eeb2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,7 +3,6 @@
xmlns:tools="http://schemas.android.com/tools">
-
-
-
-
-
= _notes.asStateFlow()
- private val _updateInfo = MutableStateFlow(null)
- val updateInfo: StateFlow = _updateInfo.asStateFlow()
-
- data class UpdateInfo(val versionCode: Int, val apkUrl: String)
-
- fun checkForUpdates(context: Context) {
- viewModelScope.launch(Dispatchers.IO) {
+ fun loadState(context: Context) {
+ val prefs = context.getSharedPreferences("inventory_prefs", Context.MODE_PRIVATE)
+ _notes.value = prefs.getString("notes", "") ?: ""
+
+ val machinesJson = prefs.getString("machines", null)
+ if (machinesJson != null) {
try {
- val url = URL("https://bbjsolution.org/AR/InwentARyzacja/src/branch/master/update.json")
- val connection = url.openConnection() as HttpURLConnection
- connection.connectTimeout = 5000
- connection.readTimeout = 5000
-
- if (connection.responseCode == 200) {
- val scanner = Scanner(connection.inputStream).useDelimiter("\\A")
- val result = if (scanner.hasNext()) scanner.next() else ""
- val json = JSONObject(result)
-
- val newVersionCode = json.getInt("versionCode")
- val apkUrl = json.getString("url")
-
- val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
- @Suppress("DEPRECATION")
- val currentVersionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- packageInfo.longVersionCode.toInt()
- } else {
- packageInfo.versionCode
- }
-
- if (newVersionCode > currentVersionCode) {
- _updateInfo.value = UpdateInfo(newVersionCode, apkUrl)
- }
+ val jsonArray = JSONArray(machinesJson)
+ val loadedList = mutableListOf()
+ for (i in 0 until jsonArray.length()) {
+ val obj = jsonArray.getJSONObject(i)
+ loadedList.add(
+ Machine(
+ id = obj.getString("id"),
+ name = obj.getString("name"),
+ category = obj.getString("category"),
+ originalStatus = obj.getString("originalStatus"),
+ isChecked = obj.getBoolean("isChecked")
+ )
+ )
}
+ _machines.value = loadedList
} catch (e: Exception) {
e.printStackTrace()
}
}
}
- fun downloadAndInstall(context: Context, apkUrl: String) {
- val request = DownloadManager.Request(Uri.parse(apkUrl))
- .setTitle("Aktualizacja inwentARyzacja")
- .setDescription("Pobieranie nowej wersji...")
- .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
- .setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "update.apk")
- .setAllowedOverMetered(true)
- .setAllowedOverRoaming(true)
-
- val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
- downloadManager.enqueue(request)
+ private fun saveState(context: Context) {
+ val prefs = context.getSharedPreferences("inventory_prefs", Context.MODE_PRIVATE)
+ val editor = prefs.edit()
+ editor.putString("notes", _notes.value)
+
+ val jsonArray = JSONArray()
+ _machines.value.forEach { machine ->
+ val obj = JSONObject()
+ obj.put("id", machine.id)
+ obj.put("name", machine.name)
+ obj.put("category", machine.category)
+ obj.put("originalStatus", machine.originalStatus)
+ obj.put("isChecked", machine.isChecked)
+ jsonArray.put(obj)
+ }
+ editor.putString("machines", jsonArray.toString())
+ editor.apply()
}
fun setSearchQuery(query: String) {
_searchQuery.value = query
}
- fun setNotes(newNotes: String) {
+ fun setNotes(context: Context, newNotes: String) {
_notes.value = newNotes
+ saveState(context)
}
fun appendDigit(digit: String) {
@@ -181,7 +162,7 @@ class InventoryViewModel : ViewModel() {
.sorted()
}
- fun markMachinesByStatuses(statuses: Set, isChecked: Boolean) {
+ fun markMachinesByStatuses(context: Context, statuses: Set, isChecked: Boolean) {
_machines.value = _machines.value.map { machine ->
if (statuses.contains(machine.originalStatus)) {
machine.copy(isChecked = isChecked)
@@ -189,9 +170,10 @@ class InventoryViewModel : ViewModel() {
machine
}
}
+ saveState(context)
}
- fun toggleMachineCheck(machineId: String) {
+ fun toggleMachineCheck(context: Context, machineId: String) {
_machines.value = _machines.value.map { machine ->
if (machine.id == machineId) {
machine.copy(isChecked = !machine.isChecked)
@@ -199,10 +181,11 @@ class InventoryViewModel : ViewModel() {
machine
}
}
+ saveState(context)
}
// Parser zoptymalizowany pod strukturę raportu z systemu
- fun parseXlsFile(inputStream: InputStream) {
+ fun parseXlsFile(context: Context, inputStream: InputStream) {
try {
// WorkbookFactory automatycznie obsługuje zarówno .xls jak i .xlsx
val workbook = WorkbookFactory.create(inputStream)
@@ -232,6 +215,7 @@ class InventoryViewModel : ViewModel() {
}
_machines.value = parsedList
workbook.close()
+ saveState(context)
} catch (e: Exception) {
e.printStackTrace()
}
@@ -242,38 +226,10 @@ class InventoryViewModel : ViewModel() {
// 3. GŁÓWNA AKTYWNOŚĆ
// ==========================================
class MainActivity : ComponentActivity() {
- private val onDownloadComplete = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
- if (id != -1L) {
- installApk(context)
- }
- }
- }
-
- private fun installApk(context: Context) {
- val file = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "update.apk")
- if (file.exists()) {
- val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
- val intent = Intent(Intent.ACTION_VIEW)
- intent.setDataAndType(uri, "application/vnd.android.package-archive")
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- context.startActivity(intent)
- }
- }
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
- ContextCompat.registerReceiver(
- this,
- onDownloadComplete,
- IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),
- ContextCompat.RECEIVER_EXPORTED
- )
-
setContent {
MaterialTheme(
colorScheme = darkColorScheme(
@@ -291,10 +247,6 @@ class MainActivity : ComponentActivity() {
}
}
}
- override fun onDestroy() {
- super.onDestroy()
- unregisterReceiver(onDownloadComplete)
- }
}
// ==========================================
@@ -308,42 +260,12 @@ fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
val searchQuery by viewModel.searchQuery.collectAsState()
val filterMissing by viewModel.filterMissing.collectAsState()
val notes by viewModel.notes.collectAsState()
- val updateInfo by viewModel.updateInfo.collectAsState()
var showStatusDialog by remember { mutableStateOf(false) }
var showNotesDialog by remember { mutableStateOf(false) }
- var showUpdateDialog by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
- viewModel.checkForUpdates(context)
- }
-
- LaunchedEffect(updateInfo) {
- if (updateInfo != null) {
- showUpdateDialog = true
- }
- }
-
- if (showUpdateDialog && updateInfo != null) {
- AlertDialog(
- onDismissRequest = { showUpdateDialog = false },
- title = { Text("Dostępna aktualizacja", color = Color.White) },
- text = { Text("Czy chcesz pobrać i zainstalować nową wersję aplikacji?", color = Color.White) },
- confirmButton = {
- Button(onClick = {
- viewModel.downloadAndInstall(context, updateInfo!!.apkUrl)
- showUpdateDialog = false
- }) {
- Text("Pobierz")
- }
- },
- dismissButton = {
- TextButton(onClick = { showUpdateDialog = false }) {
- Text("Później")
- }
- },
- containerColor = Color(0xFF1E2638)
- )
+ viewModel.loadState(context)
}
// Launcher akceptujący pliki .xlsx oraz .xls
@@ -352,7 +274,7 @@ fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
) { uri: Uri? ->
uri?.let {
context.contentResolver.openInputStream(it)?.use { inputStream ->
- viewModel.parseXlsFile(inputStream)
+ viewModel.parseXlsFile(context, inputStream)
}
}
}
@@ -362,7 +284,7 @@ fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
statuses = viewModel.getUniqueStatuses(),
onDismiss = { showStatusDialog = false },
onConfirm = { selectedStatuses ->
- viewModel.markMachinesByStatuses(selectedStatuses, true)
+ viewModel.markMachinesByStatuses(context, selectedStatuses, true)
showStatusDialog = false
}
)
@@ -371,7 +293,7 @@ fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
if (showNotesDialog) {
NotesDialog(
notes = notes,
- onNotesChange = { viewModel.setNotes(it) },
+ onNotesChange = { viewModel.setNotes(context, it) },
onDismiss = { showNotesDialog = false }
)
}
@@ -484,7 +406,7 @@ fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
items(filteredMachines, key = { it.id }) { machine ->
MachineItem(
machine = machine,
- onToggle = { viewModel.toggleMachineCheck(machine.id) }
+ onToggle = { viewModel.toggleMachineCheck(context, machine.id) }
)
}
}
diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml
deleted file mode 100644
index 7f68867..0000000
--- a/app/src/main/res/xml/file_paths.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file