@Singleton
class TimeZoneBroadcastMonitor @Inject constructor(
@ApplicationContext private val context: Context,
@ApplicationScope appScope: CoroutineScope,
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
) : TimeZoneMonitor {
override val currentTimeZone: SharedFlow =
callbackFlow {
// Send the default time zone first.
trySend(TimeZone.currentSystemDefault())
// Registers BroadcastReceiver for the TimeZone changes
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != Intent.ACTION_TIMEZONE_CHANGED) return
val zoneIdFromIntent = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
null
} else {
// Starting Android R we also get the new TimeZone.
intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { timeZoneId ->
// We need to convert it from java.util.Timezone to java.time.ZoneId
val zoneId = ZoneId.of(timeZoneId, ZoneId.SHORT_IDS)
// Convert to kotlinx.datetime.TimeZone
zoneId.toKotlinTimeZone()
}
}
// If there isn't a zoneId in the intent, fallback to the systemDefault, which should also reflect the change
trySend(zoneIdFromIntent ?: TimeZone.currentSystemDefault())
}
}
trace("TimeZoneBroadcastReceiver.register") {
context.registerReceiver(receiver, IntentFilter(Intent.ACTION_TIMEZONE_CHANGED))
}
// Send here again, because registering the Broadcast Receiver can take up to several milliseconds.
// This way, we can reduce the likelihood that a TZ change wouldn't be caught with the Broadcast Receiver.
trySend(TimeZone.currentSystemDefault())
awaitClose {
context.unregisterReceiver(receiver)
}
}
// We use to prevent multiple emissions of the same type, because we use trySend multiple times.
.distinctUntilChanged()
.conflate()
.flowOn(ioDispatcher)
// Sharing the callback to prevent multiple BroadcastReceivers being registered
.shareIn(appScope, SharingStarted.WhileSubscribed(5_000), 1)
}
< /code>
GetHomeUseCase
@ExperimentalLayoutApi
@Composable
fun HomeScreen(
uiState: HomeUiState,
modifier: Modifier,
onTopicClick: (String) -> Unit,
currentTimeZone: State,
currentDate: State,
) {
when (uiState) {
HomeUiState.Empty -> EmptyState(modifier = modifier)
is HomeUiState.HomeData -> {
HomeItems(uiState = uiState, onTopicClick = onTopicClick, currentTimeZone=currentTimeZone,currentDate=currentDate,modifier = modifier, haveDate=true)
}
HomeUiState.Loading -> LoadingState(modifier = modifier)
is HomeUiState.HomeError -> {
HomeItems(uiState = uiState, onTopicClick = onTopicClick, currentTimeZone=currentTimeZone,currentDate=currentDate,modifier = modifier, haveDate=false)
}
}
}
< /code>
@ExperimentalLayoutApi
@Composable
fun HomeItems(
uiState: HomeUiState,
onTopicClick: (String) -> Unit,
modifier: Modifier,
haveDate: Boolean = false,
currentTimeZone: State,
currentDate: State
) {
// ...
val data = uiState as HomeUiState.HomeData
Text(
text = data.topics.data.fecha,
modifier = Modifier.padding(2.dp),
textAlign = TextAlign.Center,
)
}
Mein Problem mit diesem Code ist, dass, wenn ich das Datum im System ändere, die Homedata Informationen nicht mit dem neuen Datum aktualisiert werden.>
Ich habe eine Schnittstelle namens TimeZonemonitor zur Überwachung der Zeitzone oder des Datumsänderungen. Änderungen . Code: [code]TimeZoneMonitor[/code] [code]interface TimeZoneMonitor { val currentTimeZone: Flow val currentDate:Flow } < /code> TimeZoneBroadcastMonitor[/code] [code]@Singleton class TimeZoneBroadcastMonitor @Inject constructor( @ApplicationContext private val context: Context, @ApplicationScope appScope: CoroutineScope, @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, ) : TimeZoneMonitor {
override val currentTimeZone: SharedFlow = callbackFlow { // Send the default time zone first. trySend(TimeZone.currentSystemDefault())
// Registers BroadcastReceiver for the TimeZone changes val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action != Intent.ACTION_TIMEZONE_CHANGED) return
val zoneIdFromIntent = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { null } else { // Starting Android R we also get the new TimeZone. intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { timeZoneId -> // We need to convert it from java.util.Timezone to java.time.ZoneId val zoneId = ZoneId.of(timeZoneId, ZoneId.SHORT_IDS) // Convert to kotlinx.datetime.TimeZone zoneId.toKotlinTimeZone() } }
// If there isn't a zoneId in the intent, fallback to the systemDefault, which should also reflect the change trySend(zoneIdFromIntent ?: TimeZone.currentSystemDefault()) } }
// Send here again, because registering the Broadcast Receiver can take up to several milliseconds. // This way, we can reduce the likelihood that a TZ change wouldn't be caught with the Broadcast Receiver. trySend(TimeZone.currentSystemDefault())
awaitClose { context.unregisterReceiver(receiver) } } // We use to prevent multiple emissions of the same type, because we use trySend multiple times. .distinctUntilChanged() .conflate() .flowOn(ioDispatcher) // Sharing the callback to prevent multiple BroadcastReceivers being registered .shareIn(appScope, SharingStarted.WhileSubscribed(5_000), 1)
} < /code> GetHomeUseCase[/code] [code]class GetHomeUseCase @Inject constructor( private val universalisRepository: UniversalisRepository, private val userDataRepository: UserDataRepository, ) {
operator fun invoke( date: Int, ): Flow { return combine( userDataRepository.userData, universalisRepository.countUniversalis(UniversalisResourceQuery(date)), ) { userData, count -> if (count == 0 && date.isDateValid()) { universalisRepository.insertFromRemote(UniversalisResourceQuery(date)) } val newData = universalisRepository.getUniversalisForTest(date).first() HomeResource( date = date, data = newData, count = count, dynamic = userData ) } } } < /code> HomeViewModel[/code] [code]@HiltViewModel class HomeViewModel @Inject constructor( savedStateHandle: SavedStateHandle, private val analyticsHelper: AnalyticsHelper, timeZoneMonitor:TimeZoneMonitor, val userDataRepository: UserDataRepository, getHomeUseCase: GetHomeUseCase, ) : ViewModel() {
private val selectedTopicIdKey = "selectedTopicIdKey" private val route: UniversalisRoute = savedStateHandle.toRoute()
val currentTimeZone = timeZoneMonitor.currentTimeZone .stateIn( viewModelScope, SharingStarted.WhileSubscribed(5_000), TimeZone.currentSystemDefault(), ) val zi = ZoneId.of(currentTimeZone.value.id) val time = ZonedDateTime.now(zi) private val newDate=time.format(DateTimeFormatter.ofPattern("yyyyMMdd")).toInt() private var selectedDate = savedStateHandle.getStateFlow( key = "date", initialValue = newDate, )
val uiState: StateFlow = combine( selectedTopicId, selectedDate, getHomeUseCase.invoke( date = selectedDate.value, ), HomeUiState::HomeData, ).catch { val error = HomeUiState.HomeError( date = selectedDate.value, message = it.message!! ) analyticsHelper.logHomeErrorEvent(error) emit(error) }//.distinctUntilChanged() .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), initialValue = HomeUiState.Loading, ) }
sealed interface HomeUiState { data object Loading : HomeUiState
data class HomeData( val selectedTopicId: String?, val selectedDate:Int, val topics: HomeResource, ) : HomeUiState
data class HomeError( val date: Int, val message: String ) : HomeUiState {
@ExperimentalLayoutApi @Composable fun HomeItems( uiState: HomeUiState, onTopicClick: (String) -> Unit, modifier: Modifier, haveDate: Boolean = false, currentTimeZone: State, currentDate: State
) {
// ... val data = uiState as HomeUiState.HomeData
Text( text = data.topics.data.fecha, modifier = Modifier.padding(2.dp), textAlign = TextAlign.Center, ) } [/code] Mein [url=viewtopic.php?t=15738]Problem[/url] mit diesem Code ist, dass, wenn ich das Datum im System ändere, die Homedata Informationen nicht mit dem neuen Datum aktualisiert werden.>
Ich verwende das sqlite3-Modul in Python 2.6.4, um eine Datums- und Uhrzeitangabe in einer SQLite-Datenbank zu speichern. Das Einfügen ist sehr einfach, da SQLite das Datum automatisch in einen...
Ich verwende den Hilt mit WorkManager, um Benachrichtigungen im Hintergrund in meiner Anwendung zu synchronisieren, aber ich begegne einen Java.lang.NosuchMethodException Fehler beim Versuch, eine...
Ich folge dem exzellenten Learn .NET MAUI-Vollständiger Kurs für Anfänger von James Montemagno
In diesem Tutorial erklärt er, wie man die CommunityToolkit.MVVM
verwendet. Ich habe Probleme mit der...
Beim Ausführen meines LIBGDX -Desktop -Projekts erhalte ich manchmal diesen Fehler:
Changes are not tracked, unable determine incremental changes.
Ich habe versucht, Java 8 und 17 zu verwenden....