Skip to content

Commit eae3e45

Browse files
authored
Merge pull request #1334 from OneSignal/feat/set_language
Feature app-defined language implementation
2 parents 5c8a029 + 5b4d1a8 commit eae3e45

13 files changed

+215
-33
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationChannelManager.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import androidx.annotation.RequiresApi;
4141
import androidx.core.app.NotificationManagerCompat;
4242

43+
import com.onesignal.language.LanguageContext;
44+
4345
import org.json.JSONArray;
4446
import org.json.JSONException;
4547
import org.json.JSONObject;
@@ -116,9 +118,9 @@ private static String createChannel(Context context, NotificationManager notific
116118
JSONObject payloadWithText = channelPayload;
117119
if (channelPayload.has("langs")) {
118120
JSONObject langList = channelPayload.getJSONObject("langs");
119-
String deviceLanguage = OSUtils.getCorrectedLanguage();
120-
if (langList.has(deviceLanguage))
121-
payloadWithText = langList.optJSONObject(deviceLanguage);
121+
String language = LanguageContext.getInstance().getLanguage();
122+
if (langList.has(language))
123+
payloadWithText = langList.optJSONObject(language);
122124
}
123125

124126
String channel_name = payloadWithText.optString("nm", "Miscellaneous");

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import com.onesignal.OSDynamicTriggerController.OSDynamicTriggerControllerObserver;
1010
import com.onesignal.OneSignalRestClient.ResponseHandler;
11+
import com.onesignal.language.LanguageContext;
1112

1213
import org.json.JSONArray;
1314
import org.json.JSONException;
@@ -39,6 +40,7 @@ class OSInAppMessageController extends OSBackgroundManager implements OSDynamicT
3940

4041
private final OSLogger logger;
4142
private final OSTaskController taskController;
43+
private final LanguageContext languageContext;
4244

4345
private OSSystemConditionController systemConditionController;
4446
private OSInAppMessageRepository inAppMessageRepository;
@@ -87,7 +89,7 @@ class OSInAppMessageController extends OSBackgroundManager implements OSDynamicT
8789
Date lastTimeInAppDismissed = null;
8890
private int htmlNetworkRequestAttemptCount = 0;
8991

90-
protected OSInAppMessageController(OneSignalDbHelper dbHelper, OSTaskController controller, OSLogger logger) {
92+
protected OSInAppMessageController(OneSignalDbHelper dbHelper, OSTaskController controller, OSLogger logger, LanguageContext languageContext) {
9193
taskController = controller;
9294
messages = new ArrayList<>();
9395
dismissedMessages = OSUtils.newConcurrentSet();
@@ -97,6 +99,7 @@ protected OSInAppMessageController(OneSignalDbHelper dbHelper, OSTaskController
9799
clickedClickIds = OSUtils.newConcurrentSet();
98100
triggerController = new OSTriggerController(this);
99101
systemConditionController = new OSSystemConditionController(this);
102+
this.languageContext = languageContext;
100103
this.logger = logger;
101104

102105
Set<String> tempDismissedSet = OneSignalPrefs.getStringSet(
@@ -285,15 +288,15 @@ public void run() {
285288
}
286289

287290
private @Nullable String variantIdForMessage(@NonNull OSInAppMessage message) {
288-
String languageIdentifier = OSUtils.getCorrectedLanguage();
291+
String language = languageContext.getLanguage();
289292

290293
for (String variant : PREFERRED_VARIANT_ORDER) {
291294
if (!message.variants.containsKey(variant))
292295
continue;
293296

294297
HashMap<String, String> variantMap = message.variants.get(variant);
295-
if (variantMap.containsKey(languageIdentifier))
296-
return variantMap.get(languageIdentifier);
298+
if (variantMap.containsKey(language))
299+
return variantMap.get(language);
297300
return variantMap.get("default");
298301
}
299302

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageControllerFactory.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,23 @@
2929

3030
import android.os.Build;
3131

32+
import com.onesignal.language.LanguageContext;
33+
3234
class OSInAppMessageControllerFactory {
3335

3436
private static final Object LOCK = new Object();
3537

3638
private OSInAppMessageController controller;
3739

38-
public OSInAppMessageController getController(OneSignalDbHelper dbHelper, OSTaskController taskController, OSLogger logger) {
40+
public OSInAppMessageController getController(OneSignalDbHelper dbHelper, OSTaskController taskController, OSLogger logger, LanguageContext languageContext) {
3941
if (controller == null) {
4042
synchronized (LOCK) {
4143
if (controller == null) {
4244
// Make sure only Android 4.4 devices and higher can use IAMs
4345
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2)
44-
controller = new OSInAppMessageDummyController(null, taskController, logger);
46+
controller = new OSInAppMessageDummyController(null, taskController, logger, languageContext);
4547
else
46-
controller = new OSInAppMessageController(dbHelper, taskController, logger);
48+
controller = new OSInAppMessageController(dbHelper, taskController, logger, languageContext);
4749
}
4850
}
4951
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageDummyController.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import androidx.annotation.NonNull;
44
import androidx.annotation.Nullable;
55

6+
import com.onesignal.language.LanguageContext;
7+
68
import org.json.JSONArray;
79
import org.json.JSONException;
810
import org.json.JSONObject;
@@ -17,8 +19,8 @@ class OSInAppMessageDummyController extends OSInAppMessageController {
1719
* This is a dummy controller that will be used for Android 4.3 and older devices
1820
* All methods should be overridden and as empty as possible (few return exceptions)
1921
*/
20-
OSInAppMessageDummyController(OneSignalDbHelper dbHelper, OSTaskController taskController, OSLogger logger) {
21-
super(dbHelper, taskController, logger);
22+
OSInAppMessageDummyController(OneSignalDbHelper dbHelper, OSTaskController taskController, OSLogger logger, LanguageContext languageContext) {
23+
super(dbHelper, taskController, logger, languageContext);
2224
}
2325

2426
@Override

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSTaskRemoteController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class OSTaskRemoteController extends OSTaskController {
1313
static final String LOGOUT_EMAIL = "logoutEmail()";
1414
static final String SYNC_HASHED_EMAIL = "syncHashedEmail()";
1515
static final String SET_EXTERNAL_USER_ID = "setExternalUserId()";
16+
static final String SET_LANGUAGE = "setLanguage()";
1617
static final String SET_SUBSCRIPTION = "setSubscription()";
1718
static final String PROMPT_LOCATION = "promptLocation()";
1819
static final String IDS_AVAILABLE = "idsAvailable()";
@@ -39,6 +40,7 @@ class OSTaskRemoteController extends OSTaskController {
3940
LOGOUT_EMAIL,
4041
SYNC_HASHED_EMAIL,
4142
SET_EXTERNAL_USER_ID,
43+
SET_LANGUAGE,
4244
SET_SUBSCRIPTION,
4345
PROMPT_LOCATION,
4446
IDS_AVAILABLE,

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
import java.util.Collections;
6363
import java.util.HashSet;
6464
import java.util.Iterator;
65-
import java.util.Locale;
6665
import java.util.Set;
6766
import java.util.UUID;
6867
import java.util.concurrent.ConcurrentHashMap;
@@ -440,24 +439,6 @@ static String getResourceString(Context context, String key, String defaultStr)
440439
return defaultStr;
441440
}
442441

443-
static String getCorrectedLanguage() {
444-
String lang = Locale.getDefault().getLanguage();
445-
446-
// https://github.com/OneSignal/OneSignal-Android-SDK/issues/64
447-
if (lang.equals("iw"))
448-
return "he";
449-
if (lang.equals("in"))
450-
return "id";
451-
if (lang.equals("ji"))
452-
return "yi";
453-
454-
// https://github.com/OneSignal/OneSignal-Android-SDK/issues/98
455-
if (lang.equals("zh"))
456-
return lang + "-" + Locale.getDefault().getCountry();
457-
458-
return lang;
459-
}
460-
461442
static boolean isValidEmail(String email) {
462443
if (email == null)
463444
return false;

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747

4848
import com.onesignal.influence.data.OSTrackerFactory;
4949
import com.onesignal.influence.domain.OSInfluence;
50+
import com.onesignal.language.LanguageContext;
51+
import com.onesignal.language.LanguageProviderAppDefined;
5052
import com.onesignal.outcomes.data.OSOutcomeEventsFactory;
5153

5254
import org.json.JSONArray;
@@ -368,6 +370,8 @@ static Activity getCurrentActivity() {
368370
private static String smsId = null;
369371
private static int subscribableStatus = Integer.MAX_VALUE;
370372

373+
private static LanguageContext languageContext = null;
374+
371375
static OSRemoteNotificationReceivedHandler remoteNotificationReceivedHandler;
372376
static OSNotificationWillShowInForegroundHandler notificationWillShowInForegroundHandler;
373377
static OSNotificationOpenedHandler notificationOpenedHandler;
@@ -418,7 +422,7 @@ public void onSessionEnding(@NonNull List<OSInfluence> lastInfluences) {
418422

419423
private static OSInAppMessageControllerFactory inAppMessageControllerFactory = new OSInAppMessageControllerFactory();
420424
static OSInAppMessageController getInAppMessageController() {
421-
return inAppMessageControllerFactory.getController(getDBHelperInstance(), taskController, getLogger());
425+
return inAppMessageControllerFactory.getController(getDBHelperInstance(), taskController, getLogger(), languageContext);
422426
}
423427
private static OSTime time = new OSTimeImpl();
424428
private static OSRemoteParamController remoteParamController = new OSRemoteParamController();
@@ -823,6 +827,9 @@ private static void setupContextListeners(boolean wasAppContextNull) {
823827

824828
// Do work here that should only happen once or at the start of a new lifecycle
825829
if (wasAppContextNull) {
830+
// Set Language Context to null
831+
languageContext = new LanguageContext(preferences);
832+
826833
// Prefs require a context to save
827834
// If the previous state of appContext was null, kick off write in-case it was waiting
828835
OneSignalPrefs.startDelayedWrite();
@@ -1414,7 +1421,7 @@ private static void registerUserTask() throws JSONException {
14141421
deviceInfo.put("device_os", Build.VERSION.RELEASE);
14151422
deviceInfo.put("timezone", getTimeZoneOffset());
14161423
deviceInfo.put("timezone_id", getTimeZoneId());
1417-
deviceInfo.put("language", OSUtils.getCorrectedLanguage());
1424+
deviceInfo.put("language", languageContext.getLanguage());
14181425
deviceInfo.put("sdk", VERSION);
14191426
deviceInfo.put("sdk_type", sdkType);
14201427
deviceInfo.put("android_package", packageName);
@@ -1653,6 +1660,36 @@ public void run() {
16531660
OneSignalStateSynchronizer.logoutEmail();
16541661
}
16551662

1663+
public static void setLanguage(@NonNull final String language) {
1664+
if (taskRemoteController.shouldQueueTaskForInit(OSTaskRemoteController.SET_LANGUAGE)) {
1665+
logger.error("Waiting for remote params. " +
1666+
"Moving " + OSTaskRemoteController.SET_LANGUAGE + " operation to a pending task queue.");
1667+
taskRemoteController.addTaskToQueue(new Runnable() {
1668+
@Override
1669+
public void run() {
1670+
logger.debug("Running " + OSTaskRemoteController.SET_LANGUAGE + " operation from pending task queue.");
1671+
setLanguage(language);
1672+
}
1673+
});
1674+
return;
1675+
}
1676+
1677+
if (shouldLogUserPrivacyConsentErrorMessageForMethodName(OSTaskRemoteController.SET_LANGUAGE))
1678+
return;
1679+
1680+
LanguageProviderAppDefined languageProviderAppDefined = new LanguageProviderAppDefined(preferences);
1681+
languageProviderAppDefined.setLanguage(language);
1682+
languageContext.setStrategy(languageProviderAppDefined);
1683+
1684+
try {
1685+
JSONObject deviceInfo = new JSONObject();
1686+
deviceInfo.put("language", languageContext.getLanguage());
1687+
OneSignalStateSynchronizer.updateDeviceInfo(deviceInfo);
1688+
} catch (JSONException exception) {
1689+
exception.printStackTrace();
1690+
}
1691+
}
1692+
16561693
public static void setExternalUserId(@NonNull final String externalId) {
16571694
setExternalUserId(externalId, null, null);
16581695
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.onesignal.language;
2+
3+
import androidx.annotation.NonNull;
4+
5+
import com.onesignal.OSSharedPreferences;
6+
7+
import static com.onesignal.language.LanguageProviderAppDefined.PREFS_OS_LANGUAGE;
8+
9+
/*
10+
The Interface implements a getter and setter for the Language Provider.
11+
It defaults to the device defined Language unless a language override is set.
12+
*/
13+
public class LanguageContext {
14+
private LanguageProvider strategy;
15+
private static LanguageContext instance = null;
16+
17+
public static LanguageContext getInstance() {
18+
return instance;
19+
}
20+
21+
public LanguageContext(OSSharedPreferences preferences) {
22+
instance = this;
23+
String languageAppDefined = preferences.getString(preferences.getPreferencesName(), PREFS_OS_LANGUAGE, null);
24+
if (languageAppDefined != null) {
25+
this.strategy = new LanguageProviderAppDefined(preferences);
26+
}
27+
else {
28+
this.strategy = new LanguageProviderDevice();
29+
}
30+
}
31+
32+
public void setStrategy(LanguageProvider strategy) {
33+
this.strategy = strategy;
34+
}
35+
36+
@NonNull
37+
public String getLanguage() {
38+
return strategy.getLanguage();
39+
}
40+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.onesignal.language;
2+
3+
import androidx.annotation.NonNull;
4+
5+
public interface LanguageProvider {
6+
@NonNull
7+
String getLanguage();
8+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.onesignal.language;
2+
import androidx.annotation.NonNull;
3+
4+
import com.onesignal.OSSharedPreferences;
5+
6+
public class LanguageProviderAppDefined implements LanguageProvider {
7+
public static final String PREFS_OS_LANGUAGE = "PREFS_OS_LANGUAGE";
8+
9+
private static final String DEFAULT_LANGUAGE = "en";
10+
private final OSSharedPreferences preferences;
11+
12+
public LanguageProviderAppDefined(OSSharedPreferences preferences) {
13+
this.preferences = preferences;
14+
}
15+
16+
public void setLanguage(String language) {
17+
preferences.saveString(
18+
preferences.getPreferencesName(),
19+
PREFS_OS_LANGUAGE,
20+
language);
21+
}
22+
23+
@NonNull
24+
public String getLanguage() {
25+
return preferences.getString(
26+
preferences.getPreferencesName(), PREFS_OS_LANGUAGE, DEFAULT_LANGUAGE);
27+
}
28+
}

0 commit comments

Comments
 (0)