From 5f9c644953eccd0a5879f3270b072c29b4c15d40 Mon Sep 17 00:00:00 2001 From: Dennis Arndt Date: Mon, 21 Apr 2025 13:17:00 +0100 Subject: [PATCH 01/71] create empty UI and navigation for tracker export --- .../ui/settings/FoundTrackersExport.kt | 9 +++++++++ .../ui/settings/InformationFragment.kt | 2 ++ .../ui/settings/SettingsFragment.kt | 13 +++++++++++++ .../res/drawable/ic_baseline_attach_file_24.xml | 5 +++++ .../res/layout/fragment_found_trackers_export.xml | 8 ++++++++ app/src/main/res/navigation/main_navigation.xml | 12 ++++++++++++ app/src/main/res/values-de/strings.xml | 4 ++++ app/src/main/res/values/strings.xml | 5 +++++ app/src/main/res/xml/fragment_settings.xml | 6 ++++++ 9 files changed, 64 insertions(+) create mode 100644 app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt create mode 100644 app/src/main/res/drawable/ic_baseline_attach_file_24.xml create mode 100644 app/src/main/res/layout/fragment_found_trackers_export.xml diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt new file mode 100644 index 00000000..d09b68e9 --- /dev/null +++ b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt @@ -0,0 +1,9 @@ +package de.seemoo.at_tracking_detection.ui.settings + +import androidx.fragment.app.Fragment +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class FoundTrackersExport : Fragment() { + +} \ No newline at end of file diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/InformationFragment.kt b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/InformationFragment.kt index 99f1eb67..a6dba083 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/InformationFragment.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/InformationFragment.kt @@ -14,8 +14,10 @@ import androidx.navigation.NavDirections import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import dagger.hilt.android.AndroidEntryPoint import de.seemoo.at_tracking_detection.R +@AndroidEntryPoint class InformationFragment : Fragment() { private lateinit var attributionList: RecyclerView diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/SettingsFragment.kt b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/SettingsFragment.kt index 2e1f2809..719b68fe 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/SettingsFragment.kt @@ -77,6 +77,13 @@ class SettingsFragment : PreferenceFragmentCompat() { setAdvancedModeButtonVisibility() + // TODO +// if (ATTrackingDetectionApplication.getCurrentApp().beaconRepository.totalCount > 0) { +// findPreference("export_found_trackers")?.isVisible = true +// } else { +// findPreference("export_found_trackers")?.isVisible = false +// } + val deactivateBackgroundScanningPref = findPreference("deactivate_background_scanning") deactivateBackgroundScanningPref?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> if (newValue as Boolean) { @@ -114,6 +121,12 @@ class SettingsFragment : PreferenceFragmentCompat() { true } + findPreference("export_found_trackers")?.onPreferenceClickListener = + Preference.OnPreferenceClickListener { + view?.findNavController()?.navigate(R.id.action_settings_to_export_found_trackers) + true + } + findPreference("delete_study_data")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { view?.findNavController()?.navigate(R.id.action_settings_to_data_deletion) diff --git a/app/src/main/res/drawable/ic_baseline_attach_file_24.xml b/app/src/main/res/drawable/ic_baseline_attach_file_24.xml new file mode 100644 index 00000000..dc6c07a4 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_attach_file_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_found_trackers_export.xml b/app/src/main/res/layout/fragment_found_trackers_export.xml new file mode 100644 index 00000000..a0993e98 --- /dev/null +++ b/app/src/main/res/layout/fragment_found_trackers_export.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml index 253d1372..201256e1 100644 --- a/app/src/main/res/navigation/main_navigation.xml +++ b/app/src/main/res/navigation/main_navigation.xml @@ -77,6 +77,10 @@ android:id="@+id/action_settings_to_data_deletion" app:destination="@id/data_deletion" /> + @@ -99,6 +103,14 @@ /> + + + + Hoch Information & Kontakt Bekomme Informationen über uns + Exportiere gefundene Tracker + Erstelle ein Dokument mit allen gefunden Trackern Studiendaten löschen Anfrage der Löschung der Studiendaten Gerätetypen herausfiltern @@ -396,4 +398,6 @@ Links Rechts + + Tracker exportieren diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8577b918..6a7241f5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -120,6 +120,9 @@ Information & Contact Get information about us + Export Found Trackers + Create a document with all identified trackers + Delete study data Request deletion of study data @@ -438,4 +441,6 @@ Left Right + Export Trackers + diff --git a/app/src/main/res/xml/fragment_settings.xml b/app/src/main/res/xml/fragment_settings.xml index b3b1f35b..383d7e37 100644 --- a/app/src/main/res/xml/fragment_settings.xml +++ b/app/src/main/res/xml/fragment_settings.xml @@ -10,6 +10,12 @@ android:summary="@string/settings_advanced_mode_summary" app:title="@string/settings_advanced_mode_title" /> + + Date: Mon, 21 Apr 2025 16:19:34 +0100 Subject: [PATCH 02/71] initial implementation of the PDF creation --- app/src/main/AndroidManifest.xml | 3 + .../database/daos/NotificationDao.kt | 3 + .../database/repository/LocationRepository.kt | 1 - .../repository/NotificationRepository.kt | 4 +- .../ui/settings/FoundTrackersExport.kt | 358 ++++++++++++++++++ .../layout/fragment_found_trackers_export.xml | 62 ++- app/src/main/res/values-de/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 8 files changed, 428 insertions(+), 7 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cb8732f2..3d4eaa83 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -45,6 +45,9 @@ + + > + @Query("SELECT * FROM notification") + fun getAllNotifications(): List + @Query("UPDATE notification SET falseAlarm = :state WHERE :id Like notificationId") suspend fun setFalseAlarm(id: Int, state: Boolean) diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/LocationRepository.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/LocationRepository.kt index 07d066c0..b6b88a8b 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/LocationRepository.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/LocationRepository.kt @@ -28,7 +28,6 @@ class LocationRepository @Inject constructor( fun getLocationsForBeaconSince(deviceAddress: String, since: LocalDateTime): List = locationDao.getLocationsForDeviceSince(deviceAddress, since) - fun getLocationsWithNoBeacons(): List = locationDao.getLocationsWithNoBeacons() @WorkerThread diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/NotificationRepository.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/NotificationRepository.kt index c8701b07..0aeee895 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/NotificationRepository.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/repository/NotificationRepository.kt @@ -44,7 +44,7 @@ class NotificationRepository @Inject constructor( */ val last_notification: List = notificationDao.getLastNotification() - fun notificationForDevice(device: BaseDevice) = notificationDao.getNotificationForDevice(device.address) + fun notificationForDevice(device: BaseDevice): List = notificationDao.getNotificationForDevice(device.address) fun getNotificationForDeviceSinceCount(deviceAddress: String, since: LocalDateTime): Int = notificationDao.getNotificationForDeviceSinceCount(deviceAddress, since) @@ -52,6 +52,8 @@ class NotificationRepository @Inject constructor( fun existsNotificationForDevice(deviceAddress: String): Boolean = notificationDao.existsNotificationForDevice(deviceAddress) + fun getAllNotifications(): List = notificationDao.getAllNotifications() + @WorkerThread suspend fun insert(notification: Notification): Long { return notificationDao.insert(notification) diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt index d09b68e9..718afd32 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/ui/settings/FoundTrackersExport.kt @@ -1,9 +1,367 @@ package de.seemoo.at_tracking_detection.ui.settings +import android.Manifest +import android.app.Activity +import android.app.AlertDialog +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Typeface +import android.graphics.pdf.PdfDocument +import android.os.Build +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.ProgressBar +import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import de.seemoo.at_tracking_detection.R +import de.seemoo.at_tracking_detection.database.models.device.BaseDevice +import de.seemoo.at_tracking_detection.database.repository.BeaconRepository +import de.seemoo.at_tracking_detection.database.repository.DeviceRepository +import de.seemoo.at_tracking_detection.database.repository.LocationRepository +import de.seemoo.at_tracking_detection.database.repository.NotificationRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import timber.log.Timber +import java.io.ByteArrayOutputStream +import java.time.format.DateTimeFormatter +import javax.inject.Inject @AndroidEntryPoint class FoundTrackersExport : Fragment() { + @Inject lateinit var deviceRepository: DeviceRepository + @Inject lateinit var beaconRepository: BeaconRepository + @Inject lateinit var locationRepository: LocationRepository + @Inject lateinit var notificationRepository: NotificationRepository + + private lateinit var exportDocumentButton: Button + private lateinit var progressBar: ProgressBar + + data class PageContext( + val page: PdfDocument.Page, + val canvas: Canvas, + val yPos: Float + ) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_found_trackers_export, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + exportDocumentButton = view.findViewById(R.id.create_document_button) + progressBar = view.findViewById(R.id.progress_bar) + + val exportDocumentButton = view.findViewById