Skip to content

Commit a4a55a0

Browse files
authored
Switch AppDataStore to Java instead of Kotlin (#418)
1 parent 618d217 commit a4a55a0

File tree

7 files changed

+100
-111
lines changed

7 files changed

+100
-111
lines changed

build.gradle

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import com.github.spotbugs.snom.Confidence
22
import com.github.spotbugs.snom.Effort
33

44
buildscript {
5-
ext {
6-
kotlin_version = '1.9.22'
7-
}
85
repositories {
96
mavenCentral()
107
maven { url 'https://jitpack.io' }
@@ -14,7 +11,6 @@ buildscript {
1411
dependencies {
1512
classpath 'com.android.tools.build:gradle:8.10.1'
1613
classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.1.13'
17-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1814
}
1915
}
2016

@@ -23,7 +19,6 @@ apply plugin: 'checkstyle'
2319
apply plugin: 'pmd'
2420
apply plugin: 'com.github.spotbugs'
2521
apply from: 'coverage.gradle'
26-
apply plugin: 'org.jetbrains.kotlin.android'
2722

2823
// enable verbose lint warnings
2924
gradle.projectsEvaluated {
@@ -475,23 +470,19 @@ android {
475470
universalApk false
476471
}
477472
}
478-
kotlinOptions {
479-
jvmTarget = '17'
480-
}
481473
}
482474

483-
def androidXCoreVersion = '1.16.0'
484475
dependencies {
485476
implementation fileTree(dir: 'libs', include: ['*.jar'])
486477
implementation platform('org.jetbrains.kotlin:kotlin-bom:1.9.24')
487478
implementation 'androidx.browser:browser:1.8.0'
488479
implementation 'androidx.appcompat:appcompat:1.7.1'
489480
implementation 'androidx.work:work-runtime:2.10.5'
490-
implementation 'androidx.core:core:$androidXCoreVersion'
491-
implementation 'androidx.core:core-ktx:$androidXCoreVersion'
481+
implementation 'androidx.core:core:1.16.0'
492482
implementation 'androidx.activity:activity:1.10.1'
493483
implementation 'androidx.fragment:fragment:1.8.8'
494484
implementation "androidx.datastore:datastore-preferences:1.1.7"
485+
implementation "androidx.datastore:datastore-preferences-rxjava3:1.1.7"
495486
compileOnly 'com.github.spotbugs:spotbugs-annotations:4.9.3'
496487
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
497488
testImplementation 'junit:junit:4.13.2'
@@ -508,4 +499,4 @@ dependencies {
508499
androidTestImplementation 'androidx.test:rules:1.7.0'
509500
androidTestImplementation 'androidx.test:core:1.7.0'
510501
androidTestImplementation 'org.hamcrest:hamcrest-library:2.2'
511-
}
502+
}

src/main/java/org/medicmobile/webapp/mobile/AppNotificationManager.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public AppNotificationManager(Context context) {
4949
SettingsStore settings = SettingsStore.in(context);
5050
this.appUrl = settings.getAppUrl();
5151
manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
52-
appDataStore = new AppDataStore(this.context);
52+
appDataStore = AppDataStore.getInstance(this.context);
5353
createNotificationChannel();
5454
}
5555

@@ -115,7 +115,7 @@ public void showNotificationsFromJsArray(String jsArrayString) throws JSONExcept
115115
private void showMultipleTaskNotifications(JSONArray dataArray) throws JSONException {
116116
Intent intent = new Intent(context, EmbeddedBrowserActivity.class);
117117
intent.setData(Uri.parse(TextUtils.concat(appUrl, "/#/tasks").toString()));
118-
long maxNotifications = appDataStore.getLongBlocking(MAX_NOTIFICATIONS_TO_SHOW_KEY, 8);
118+
long maxNotifications = appDataStore.getLongBlocking(MAX_NOTIFICATIONS_TO_SHOW_KEY, 8L);
119119
long latestStoredTimestamp = getLatestStoredTimestamp(getStartOfDay());
120120
int counter = 0;
121121
for (int i = 0; i < dataArray.length(); i++) {
@@ -156,11 +156,11 @@ private long getLatestStoredTimestamp(long startOfDay) {
156156
if (isNewDay(startOfDay)) {
157157
return 0;
158158
}
159-
return appDataStore.getLongBlocking(LATEST_NOTIFICATION_TIMESTAMP_KEY, 0);
159+
return appDataStore.getLongBlocking(LATEST_NOTIFICATION_TIMESTAMP_KEY, 0L);
160160
}
161161

162162
private boolean isNewDay(long startOfDay) {
163-
long storedNotificationDay = appDataStore.getLongBlocking(TASK_NOTIFICATION_DAY_KEY, 0);
163+
long storedNotificationDay = appDataStore.getLongBlocking(TASK_NOTIFICATION_DAY_KEY, 0L);
164164
if (getStartOfDay() != storedNotificationDay) {
165165
appDataStore.saveLong(TASK_NOTIFICATION_DAY_KEY, startOfDay);
166166
return true;
@@ -197,4 +197,4 @@ private void createNotificationChannel() {
197197
}
198198
}
199199

200-
}
200+
}

src/main/java/org/medicmobile/webapp/mobile/MedicAndroidJavascript.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ public void mrdt_verify() {
168168
}
169169

170170
@JavascriptInterface
171-
public void updateTaskNotificationStore(String notifications, int maxNotifications) {
172-
AppDataStore appDataStore = new AppDataStore(parent.getApplicationContext());
171+
public void updateTaskNotificationStore(String notifications, long maxNotifications) {
172+
AppDataStore appDataStore = AppDataStore.getInstance(parent.getApplicationContext());
173173
appDataStore.saveLong(AppNotificationManager.MAX_NOTIFICATIONS_TO_SHOW_KEY, maxNotifications);
174174
appDataStore.saveString(AppNotificationManager.TASK_NOTIFICATIONS_KEY, notifications);
175175
}

src/main/java/org/medicmobile/webapp/mobile/NotificationWorker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters wo
2424
@Override
2525
public Result doWork() {
2626
Context context = getApplicationContext();
27-
AppDataStore appDataStore = new AppDataStore(context);
27+
AppDataStore appDataStore = AppDataStore.getInstance(context);
2828
AppNotificationManager appNotificationManager = new AppNotificationManager(context);
2929
try {
3030
String result = appDataStore
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package org.medicmobile.webapp.mobile.util;
2+
3+
import static org.medicmobile.webapp.mobile.MedicLog.log;
4+
5+
import android.content.Context;
6+
7+
import androidx.annotation.Nullable;
8+
import androidx.annotation.OptIn;
9+
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler;
10+
import androidx.datastore.preferences.core.MutablePreferences;
11+
import androidx.datastore.preferences.core.Preferences;
12+
import androidx.datastore.preferences.core.Preferences.Key;
13+
import androidx.datastore.preferences.core.PreferencesKeys;
14+
import androidx.datastore.preferences.rxjava3.RxPreferenceDataStoreBuilder;
15+
import androidx.datastore.rxjava3.RxDataStore;
16+
17+
import io.reactivex.rxjava3.core.Single;
18+
19+
@OptIn(markerClass = kotlinx.coroutines.ExperimentalCoroutinesApi.class)
20+
public class AppDataStore {
21+
private static final String DATASTORE_NAME = "cht_datastore";
22+
private static AppDataStore instance;
23+
private final RxDataStore<Preferences> dataStore;
24+
25+
private AppDataStore(Context context) {
26+
ReplaceFileCorruptionHandler<Preferences> corruptionHandler = new ReplaceFileCorruptionHandler<>(corruptionException -> {
27+
log(corruptionException, "Data store corrupted");
28+
return new MutablePreferences();
29+
});
30+
dataStore = new RxPreferenceDataStoreBuilder(context, DATASTORE_NAME)
31+
.setCorruptionHandler(corruptionHandler)
32+
.build();
33+
}
34+
35+
public static synchronized AppDataStore getInstance(Context context) {
36+
if (instance == null) {
37+
instance = new AppDataStore(context);
38+
}
39+
return instance;
40+
}
41+
42+
private <T> Single<Preferences> save(Key<T> prefKey, T value) {
43+
return dataStore.updateDataAsync(preferences -> {
44+
MutablePreferences mutablePreferences = preferences.toMutablePreferences();
45+
mutablePreferences.set(prefKey, value);
46+
return Single.just(mutablePreferences);
47+
});
48+
}
49+
50+
public void saveString(String key, String value) {
51+
save(PreferencesKeys.stringKey(key), value);
52+
}
53+
54+
public void saveLong(String key, Long value) {
55+
save(PreferencesKeys.longKey(key), value);
56+
}
57+
58+
public void saveLongBlocking(String key, Long value) {
59+
Single<Preferences> updateResult = save(PreferencesKeys.longKey(key), value);
60+
Preferences ignored = updateResult.blockingGet(); // NOSONAR
61+
}
62+
63+
private <T> T getBlocking(Key<T> key, @Nullable T defaultValue) {
64+
return dataStore
65+
.data()
66+
.map(preferences -> {
67+
T value = preferences.get(key);
68+
return value != null ? value : defaultValue;
69+
})
70+
.blockingFirst();
71+
}
72+
73+
public String getStringBlocking(String key, @Nullable String defaultValue) {
74+
return getBlocking(PreferencesKeys.stringKey(key), defaultValue);
75+
}
76+
77+
public long getLongBlocking(String key, @Nullable Long defaultValue) {
78+
return getBlocking(PreferencesKeys.longKey(key), defaultValue);
79+
}
80+
}

src/main/java/org/medicmobile/webapp/mobile/util/AppDataStore.kt

Lines changed: 0 additions & 82 deletions
This file was deleted.

src/test/java/org/medicmobile/webapp/mobile/AppNotificationManagerTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ public void setup() {
3737
shadowNotificationManager = Shadows.shadowOf(testNotificationManager);
3838
appNotificationManager = spy(new AppNotificationManager(context));
3939
startOfDay = appNotificationManager.getStartOfDay();
40-
appDataStore = new AppDataStore(context);
40+
appDataStore = AppDataStore.getInstance(context);
4141
useBlockingDataStoreGet();
4242
}
4343

4444
@After
4545
public void resetDataStore() {
4646
appDataStore.saveString(AppNotificationManager.TASK_NOTIFICATIONS_KEY, "[]");
47-
appDataStore.saveLong(AppNotificationManager.TASK_NOTIFICATION_DAY_KEY, 0);
48-
appDataStore.saveLong(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 0);
49-
appDataStore.saveLong(AppNotificationManager.MAX_NOTIFICATIONS_TO_SHOW_KEY, 8);
47+
appDataStore.saveLong(AppNotificationManager.TASK_NOTIFICATION_DAY_KEY, 0L);
48+
appDataStore.saveLong(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 0L);
49+
appDataStore.saveLong(AppNotificationManager.MAX_NOTIFICATIONS_TO_SHOW_KEY, 8L);
5050
}
5151

5252
@Test
@@ -58,14 +58,14 @@ public void showsAndDismissesAllNotifications() throws JSONException {
5858
appNotificationManager.cancelAllNotifications();
5959
assertEquals(0, shadowNotificationManager.getAllNotifications().size());
6060

61-
assertEquals(appDataStore.getLongBlocking(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 99), taskDate);
62-
assertEquals(appDataStore.getLongBlocking(AppNotificationManager.TASK_NOTIFICATION_DAY_KEY, 99), startOfDay);
61+
assertEquals(appDataStore.getLongBlocking(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 99L), taskDate);
62+
assertEquals(appDataStore.getLongBlocking(AppNotificationManager.TASK_NOTIFICATION_DAY_KEY, 99L), startOfDay);
6363
}
6464

6565
@Test
6666
public void showsOnlyMaxAllowedNotifications() throws JSONException {
6767
String jsData = "[" + getJSTaskNotificationString(startOfDay, startOfDay, startOfDay) + "]";
68-
appDataStore.saveLongBlocking(AppNotificationManager.MAX_NOTIFICATIONS_TO_SHOW_KEY, 1);
68+
appDataStore.saveLongBlocking(AppNotificationManager.MAX_NOTIFICATIONS_TO_SHOW_KEY, 1L);
6969
appNotificationManager.showNotificationsFromJsArray(jsData);
7070
assertEquals(1, shadowNotificationManager.getAllNotifications().size());
7171
}
@@ -74,7 +74,7 @@ public void showsOnlyMaxAllowedNotifications() throws JSONException {
7474
public void showsNotificationsOnNewDay() throws JSONException {
7575
long taskDate = startOfDay;
7676
String jsData = "[" + getJSTaskNotificationString(taskDate, taskDate, taskDate + DAY_IN_MILLIS) + "]";
77-
assertEquals(0, appDataStore.getLongBlocking(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 0));
77+
assertEquals(0, appDataStore.getLongBlocking(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 0L));
7878
appNotificationManager.showNotificationsFromJsArray(jsData);
7979
assertEquals(2, shadowNotificationManager.getAllNotifications().size());
8080

@@ -84,7 +84,7 @@ public void showsNotificationsOnNewDay() throws JSONException {
8484

8585
appNotificationManager.showNotificationsFromJsArray(jsData);
8686
assertEquals(2, shadowNotificationManager.getAllNotifications().size());
87-
assertEquals(taskDate, appDataStore.getLongBlocking(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 0));
87+
assertEquals(taskDate, appDataStore.getLongBlocking(AppNotificationManager.LATEST_NOTIFICATION_TIMESTAMP_KEY, 0L));
8888
}
8989

9090
@Test

0 commit comments

Comments
 (0)