diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cecae197..49040a5e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -98,7 +98,13 @@ SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
-
+
+
+
+
+
+
+
diff --git a/app/src/main/java/helium314/keyboard/latin/AppsBinaryDictionary.java b/app/src/main/java/helium314/keyboard/latin/AppsBinaryDictionary.java
new file mode 100644
index 00000000..15b5079c
--- /dev/null
+++ b/app/src/main/java/helium314/keyboard/latin/AppsBinaryDictionary.java
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-3.0-only
+
+package helium314.keyboard.latin;
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import com.android.inputmethod.latin.BinaryDictionary;
+
+import java.io.File;
+import java.util.Locale;
+
+import helium314.keyboard.latin.common.StringUtils;
+import helium314.keyboard.latin.utils.Log;
+
+public class AppsBinaryDictionary extends ExpandableBinaryDictionary {
+ private static final String TAG = AppsBinaryDictionary.class.getSimpleName();
+ private static final String NAME = "apps";
+
+ private static final boolean DEBUG = false;
+ private static final boolean DEBUG_DUMP = false;
+
+ private final AppsManager mAppsManager;
+
+ protected AppsBinaryDictionary(final Context ctx, final Locale locale,
+ final File dictFile, final String name) {
+ super(ctx, getDictName(name, locale, dictFile), locale, Dictionary.TYPE_APPS, dictFile);
+ mAppsManager = new AppsManager(ctx);
+ reloadDictionaryIfRequired();
+ }
+
+ public static AppsBinaryDictionary getDictionary(final Context context, final Locale locale,
+ final File dictFile, final String dictNamePrefix, @Nullable final String account) {
+ return new AppsBinaryDictionary(context, locale, dictFile, dictNamePrefix + NAME);
+ }
+
+ /**
+ * Typically called whenever the dictionary is created for the first time or recreated when we
+ * think that there are updates to the dictionary. This is called asynchronously.
+ */
+ @Override
+ public void loadInitialContentsLocked() {
+ loadDictionaryLocked();
+ }
+
+ /**
+ * Loads app names to the dictionary.
+ */
+ private void loadDictionaryLocked() {
+ for (final String name : mAppsManager.getNames()) {
+ addNameLocked(name);
+ }
+ }
+
+ /**
+ * Adds the words in an app label to the binary dictionary along with their n-grams.
+ */
+ private void addNameLocked(final String appLabel) {
+ NgramContext ngramContext = NgramContext.getEmptyPrevWordsContext(
+ BinaryDictionary.MAX_PREV_WORD_COUNT_FOR_N_GRAM);
+ // TODO: Better tokenization for non-Latin writing systems
+ for (final String word : new LatinTokens(appLabel)) {
+ if (DEBUG_DUMP) {
+ Log.d(TAG, "addName word = " + word);
+ }
+ final int wordLen = StringUtils.codePointCount(word);
+ // Don't add single letter words, possibly confuses capitalization of i.
+ if (1 < wordLen && wordLen <= MAX_WORD_LENGTH) {
+ if (DEBUG) {
+ Log.d(TAG, "addName " + appLabel + ", " + word + ", " + ngramContext);
+ }
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addUnigramLocked(word, AppsDictionaryConstantsKt.FREQUENCY_FOR_APPS,
+ null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */,
+ false /* isPossiblyOffensive */,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ if (ngramContext.isValid()) {
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addNgramEntryLocked(ngramContext,
+ word,
+ AppsDictionaryConstantsKt.FREQUENCY_FOR_APPS_BIGRAM,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ }
+ ngramContext = ngramContext.getNextNgramContext(
+ new NgramContext.WordInfo(word));
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/helium314/keyboard/latin/AppsDictionaryConstants.kt b/app/src/main/java/helium314/keyboard/latin/AppsDictionaryConstants.kt
new file mode 100644
index 00000000..5c847a82
--- /dev/null
+++ b/app/src/main/java/helium314/keyboard/latin/AppsDictionaryConstants.kt
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-3.0-only
+
+package helium314.keyboard.latin
+
+/**
+ * Frequency for app names into the dictionary
+ */
+const val FREQUENCY_FOR_APPS: Int = 40
+const val FREQUENCY_FOR_APPS_BIGRAM: Int = 90
diff --git a/app/src/main/java/helium314/keyboard/latin/AppsManager.kt b/app/src/main/java/helium314/keyboard/latin/AppsManager.kt
new file mode 100644
index 00000000..3c918563
--- /dev/null
+++ b/app/src/main/java/helium314/keyboard/latin/AppsManager.kt
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-3.0-only
+
+package helium314.keyboard.latin
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import java.util.HashSet
+
+class AppsManager(context: Context) {
+ private val mPackageManager: PackageManager = context.packageManager
+
+ /**
+ * Returns all app labels associated with a launcher icon, sorted arbitrarily.
+ */
+ fun getNames(): HashSet {
+ val filter = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
+ // activities with an entry/icon for the launcher
+ val launcherApps: List = mPackageManager.queryIntentActivities(filter, 0)
+
+ val names = HashSet(launcherApps.size)
+ for (info in launcherApps) {
+ val name = info.activityInfo.loadLabel(mPackageManager).toString()
+ names.add(name)
+ }
+
+ return names
+ }
+}
diff --git a/app/src/main/java/helium314/keyboard/latin/Dictionary.java b/app/src/main/java/helium314/keyboard/latin/Dictionary.java
index 108fdf4f..88c52dbb 100644
--- a/app/src/main/java/helium314/keyboard/latin/Dictionary.java
+++ b/app/src/main/java/helium314/keyboard/latin/Dictionary.java
@@ -48,6 +48,7 @@ public abstract class Dictionary {
// phony dictionary instances for them.
public static final String TYPE_MAIN = "main";
public static final String TYPE_CONTACTS = "contacts";
+ public static final String TYPE_APPS = "apps";
// User dictionary, the system-managed one.
public static final String TYPE_USER = "user";
// User history dictionary internal to LatinIME.
@@ -173,6 +174,7 @@ public abstract class Dictionary {
case TYPE_USER_TYPED,
TYPE_USER,
TYPE_CONTACTS,
+ TYPE_APPS,
TYPE_USER_HISTORY -> true;
default -> false;
};
diff --git a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java
index 4d8ca5f6..783235a1 100644
--- a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java
+++ b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitator.java
@@ -32,11 +32,13 @@ public interface DictionaryFacilitator {
String[] ALL_DICTIONARY_TYPES = new String[] {
Dictionary.TYPE_MAIN,
Dictionary.TYPE_CONTACTS,
+ Dictionary.TYPE_APPS,
Dictionary.TYPE_USER_HISTORY,
Dictionary.TYPE_USER};
String[] DYNAMIC_DICTIONARY_TYPES = new String[] {
Dictionary.TYPE_CONTACTS,
+ Dictionary.TYPE_APPS,
Dictionary.TYPE_USER_HISTORY,
Dictionary.TYPE_USER};
@@ -87,6 +89,7 @@ public interface DictionaryFacilitator {
boolean usesSameSettings(
@NonNull final List locales,
final boolean contacts,
+ final boolean apps,
final boolean personalization,
@Nullable final String account
);
@@ -97,6 +100,7 @@ public interface DictionaryFacilitator {
final Context context,
final Locale newLocale,
final boolean useContactsDict,
+ final boolean useAppsDict,
final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
@Nullable final String account,
diff --git a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java
index e075b129..f1cb8a6f 100644
--- a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java
+++ b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorImpl.java
@@ -16,6 +16,23 @@ import android.view.inputmethod.InputMethodSubtype;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
import helium314.keyboard.keyboard.Keyboard;
import helium314.keyboard.latin.NgramContext.WordInfo;
import helium314.keyboard.latin.SuggestedWords.SuggestedWordInfo;
@@ -35,23 +52,6 @@ import helium314.keyboard.latin.utils.SubtypeSettings;
import helium314.keyboard.latin.utils.SubtypeUtilsKt;
import helium314.keyboard.latin.utils.SuggestionResults;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
/**
* Facilitates interaction with different kinds of dictionaries. Provides APIs
* to instantiate and select the correct dictionaries (based on language or account),
@@ -274,6 +274,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
return mDictionaryGroups.get(0).getSubDict(Dictionary.TYPE_CONTACTS) != null;
}
+ public boolean usesApps() {
+ return mDictionaryGroups.get(0).getSubDict(Dictionary.TYPE_APPS) != null;
+ }
+
public boolean usesPersonalization() {
return mDictionaryGroups.get(0).getSubDict(Dictionary.TYPE_USER_HISTORY) != null;
}
@@ -306,6 +310,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
case Dictionary.TYPE_USER_HISTORY -> UserHistoryDictionary.getDictionary(context, locale, dictFile, dictNamePrefix, account);
case Dictionary.TYPE_USER -> UserBinaryDictionary.getDictionary(context, locale, dictFile, dictNamePrefix, account);
case Dictionary.TYPE_CONTACTS -> ContactsBinaryDictionary.getDictionary(context, locale, dictFile, dictNamePrefix, account);
+ case Dictionary.TYPE_APPS -> AppsBinaryDictionary.getDictionary(context, locale, dictFile, dictNamePrefix, account);
default -> null;
};
} catch (final SecurityException | IllegalArgumentException e) {
@@ -332,6 +337,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
final Context context,
@NonNull final Locale newLocale,
final boolean useContactsDict,
+ final boolean useAppsDict,
final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
@Nullable final String account,
@@ -364,6 +370,9 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
&& PermissionsUtil.checkAllPermissionsGranted(context, Manifest.permission.READ_CONTACTS)) {
subDictTypesToUse.add(Dictionary.TYPE_CONTACTS);
}
+ if (useAppsDict) {
+ subDictTypesToUse.add(Dictionary.TYPE_APPS);
+ }
if (usePersonalizedDicts) {
subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY);
}
@@ -958,6 +967,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
if (historyDict != null) {
historyDict.removeUnigramEntryDynamically(word);
}
+
// and from personal dictionary
final ExpandableBinaryDictionary userDict = group.getSubDict(Dictionary.TYPE_USER);
if (userDict != null) {
@@ -965,19 +975,28 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
}
final ExpandableBinaryDictionary contactsDict = group.getSubDict(Dictionary.TYPE_CONTACTS);
- if (contactsDict != null) {
- if (contactsDict.isInDictionary(word)) {
- contactsDict.removeUnigramEntryDynamically(word); // will be gone until next reload of dict
- addToBlacklist(word, group);
- return;
- }
- }
- if (!group.hasDict(Dictionary.TYPE_MAIN, null))
+ if (contactsDict != null && contactsDict.isInDictionary(word)) {
+ contactsDict.removeUnigramEntryDynamically(word); // will be gone until next reload of dict
+ addToBlacklist(word, group);
return;
+ }
+
+ final ExpandableBinaryDictionary appsDict = group.getSubDict(Dictionary.TYPE_APPS);
+ if (appsDict != null && appsDict.isInDictionary(word)) {
+ appsDict.removeUnigramEntryDynamically(word); // will be gone until next reload of dict
+ addToBlacklist(word, group);
+ return;
+ }
+
+ if (!group.hasDict(Dictionary.TYPE_MAIN, null)) {
+ return;
+ }
+
if (group.getDict(Dictionary.TYPE_MAIN).isValidWord(word)) {
addToBlacklist(word, group);
return;
}
+
final String lowercase = word.toLowerCase(group.mLocale);
if (group.getDict(Dictionary.TYPE_MAIN).isValidWord(lowercase)) {
addToBlacklist(lowercase, group);
diff --git a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorLruCache.java b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorLruCache.java
index 08096413..28cd88c5 100644
--- a/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorLruCache.java
+++ b/app/src/main/java/helium314/keyboard/latin/DictionaryFacilitatorLruCache.java
@@ -26,6 +26,7 @@ public class DictionaryFacilitatorLruCache {
private final Object mLock = new Object();
private final DictionaryFacilitator mDictionaryFacilitator;
private boolean mUseContactsDictionary;
+ private boolean mUseAppsDictionary;
private Locale mLocale;
public DictionaryFacilitatorLruCache(final Context context, final String dictionaryNamePrefix) {
@@ -59,7 +60,7 @@ public class DictionaryFacilitatorLruCache {
if (mLocale != null) {
// Note: Given that personalized dictionaries are not used here; we can pass null account.
mDictionaryFacilitator.resetDictionaries(mContext, mLocale,
- mUseContactsDictionary, false /* usePersonalizedDicts */,
+ mUseContactsDictionary, mUseAppsDictionary, false /* usePersonalizedDicts */,
false /* forceReloadMainDictionary */, null /* account */,
mDictionaryNamePrefix, null /* listener */);
}
@@ -77,6 +78,18 @@ public class DictionaryFacilitatorLruCache {
}
}
+ public void setUseAppsDictionary(final boolean useAppsDictionary) {
+ synchronized (mLock) {
+ if (mUseAppsDictionary == useAppsDictionary) {
+ // The value has not been changed.
+ return;
+ }
+ mUseAppsDictionary = useAppsDictionary;
+ resetDictionariesForLocaleLocked();
+ waitForLoadingMainDictionary(mDictionaryFacilitator);
+ }
+ }
+
public DictionaryFacilitator get(final Locale locale) {
synchronized (mLock) {
if (!mDictionaryFacilitator.isForLocale(locale)) {
diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java
index d2e75a45..d9326b18 100644
--- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java
+++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java
@@ -668,6 +668,7 @@ public class LatinIME extends InputMethodService implements
if (mDictionaryFacilitator.usesSameSettings(
locales,
mSettings.getCurrent().mUseContactsDictionary,
+ mSettings.getCurrent().mUseAppsDictionary,
mSettings.getCurrent().mUsePersonalizedDicts,
mSettings.getCurrent().mAccount
)) {
@@ -686,8 +687,8 @@ public class LatinIME extends InputMethodService implements
private void resetDictionaryFacilitator(@NonNull final Locale locale) {
final SettingsValues settingsValues = mSettings.getCurrent();
mDictionaryFacilitator.resetDictionaries(this, locale,
- settingsValues.mUseContactsDictionary, settingsValues.mUsePersonalizedDicts,
- false, settingsValues.mAccount, "", this);
+ settingsValues.mUseContactsDictionary, settingsValues.mUseAppsDictionary,
+ settingsValues.mUsePersonalizedDicts, false, settingsValues.mAccount, "", this);
mInputLogic.mSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
}
@@ -698,7 +699,7 @@ public class LatinIME extends InputMethodService implements
final SettingsValues settingsValues = mSettings.getCurrent();
mDictionaryFacilitator.resetDictionaries(this /* context */,
mDictionaryFacilitator.getMainLocale(), settingsValues.mUseContactsDictionary,
- settingsValues.mUsePersonalizedDicts,
+ settingsValues.mUseAppsDictionary, settingsValues.mUsePersonalizedDicts,
true /* forceReloadMainDictionary */,
settingsValues.mAccount, "" /* dictNamePrefix */,
this /* DictionaryInitializationListener */);
diff --git a/app/src/main/java/helium314/keyboard/latin/LatinTokens.kt b/app/src/main/java/helium314/keyboard/latin/LatinTokens.kt
new file mode 100644
index 00000000..2c80e584
--- /dev/null
+++ b/app/src/main/java/helium314/keyboard/latin/LatinTokens.kt
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-3.0-only
+
+package helium314.keyboard.latin
+
+/**
+ * Tokenizes strings by groupings of non-space characters, making them iterable. Note that letters,
+ * punctuations, etc. are all treated the same by this construct.
+ */
+class LatinTokens(phrase: String) : Iterable {
+ private val mPhrase = phrase
+ private val mLength = phrase.length
+ private val mStartPos = phrase.indexOfFirst { !Character.isWhitespace(it) }
+ // the iterator should start at the first non-whitespace character
+
+ override fun iterator() = object : Iterator {
+ private var startPos = mStartPos
+
+ override fun hasNext(): Boolean {
+ return startPos < mLength
+ }
+
+ override fun next(): String {
+ var endPos = startPos
+
+ do if (++endPos >= mLength) break
+ while (!Character.isWhitespace(mPhrase[endPos]))
+ val word = mPhrase.substring(startPos, endPos)
+
+ if (endPos < mLength) {
+ do if (++endPos >= mLength) break
+ while (Character.isWhitespace(mPhrase[endPos]))
+ }
+ startPos = endPos
+
+ return word
+ }
+ }
+}
diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt
index 0301409b..c133584a 100644
--- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt
+++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt
@@ -110,6 +110,7 @@ object Defaults {
const val PREF_GESTURE_TRAIL_FADEOUT_DURATION = 800
const val PREF_SHOW_SETUP_WIZARD_ICON = true
const val PREF_USE_CONTACTS = false
+ const val PREF_USE_APPS = false
const val PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD = false
const val PREF_ONE_HANDED_MODE = false
@SuppressLint("RtlHardcoded")
diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java
index 89e93e8d..3b77b820 100644
--- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java
+++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java
@@ -114,6 +114,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_GESTURE_TRAIL_FADEOUT_DURATION = "gesture_trail_fadeout_duration";
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "show_setup_wizard_icon";
public static final String PREF_USE_CONTACTS = "use_contacts";
+ public static final String PREF_USE_APPS = "use_apps";
public static final String PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD = "long_press_symbols_for_numpad";
// one-handed mode gravity, enablement and scale, stored separately per orientation
diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java
index 8576bc1d..911ecf0a 100644
--- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java
+++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java
@@ -103,6 +103,7 @@ public class SettingsValues {
public final int mScreenMetrics;
public final boolean mAddToPersonalDictionary;
public final boolean mUseContactsDictionary;
+ public final boolean mUseAppsDictionary;
public final boolean mCustomNavBarColor;
public final float mKeyboardHeightScale;
public final boolean mUrlDetectionEnabled;
@@ -251,6 +252,7 @@ public class SettingsValues {
mPopupKeyLabelSources = SubtypeUtilsKt.getPopupKeyLabelSources(selectedSubtype, prefs);
mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, Defaults.PREF_ADD_TO_PERSONAL_DICTIONARY);
mUseContactsDictionary = SettingsValues.readUseContactsEnabled(prefs, context);
+ mUseAppsDictionary = prefs.getBoolean(Settings.PREF_USE_APPS, Defaults.PREF_USE_APPS);
mCustomNavBarColor = prefs.getBoolean(Settings.PREF_NAVBAR_COLOR, Defaults.PREF_NAVBAR_COLOR);
mNarrowKeyGaps = prefs.getBoolean(Settings.PREF_NARROW_KEY_GAPS, Defaults.PREF_NARROW_KEY_GAPS);
mSettingsValuesForSuggestion = new SettingsValuesForSuggestion(
@@ -334,11 +336,12 @@ public class SettingsValues {
return mDisplayOrientation == configuration.orientation;
}
- private static boolean readUseContactsEnabled(final SharedPreferences prefs, final Context context) {
+ private static boolean readUseContactsEnabled(final SharedPreferences prefs, final Context ctx) {
final boolean setting = prefs.getBoolean(Settings.PREF_USE_CONTACTS, Defaults.PREF_USE_CONTACTS);
if (!setting) return false;
- if (PermissionsUtil.checkAllPermissionsGranted(context, Manifest.permission.READ_CONTACTS))
+ if (PermissionsUtil.checkAllPermissionsGranted(ctx, Manifest.permission.READ_CONTACTS)) {
return true;
+ }
// disable if permission not granted
prefs.edit().putBoolean(Settings.PREF_USE_CONTACTS, false).apply();
return false;
diff --git a/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java b/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java
index 80756179..73d66ad3 100644
--- a/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/app/src/main/java/helium314/keyboard/latin/spellcheck/AndroidSpellCheckerService.java
@@ -83,6 +83,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
final SharedPreferences prefs = KtxKt.prefs(this);
prefs.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(prefs, Settings.PREF_USE_CONTACTS);
+ onSharedPreferenceChanged(prefs, Settings.PREF_USE_APPS);
final boolean blockOffensive = prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, Defaults.PREF_BLOCK_POTENTIALLY_OFFENSIVE);
mSettingsValuesForSuggestion = new SettingsValuesForSuggestion(blockOffensive, false);
}
@@ -93,13 +94,19 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
@Override
public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
- if (Settings.PREF_USE_CONTACTS.equals(key)) {
+ if (key != null) switch (key) {
+ case Settings.PREF_USE_CONTACTS -> {
final boolean useContactsDictionary = prefs.getBoolean(Settings.PREF_USE_CONTACTS, Defaults.PREF_USE_CONTACTS);
mDictionaryFacilitatorCache.setUseContactsDictionary(useContactsDictionary);
- } else if (Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE.equals(key)) {
+ }
+ case Settings.PREF_USE_APPS -> {
+ final boolean useAppsDictionary = prefs.getBoolean(Settings.PREF_USE_APPS, Defaults.PREF_USE_APPS);
+ mDictionaryFacilitatorCache.setUseAppsDictionary(useAppsDictionary);
+ }
+ case Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE -> {
final boolean blockOffensive = prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, Defaults.PREF_BLOCK_POTENTIALLY_OFFENSIVE);
mSettingsValuesForSuggestion = new SettingsValuesForSuggestion(blockOffensive, false);
- }
+ }}
}
@Override
diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt b/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt
index 498b7293..387eb3bb 100644
--- a/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt
+++ b/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt
@@ -99,6 +99,7 @@ class SettingsActivity : ComponentActivity(), SharedPreferences.OnSharedPreferen
if (spellchecker)
Column { // lazy way of implementing spell checker settings
settingsContainer[Settings.PREF_USE_CONTACTS]!!.Preference()
+ settingsContainer[Settings.PREF_USE_APPS]!!.Preference()
settingsContainer[Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE]!!.Preference()
}
else
diff --git a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt
index 97d64188..3d726cbe 100644
--- a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt
+++ b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt
@@ -68,6 +68,7 @@ fun TextCorrectionScreen(
Settings.PREF_BIGRAM_PREDICTIONS,
Settings.PREF_SUGGEST_CLIPBOARD_CONTENT,
Settings.PREF_USE_CONTACTS,
+ Settings.PREF_USE_APPS,
if (prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, Defaults.PREF_KEY_USE_PERSONALIZED_DICTS))
Settings.PREF_ADD_TO_PERSONAL_DICTIONARY else null
)
@@ -195,6 +196,11 @@ fun createCorrectionSettings(context: Context) = listOf(
}
)
},
+ Setting(context, Settings.PREF_USE_APPS,
+ R.string.use_apps_dict, R.string.use_apps_dict_summary
+ ) { setting ->
+ SwitchPreference(setting, Defaults.PREF_USE_APPS)
+ },
Setting(context, Settings.PREF_ADD_TO_PERSONAL_DICTIONARY,
R.string.add_to_personal_dictionary, R.string.add_to_personal_dictionary_summary
) {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 903b3cbd..425a70b6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -76,6 +76,10 @@
Look up contact names
Use names from Contacts for suggestions and corrections
+
+ Look up app names
+
+ Use names of installed apps for suggestions and corrections
Personalized suggestions