mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
@@ -24,6 +24,9 @@ class GeneralSettings @Inject constructor(
|
||||
override val preferences: SharedPreferences = context.getSharedPreferences("settings_general", Context.MODE_PRIVATE)
|
||||
|
||||
val monitorMode = preferences.createFlowPreference("core.monitor.mode", MonitorMode.AUTOMATIC, moshi)
|
||||
|
||||
val useExtraMonitorNotification = preferences.createFlowPreference("core.monitor.notification.connected", false)
|
||||
|
||||
val scannerMode = preferences.createFlowPreference("core.scanner.mode", ScannerMode.BALANCED, moshi)
|
||||
|
||||
val showAll = preferences.createFlowPreference("core.showall.enabled", true)
|
||||
@@ -44,6 +47,7 @@ class GeneralSettings @Inject constructor(
|
||||
|
||||
override val preferenceDataStore: PreferenceDataStore = PreferenceStoreMapper(
|
||||
monitorMode,
|
||||
useExtraMonitorNotification,
|
||||
scannerMode,
|
||||
showAll,
|
||||
minimumSignalQuality,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M23 4.5C23 6.43 21.43 8 19.5 8S16 6.43 16 4.5 17.57 1 19.5 1 23 2.57 23 4.5M19.5 10C16.47 10 14 7.53 14 4.5C14 4 14.08 3.5 14.21 3H5C3.89 3 3 3.89 3 5V19C3 20.11 3.9 21 5 21H19C20.11 21 21 20.11 21 19V9.79C20.5 9.92 20 10 19.5 10Z" />
|
||||
</vector>
|
||||
@@ -22,7 +22,6 @@ import eu.darken.capod.common.flow.throttleLatest
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import eu.darken.capod.main.core.MonitorMode
|
||||
import eu.darken.capod.main.core.PermissionTool
|
||||
import eu.darken.capod.main.ui.widget.WidgetManager
|
||||
import eu.darken.capod.monitor.core.MonitorCoroutineScope
|
||||
import eu.darken.capod.monitor.core.PodMonitor
|
||||
import eu.darken.capod.monitor.ui.MonitorNotifications
|
||||
@@ -51,7 +50,7 @@ class MonitorWorker @AssistedInject constructor(
|
||||
@Assisted private val context: Context,
|
||||
@Assisted private val params: WorkerParameters,
|
||||
private val dispatcherProvider: DispatcherProvider,
|
||||
private val monitorNotifications: MonitorNotifications,
|
||||
private val notifications: MonitorNotifications,
|
||||
private val notificationManager: NotificationManager,
|
||||
private val generalSettings: GeneralSettings,
|
||||
private val permissionTool: PermissionTool,
|
||||
@@ -61,7 +60,6 @@ class MonitorWorker @AssistedInject constructor(
|
||||
private val autoConnect: AutoConnect,
|
||||
private val popUpReaction: PopUpReaction,
|
||||
private val popUpWindow: PopUpWindow,
|
||||
private val widgetManager: WidgetManager,
|
||||
) : CoroutineWorker(context, params) {
|
||||
|
||||
private val workerScope = MonitorCoroutineScope()
|
||||
@@ -73,7 +71,7 @@ class MonitorWorker @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override suspend fun getForegroundInfo(): ForegroundInfo {
|
||||
return monitorNotifications.getForegroundInfo(null)
|
||||
return notifications.getForegroundInfo(null)
|
||||
}
|
||||
|
||||
override suspend fun doWork(): Result = try {
|
||||
@@ -106,7 +104,7 @@ class MonitorWorker @AssistedInject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
setForeground(monitorNotifications.getForegroundInfo(null))
|
||||
setForeground(notifications.getForegroundInfo(null))
|
||||
|
||||
val monitorJob = podMonitor.mainDevice
|
||||
.setupCommonEventHandlers(TAG) { "PodMonitor" }
|
||||
@@ -115,8 +113,14 @@ class MonitorWorker @AssistedInject constructor(
|
||||
.onEach { currentDevice ->
|
||||
notificationManager.notify(
|
||||
MonitorNotifications.NOTIFICATION_ID,
|
||||
monitorNotifications.getNotification(currentDevice)
|
||||
notifications.getNotification(currentDevice),
|
||||
)
|
||||
if (generalSettings.useExtraMonitorNotification.value && currentDevice != null) {
|
||||
notificationManager.notify(
|
||||
MonitorNotifications.NOTIFICATION_ID_CONNECTED,
|
||||
notifications.getNotificationConnected(currentDevice),
|
||||
)
|
||||
}
|
||||
}
|
||||
.catch {
|
||||
log(TAG, WARN) { "Pod Flow failed:\n${it.asLog()}" }
|
||||
@@ -128,20 +132,23 @@ class MonitorWorker @AssistedInject constructor(
|
||||
if (missingPermsFlow.isNotEmpty()) {
|
||||
log(TAG, WARN) { "Aborting, permissions are missing: $missingPermsFlow" }
|
||||
workerScope.coroutineContext.cancelChildren()
|
||||
return@flatMapLatest emptyFlow()
|
||||
}
|
||||
combine(
|
||||
generalSettings.monitorMode.flow,
|
||||
generalSettings.mainDeviceAddress.flow,
|
||||
bluetoothManager.connectedDevices(),
|
||||
) { monitorMode, mainAddress, connectedDevices ->
|
||||
listOf(monitorMode, mainAddress, connectedDevices)
|
||||
emptyFlow()
|
||||
} else {
|
||||
combine(
|
||||
generalSettings.monitorMode.flow,
|
||||
generalSettings.mainDeviceAddress.flow,
|
||||
bluetoothManager.connectedDevices(),
|
||||
) { monitorMode, mainAddress, connectedDevices ->
|
||||
listOf(monitorMode, mainAddress, connectedDevices)
|
||||
}
|
||||
}
|
||||
}
|
||||
.setupCommonEventHandlers(TAG) { "MonitorMode" }
|
||||
.flatMapLatest { arguments ->
|
||||
val monitorMode = arguments[0] as MonitorMode
|
||||
val mainAddress = arguments[1] as String?
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val devices = arguments[2] as Collection<BluetoothDevice2>
|
||||
|
||||
log(TAG) { "Monitor mode: $monitorMode" }
|
||||
@@ -150,15 +157,18 @@ class MonitorWorker @AssistedInject constructor(
|
||||
// Cancel worker, ui scans manually
|
||||
workerScope.coroutineContext.cancelChildren()
|
||||
}
|
||||
|
||||
MonitorMode.ALWAYS -> emptyFlow()
|
||||
MonitorMode.AUTOMATIC -> flow {
|
||||
when {
|
||||
mainAddress == null && devices.isNotEmpty() -> {
|
||||
log(TAG, WARN) { "Main device address not set, staying alive while any is connected" }
|
||||
}
|
||||
|
||||
devices.any { it.address == mainAddress } -> {
|
||||
log(TAG) { "Main device is connected ($mainAddress), aborting any timeout." }
|
||||
}
|
||||
|
||||
else -> {
|
||||
log(TAG) { "No known Pods are connected, canceling worker soon." }
|
||||
delay(15 * 1000)
|
||||
|
||||
@@ -49,6 +49,11 @@ class MonitorNotifications @Inject constructor(
|
||||
context.getString(R.string.notification_channel_device_status_label),
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).run { notificationManager.createNotificationChannel(this) }
|
||||
NotificationChannel(
|
||||
NOTIFICATION_CHANNEL_ID_CONNECTED,
|
||||
context.getString(R.string.notification_channel_device_status_connected_label),
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).run { notificationManager.createNotificationChannel(this) }
|
||||
|
||||
val openIntent = Intent(context, MainActivity::class.java)
|
||||
val openPi = PendingIntent.getActivity(
|
||||
@@ -59,7 +64,6 @@ class MonitorNotifications @Inject constructor(
|
||||
)
|
||||
|
||||
builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID).apply {
|
||||
setChannelId(NOTIFICATION_CHANNEL_ID)
|
||||
setContentIntent(openPi)
|
||||
priority = NotificationCompat.PRIORITY_LOW
|
||||
setSmallIcon(eu.darken.capod.common.R.drawable.devic_earbuds_generic_both)
|
||||
@@ -145,11 +149,21 @@ class MonitorNotifications @Inject constructor(
|
||||
}
|
||||
|
||||
suspend fun getNotification(podDevice: PodDevice?): Notification = builderLock.withLock {
|
||||
getBuilder(podDevice).build()
|
||||
getBuilder(podDevice).apply {
|
||||
setChannelId(NOTIFICATION_CHANNEL_ID)
|
||||
}.build()
|
||||
}
|
||||
|
||||
suspend fun getNotificationConnected(podDevice: PodDevice?): Notification = builderLock.withLock {
|
||||
getBuilder(podDevice).apply {
|
||||
setChannelId(NOTIFICATION_CHANNEL_ID_CONNECTED)
|
||||
}.build()
|
||||
}
|
||||
|
||||
suspend fun getForegroundInfo(podDevice: PodDevice?): ForegroundInfo = builderLock.withLock {
|
||||
getBuilder(podDevice).toForegroundInfo()
|
||||
getBuilder(podDevice).apply {
|
||||
setChannelId(NOTIFICATION_CHANNEL_ID)
|
||||
}.toForegroundInfo()
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
@@ -168,8 +182,10 @@ class MonitorNotifications @Inject constructor(
|
||||
|
||||
companion object {
|
||||
val TAG = logTag("Monitor", "Notifications")
|
||||
private val NOTIFICATION_CHANNEL_ID =
|
||||
"${BuildConfigWrap.APPLICATION_ID}.notification.channel.device.status"
|
||||
private val NOTIFICATION_CHANNEL_ID = "${BuildConfigWrap.APPLICATION_ID}.notification.channel.device.status"
|
||||
private val NOTIFICATION_CHANNEL_ID_CONNECTED =
|
||||
"${BuildConfigWrap.APPLICATION_ID}.notification.channel.device.status.connected"
|
||||
internal const val NOTIFICATION_ID = 1
|
||||
internal const val NOTIFICATION_ID_CONNECTED = 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<string name="settings_popup_connected_label">Verbindungs-Popup anzeigen</string>
|
||||
<string name="settings_popup_connected_description">Zeigt ein Popup an, wenn das Gerät zum ersten Mal eine Verbindung herstellt.</string>
|
||||
<string name="notification_channel_device_status_label">Geräte Status</string>
|
||||
<string name="notification_channel_device_status_connected_label">Verbundenes Gerät</string>
|
||||
<string name="support_debuglog_label">Debug-Protokoll</string>
|
||||
<string name="support_debuglog_desc">Zeichne alle Aktivitäten der App in einer Textdatei auf, die du weitergeben kannst.</string>
|
||||
<string name="debug_debuglog_size_label">Größe</string>
|
||||
@@ -77,7 +78,7 @@
|
||||
<string name="settings_licenses_label">Lizenzen</string>
|
||||
<string name="settings_category_other_label">Andere</string>
|
||||
<string name="settings_general_label">Einstellungen</string>
|
||||
<string name="settings_general_description">Allgemeine Optimierungen, die die gesamte App betreffen.</string>
|
||||
<string name="settings_general_description" tools:ignore="Typos">Allgemeine Optimierungen, die die gesamte App betreffen.</string>
|
||||
<string name="settings_acknowledgements_label">Danksagungen</string>
|
||||
<string name="settings_debug_autoreports_label">Automatische Fehlerberichte</string>
|
||||
<string name="settings_debug_autoreports_description">Meldet Probleme automatisch, z.B. Details zu einem App-Absturz, damit ich herausfinden kann, wie ich ihn beheben kann.</string>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
<string name="settings_monitor_mode_label">Monitor mode</string>
|
||||
<string name="settings_monitor_mode_description">Under which circumstances this app monitors Bluetooth data.</string>
|
||||
<string name="settings_monitor_connected_notification_label">Extra notification</string>
|
||||
<string name="settings_monitor_connected_notification_description">Shows an extra notification when a device is connected. This lets you hide the permanent \"No devices\" notification by disabling the \"Device status\" channel.</string>
|
||||
<string name="settings_scanner_mode_label">Scanner mode</string>
|
||||
<string name="settings_scanner_mode_description">Should the Bluetooth Low Energy data scanner prioritize performance or conserve energy?</string>
|
||||
<string name="settings_autopause_label">Auto pause</string>
|
||||
@@ -55,6 +57,7 @@
|
||||
<string name="settings_popup_connected_description">Show a popup when the device connects for the first time.</string>
|
||||
|
||||
<string name="notification_channel_device_status_label">Device status</string>
|
||||
<string name="notification_channel_device_status_connected_label">Connected device</string>
|
||||
|
||||
<string name="support_debuglog_label">Debug log</string>
|
||||
<string name="support_debuglog_desc">Record everything the app is doing into a text file that you can share.</string>
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/settings_category_other_label">
|
||||
|
||||
<eu.darken.capod.common.preferences.MaterialSwitchPreference
|
||||
android:icon="@drawable/ic_checkbox_blank_badge_24"
|
||||
android:key="core.monitor.notification.connected"
|
||||
android:summary="@string/settings_monitor_connected_notification_description"
|
||||
android:title="@string/settings_monitor_connected_notification_label" />
|
||||
|
||||
<Preference
|
||||
android:fragment="eu.darken.capod.main.ui.settings.general.debug.DebugSettingsFragment"
|
||||
android:icon="@drawable/ic_baseline_bug_report_24"
|
||||
|
||||
Reference in New Issue
Block a user