Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e12bdd4
chore: [ANDROAPP-7432] Add workflow dispatch to dependency tracker an…
xavimolloy Jan 15, 2026
d87193d
Merge pull request #4589 from dhis2/release/3.3.1
xavimolloy Jan 16, 2026
e72f532
fix(translations): sync translations from transifex (main) [skip size…
dhis2-bot Feb 4, 2026
cbac4c1
fix(translations): sync translations from transifex (main) [skip size…
dhis2-bot Feb 12, 2026
196c524
fix(translations): sync translations from transifex (main) (#4659)
dhis2-bot Feb 16, 2026
0b67c23
fix(translations): sync translations from transifex (main) (#4686)
dhis2-bot Feb 25, 2026
84c475d
fix(translations): sync translations from transifex (main) (#4706)
dhis2-bot Mar 4, 2026
8755327
docs: Modify testing.agent.md to allow the posibility to fix or imple…
Copilot Mar 16, 2026
2da3def
Update version to 3.4.0-RC
dhis2-bot Mar 18, 2026
955aab1
build: update ruleEngine to 3.7.1 and expressionParser to 1.4.0 (#4758)
andresmr Mar 24, 2026
de2cd0f
fix: [ANDROAPP-7550] Update filters in main thread (#4783)
xavimolloy Apr 6, 2026
e0edafb
fix: [ANDROAPP-7550] maintain running status in syncStatusController …
xavimolloy Apr 10, 2026
aa15034
fix: [ANDROAPP-7569] change sync settings job period to one hour, syn…
xavimolloy Apr 10, 2026
d901176
fix: [ANDROAPP-7569] Workers not been properly scheduled (#4807)
Balcan Apr 28, 2026
20ebb7f
fix(translations): sync translations from transifex (main) (#4833)
dhis2-bot Apr 28, 2026
94f889d
fix: [ANDROAPP-7569] Set default sync periods if ASWA is not configur…
Balcan Apr 28, 2026
ac5fd7d
Update Sdk, Design System, and Version Code (#4845)
github-actions[bot] May 1, 2026
97bf68c
Merge branch 'main' into release/3.4.0-RC
andresmr May 1, 2026
315eb8d
build: update release 3.4.0 with main
andresmr May 1, 2026
f75af25
Merge pull request #4847 from dhis2/release/3.4.0-RC
andresmr May 1, 2026
b370a95
build: update release 3.4.0 version name and version code
andresmr May 1, 2026
23edd7d
Merge pull request #4850 from dhis2/update-version-name-and-version-code
andresmr May 1, 2026
48cc5b9
Merge branch 'release/3.4.1' into release/3.4.0-RC
andresmr May 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/generate-and-upload-bom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ jobs:
-H "Content-Type: multipart/form-data" \
-H "X-Api-Key: ${{ secrets.DEPENDENCYTRACK_APIKEY }}" \
-F "project=5d9c948b-3968-4f47-867f-3b7f04ba9fb6" \
-F "bom=@build/reports/bom.json"
-F "bom=@build/reports/bom.json"
79 changes: 31 additions & 48 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,58 @@
# Release notes - Android App for DHIS2 - 3.3.1
# Release notes - Android App for DHIS2 - 3.4.0

### Bug
### NEW FUNCTIONALITY AND WEB PARITY

[ANDROAPP-6870](https://dhis2.atlassian.net/browse/ANDROAPP-6870) Let the rule-engine apply the logic for useCodeForOptionSet in RuleVariable
#### Tracked Entity Search Performance Configuration:
This feature enables the configuration of the search operators for the different Tracked Entity Attributes to improve search performance.

[ANDROAPP-6975](https://dhis2.atlassian.net/browse/ANDROAPP-6975) Crash when rotating the device with the save dialog open
Tracked entity attributes can now define a preferred default search operator. This configuration is set in the Maintenance app and interpreted by the Capture Web and Android applications, third party clients can also use the recommended operator when performing searches. Specific operators can also be restricted to protect system performance.

[ANDROAPP-7211](https://dhis2.atlassian.net/browse/ANDROAPP-7211) NoSuchElementException: Collection contains no element matching the predicate.
Sensible defaults are automatically applied to guide efficient queries. The LIKE operator—commonly associated with slow performance—is no longer selected by default; instead, EQUALS or other more efficient operators are pre-selected

[ANDROAPP-7235](https://dhis2.atlassian.net/browse/ANDROAPP-7235) Program rules not triggered when moving between fields manually
To further optimize tracked entity instance (TEI) searches, this feature adds support for specifying a minimum number of characters required for searching and for enabling trigram indexing.

[ANDROAPP-7260](https://dhis2.atlassian.net/browse/ANDROAPP-7260) Incorrect behavior when creating a new event in timeline view
[Jira](https://dhis2.atlassian.net/browse/ROADMAP-128) | [Feature card](https://s3.eu-west-1.amazonaws.com/content.dhis2.org/releases/screenshots/43/feature-cards/43-search-performance-operators-combo.png)

[ANDROAPP-7261](https://dhis2.atlassian.net/browse/ANDROAPP-7261) Keyboard blocks the last field when entering data \(screen doesn’t scroll\)

[ANDROAPP-7269](https://dhis2.atlassian.net/browse/ANDROAPP-7269) Crash on search
#### DHIS2 Custom Theme:
DHIS2 version 43 now supports changing the theme color of your DHIS2 instance. This is done via the theme color setting under the Appearance tab in the Settings app. The color picker has a curated set of preset colors to choose from, or the user can enter a specific RGB value. The selected color is applied consistently across the headerbar on the entire instance, as well as on the Android app. A contrast algorithm automatically adjusts the text and icon color to maintain legibility against the selected background. Removing the color reverts the instance to the default blue color. The android style setting is restricted to v42 and below.

[ANDROAPP-7293](https://dhis2.atlassian.net/browse/ANDROAPP-7293) Bottom sheet landscape behavior
[Jira](https://dhis2.atlassian.net/browse/ROADMAP-622) | [Feature card](https://s3.eu-west-1.amazonaws.com/content.dhis2.org/releases/screenshots/43/feature-cards/43-custom-color-combo-new.png)

[ANDROAPP-7345](https://dhis2.atlassian.net/browse/ANDROAPP-7345) Changes to enrollment date not respected by program rules \(version 3.2.1.2\)
#### Markdown and legend support in Android Feedback Widget:
Feedback messages generated through display text and key-value pair actions can now include formatted text using Markdown, enabling the display of structured content such as titles, lists, and emphasized text.

[ANDROAPP-7368](https://dhis2.atlassian.net/browse/ANDROAPP-7368) crash: when trying to update fields in Tracker
In addition, support for legend-based styling has been introduced, allowing feedback values to be visually highlighted based on predefined legend sets. This enables dynamic color-coding of key values, helping users quickly interpret results and identify important conditions.

[ANDROAPP-7394](https://dhis2.atlassian.net/browse/ANDROAPP-7394) Login blocked after logout “The user is already logged in” error
[Jira]() | [Feature card]()

[ANDROAPP-7400](https://dhis2.atlassian.net/browse/ANDROAPP-7400) Crash - changing org unit and dates
#### Program rule priority for Actions:
Each program rule action can define an optional priority value. During rule evaluation, actions are first grouped based on their parent program rule, and then ordered by the611ir assigned priority. Actions with lower priority values are processed first, while actions without a defined priority are placed at the end.

[ANDROAPP-7402](https://dhis2.atlassian.net/browse/ANDROAPP-7402) Bottom sheet org unit not displaying buttons
This allows multiple related actions to be managed within a single program rule while still maintaining a clear and predictable execution order.

[ANDROAPP-7403](https://dhis2.atlassian.net/browse/ANDROAPP-7403) Home cards lose proper layout
[Jira](https://dhis2.atlassian.net/browse/ROADMAP-625) | [Feature card](https://s3.eu-west-1.amazonaws.com/content.dhis2.org/releases/screenshots/43/feature-cards/43-action-priority.png)

[ANDROAPP-7411](https://dhis2.atlassian.net/browse/ANDROAPP-7411) Android sync by working lists: After updating predefined list views settings, changes aren't reflected in android app after syncing

[ANDROAPP-7415](https://dhis2.atlassian.net/browse/ANDROAPP-7415) Android: WORKING LIST incorrect result in app
### USER EXPERIENCE

[ANDROAPP-7419](https://dhis2.atlassian.net/browse/ANDROAPP-7419) Server selection title is missing
#### Android Log In process improvements:
The new PIN design provides a more modern and consistent user experience during setup. This change is part of the broader work to improve authentication related screens and prepare the foundation for future enhancements

[ANDROAPP-7421](https://dhis2.atlassian.net/browse/ANDROAPP-7421) Data set table not opening after clicking next for default category combo
[Jira](https://dhis2.atlassian.net/browse/ROADMAP-618) | [Feature card](https://s3.eu-west-1.amazonaws.com/content.dhis2.org/releases/screenshots/43/feature-cards/Android-3-4-PIN-redesign-new.png)

[ANDROAPP-7425](https://dhis2.atlassian.net/browse/ANDROAPP-7425) NullPointerException: ProgramFragment
### PERFORMANCE & MAINTENANCE

[ANDROAPP-7428](https://dhis2.atlassian.net/browse/ANDROAPP-7428) LMIS program is using completed enrollment
#### Android Metadata Sync Improvements
Metadata synchronization has been enhanced with more frequency options. In addition to existing intervals, automatic metadata sync can now run every 6 or 12 hours, allowing for more timely updates and better alignment with data sync behavior.

[ANDROAPP-7442](https://dhis2.atlassian.net/browse/ANDROAPP-7442) Program rules not triggering for completed enrollments
As part of the improvements, the app also performs a daily background check to detect any changes in the configuration when the sync is set to "Manual". If a change is detected from manual to an automatic sync frequency, an immediate metadata sync is triggered and the corresponding schedule is applied.

### Task
[Jira](https://dhis2.atlassian.net/browse/ROADMAP-617) | [Feature card](https://s3.eu-west-1.amazonaws.com/content.dhis2.org/releases/screenshots/43/feature-cards/Android-3-4-new-sync-periods-new.png)

[ANDROAPP-7286](https://dhis2.atlassian.net/browse/ANDROAPP-7286) Replace deprecated categoryComboUid usages with categoryCombo in Program and DataElement
#### Improved Event ordering for consistent sync and calculations:
With this update, event ordering has been aligned across Web, Android, and API sources, allowing events to be processed in the correct sequence during synchronization and improving overall data consistency and reliability.

[ANDROAPP-7288](https://dhis2.atlassian.net/browse/ANDROAPP-7288) Implement UseCase interface
[Jira](https://dhis2.atlassian.net/browse/ROADMAP-619) | [Feature card](https://s3.eu-west-1.amazonaws.com/content.dhis2.org/releases/screenshots/43/feature-cards/43-stock-management-lmis.png)

[ANDROAPP-7318](https://dhis2.atlassian.net/browse/ANDROAPP-7318) Create AGENTS.md file

[ANDROAPP-7349](https://dhis2.atlassian.net/browse/ANDROAPP-7349) Sonarcloud - Use full commit SHA hash for this dependency.

[ANDROAPP-7373](https://dhis2.atlassian.net/browse/ANDROAPP-7373) LogoutUser use case improvements

[ANDROAPP-7384](https://dhis2.atlassian.net/browse/ANDROAPP-7384) Update transifex tracker configuration

[ANDROAPP-7386](https://dhis2.atlassian.net/browse/ANDROAPP-7386) QA: Remove duplicated UI modules

[ANDROAPP-7388](https://dhis2.atlassian.net/browse/ANDROAPP-7388) Create sync module

[ANDROAPP-7395](https://dhis2.atlassian.net/browse/ANDROAPP-7395) Review settings repository data loading for log out request

[ANDROAPP-7396](https://dhis2.atlassian.net/browse/ANDROAPP-7396) Remove and update usage to design systems' deprecated methods

[ANDROAPP-7424](https://dhis2.atlassian.net/browse/ANDROAPP-7424) Gradle warnings: Remove RX binding dependency and zxing dependency

[ANDROAPP-7426](https://dhis2.atlassian.net/browse/ANDROAPP-7426) Upload proguard mapping on Sentry

[ANDROAPP-7440](https://dhis2.atlassian.net/browse/ANDROAPP-7440) Update Expression parser to 1.2.2

[ANDROAPP-7441](https://dhis2.atlassian.net/browse/ANDROAPP-7441) Remove username from Sentry reports
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
<string name="input_coordinate_longitude">Longitude</string>
<string name="input_coordinate_add_location">Ajouter un lieu</string>
<string name="input_not_supported">Non supporté</string>
<string name="mark_dataset_complete">Voulez-vous également compléter l'ensemble de données?</string>
<string name="mark_dataset_complete">Voulez-vous également compléter l\'ensemble de données?</string>
<string name="not_now">Pas maintenant</string>
<string name="complete">Terminer</string>
<string name="saved">Enregistré!</string>
<string name="field_mandatory">Il manque des champs obligatoires. Veuillez les remplir pour compléter l'ensemble de données.</string>
<string name="field_required">Si vous saisissez une valeur, la ligne entière doit être remplie pour compléter l'ensemble de données.</string>
<string name="field_mandatory">Il manque des champs obligatoires. Veuillez les remplir pour compléter l\'ensemble de données.</string>
<string name="field_required">Si vous saisissez une valeur, la ligne entière doit être remplie pour compléter l\'ensemble de données.</string>
<string name="ok">Ok</string>
<string name="dataset_saved_completed">Enregistré et terminé!</string>
<string name="run_validation_rules">Voulez-vous vérifier la qualité des données?</string>
Expand All @@ -34,5 +34,5 @@
<string name="add_image">Ajouter une image</string>
<string name="take_photo">Prendre une photo</string>
<string name="indicators_label">Indicateurs</string>
<string name="no_data_write_access">Vous n'êtes pas autorisé à modifier ces données</string>
<string name="no_data_write_access">Vous n\'êtes pas autorisé à modifier ces données</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<string name="not_now">Не зараз</string>
<string name="complete">Завершити</string>
<string name="saved">Збережено!</string>
<string name="field_mandatory">Обов'язкові поля не заповнені. Будь ласка, заповніть їх, щоб завершити набір даних.</string>
<string name="field_mandatory">Обов\'язкові поля не заповнені. Будь ласка, заповніть їх, щоб завершити набір даних.</string>
<string name="field_required">Якщо Ви встановлюєте значення, то щодо усього рядка потрібно вказати всі значення, щоб завершити набір даних.</string>
<string name="ok">ОК</string>
<string name="dataset_saved_completed">Збережено та завершено!</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<string name="add_image">添加图片</string>
<string name="take_photo">拍照</string>
<string name="from_gallery">从图库添加</string>
<string name="empty_section_message">此部分配置错误。\n请联系您的管理员。</string>
<string name="empty_section_message">此部分配置错误。</string>
<string name="empty_dataset_message">此数据集配置错误。\n请联系您的管理员。</string>

<string name="indicators_label">指标</string>
Expand Down
11 changes: 8 additions & 3 deletions app/src/main/java/org/dhis2/usescases/settings/DeleteUserData.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package org.dhis2.usescases.settings

import kotlinx.coroutines.withContext
import org.dhis2.commons.filters.FilterManager
import org.dhis2.commons.prefs.PreferenceProvider
import org.dhis2.commons.viewmodel.DispatcherProvider
import org.dhis2.data.service.workManager.WorkManagerController
import java.io.File

class DeleteUserData(
class DeleteUserData(
private val workManagerController: WorkManagerController,
private val filterManager: FilterManager,
private val preferencesProvider: PreferenceProvider,
private val dispatcherProvider: DispatcherProvider,
) {
fun wipeCacheAndPreferences(file: File?) {
filterManager.clearAllFilters()
suspend fun wipeCacheAndPreferences(file: File?) {
withContext(dispatcherProvider.ui()) {
filterManager.clearAllFilters()
}
workManagerController.cancelAllWork()
workManagerController.pruneWork()
if (file != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.dhis2.usescases.settings

import android.text.format.DateFormat
import io.reactivex.Single
import org.dhis2.BuildConfig
import org.dhis2.bindings.toSeconds
Expand All @@ -15,6 +16,7 @@ import org.dhis2.commons.prefs.Preference.Companion.TIME_DAILY
import org.dhis2.commons.prefs.Preference.Companion.TIME_WEEKLY
import org.dhis2.commons.prefs.PreferenceProvider
import org.dhis2.data.service.SyncResult
import org.dhis2.mobile.sync.data.SyncBackgroundJobAction
import org.dhis2.usescases.settings.models.DataSettingsViewModel
import org.dhis2.usescases.settings.models.MetadataSettingsViewModel
import org.dhis2.usescases.settings.models.ReservedValueSettingsViewModel
Expand All @@ -29,10 +31,13 @@ import org.hisp.dhis.android.core.settings.SynchronizationSettings
import org.hisp.dhis.android.core.sms.domain.interactor.ConfigCase
import timber.log.Timber

private const val dateTimeFormat = "dd/MM/yyyy HH:mm"

class SettingsRepository(
val d2: D2,
val prefs: PreferenceProvider,
val featureConfigRepository: FeatureConfigRepository,
private val syncBackgroundJobAction: SyncBackgroundJobAction,
) {
private val syncSettings: SynchronizationSettings?
get() =
Expand Down Expand Up @@ -63,6 +68,9 @@ class SettingsRepository(
DataSettingsViewModel(
dataSyncPeriod = dataPeriod(),
lastDataSync = prefs.getString(Constants.LAST_DATA_SYNC, "-")!!,
nextDataSync = syncBackgroundJobAction.getNextDataSync()?.let {
DateFormat.format(dateTimeFormat, it).toString()
},
syncHasErrors = !prefs.getBoolean(Constants.LAST_DATA_SYNC_STATUS, true),
dataHasErrors = dataHasErrors(),
dataHasWarnings = dataHasWarning(),
Expand All @@ -80,6 +88,12 @@ class SettingsRepository(
MetadataSettingsViewModel(
metadataSyncPeriod = metadataPeriod(),
lastMetadataSync = prefs.getString(Constants.LAST_META_SYNC, "-")!!,
nextMetadataSync = syncBackgroundJobAction.getNextMetadataSync()?.let {
DateFormat.format(dateTimeFormat, it).toString()
},
nextSettingsSync = syncBackgroundJobAction.getNextSettingsSync()?.let {
DateFormat.format(dateTimeFormat, it).toString()
},
hasErrors = !prefs.getBoolean(Constants.LAST_META_SYNC_STATUS, true),
canEdit = syncSettings?.metadataSync() == null,
syncInProgress = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class SyncManagerModule(
d2,
preferenceProvider,
featureConfigRepository,
syncBackgroundJobAction,
)

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.dhis2.data.service.SyncResult
data class DataSettingsViewModel(
val dataSyncPeriod: Int,
val lastDataSync: String,
val nextDataSync: String?,
val syncHasErrors: Boolean,
val dataHasErrors: Boolean,
val dataHasWarnings: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.dhis2.usescases.settings.models
data class MetadataSettingsViewModel(
val metadataSyncPeriod: Int,
val lastMetadataSync: String,
val nextMetadataSync: String?,
val nextSettingsSync: String?,
val hasErrors: Boolean,
val canEdit: Boolean,
val syncInProgress: Boolean,
Expand Down
Loading
Loading