Please read this migration guide if your product is derived from AOSP’s built-in keyboard.
Zengine SDK depends on AndroidX. If you are not yet migrated to AndroidX, please do the following in Android Studio:
- Android Studio → Refactor → Migrate to AndroidX
- Press “Do Refactor” in “Refactoring Preview” panel
Or reference the official document::here
Zengine SDK supports API Level 19 (Android 4.4) or above, plus Java 1.8.Zengine SDK supports armeabi-v7a, arm64-v8a, x86 and x86_64. Specifies the ABI configurations of your native libraries in build.gradle(app).
Make sure relevant options are added to build.gradle:
app/build.gradle:
… … … …
android {
… … … … ...
defaultConfig {
… … … … …
minSdkVersion 19
multiDexEnabled true
… … … …
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'armeabi-v7a', 'arm64-v8a'/*, 'x86', 'x86_64'*/
}
}
… … … …
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
… … … …
Add our Maven repo in build.gradle like below:
build.gradle:
allprojects {
repositories {
… … … … …
maven { url 'https://repo.nlpte.ch/repository/maven-releases/' }
… … … … …
}
}
Add dependencies: build.gradle:
dependencies {
… … … … …
implementation 'com.nlptech.zengine:keyboardkernel:1.3.14'
… … … … …
}
Add Zengine appkey into AndroidManifest.xml:
AndroidManifest.xml:
… … … … …
<application
… … … … …
<meta-data
android:name="nlptech_appkey"
android:value="{appkey_value}" />
… … … … …
</application>
If you do not have your own appkey, get it here. If you have difficulty in getting the appkey, please contact [email protected].
Please modify the content in method.xml as follows (remove all subtypes): method.xml:
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:isDefault="false"
android:supportsSwitchingToNextInputMethod="false">
</input-method>
You can remove duplicated Java sources and resources by bundled zengineScript.jar. It scans the source tree and try to remove duplicated ones, and patching import statements automatically.
If the tool detected that the file is modified by you (compared to vanilla AOSP), a message will be printed and no file is deleted. Please manually review those files.
java -jar zengineScript.jar <your project folder>
// e.g : java -jar zengineScript.jar /MyApp
If the tool does not work well for you, please see FAQ to manually do the cleanup
Remove unneeded JNI library: libjni_latinime.so
Remove pinyin so : libejni_pinyinime.so [zengine v1.2]
We suggest turn on Auto Import on the fly: Android Studio → Editor → General → Auto Import → Java
LatinIME.java:
// Please extends ZengineInputMethodService
public class LatinIME extends ZengineInputMethodService implements
KeyboardActionListener,....{
… … … … …
// KeyboardSwitcher-->IKeyboardSwitcher
@UsedForTesting final IKeyboardSwitcher mKeyboardSwitcher;
… … … … …
public final UIHandler mHandler = new UIHandler(this);
// Move creation of InputLogic after creating UIHandler
// and modify signature of InputLogic constructor
final InputLogic mInputLogic = new InputLogic(this,mHandler,KeyboardSwitcher.getInstance(),mDictionaryFacilitator);
… … … … …
@Override
public void onCreate() {
… … … … …
// add arguments of KeyboardSwitcher.init()
KeyboardSwitcher.init(this, this, this);
… … … … …
// Remove second argument
mStatsUtilsManager.onCreate(this);
… … … … …
// No argument here
StatsUtils.onCreate();
… … … …
}
private boolean isImeSuppressedByHardwareKeyboard() {
// KeyboardSwitcher -> IKeyboardSwitcher
final IKeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
… … … …
}
// modify LatinIME.shouldShowLanguageSwitchKey() as below
@Override
public boolean shouldShowLanguageSwitchKey() {
return mRichImm.hasMultipleEnabledIMEsOrSubtypes(false);
}
… … … … …
@Override
void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {
… … … … …
mRichImm.refreshSubtypeCaches();
final IKeyboardSwitcher switcher = mKeyboardSwitcher;
switcher.updateKeyboardTheme(false);
switcher.updateKeyboardAdditionalNumberRow();
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
… … … … …
// Please call KeyboardSwitcher.requestUpdatingKeyboardToFirstPage()
KeyboardSwitcher.getInstance().requestUpdatingKeyboardToFirstPage();
// Please call KeyboardSwitcher.requestUpdatingDeformableKeyState()
KeyboardSwitcher.getInstance()
.requestUpdatingDeformableKeyState(mInputLogic.getTextBeforeCursor(Constants.DEFORMABLE_KEY_CHECK_TEXT_COUNT_BEFORE_CURSOR));
… … … … …
}
… … … … …
void resetSuggestMainDict() {
final SettingsValues settingsValues = mSettings.getCurrent();
// Arguments of mDictionaryFacilitator.resetDictionaries() are changed
mDictionaryFacilitator.resetDictionaries(this /* context */,
mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict,
settingsValues.mUsePersonalizedDicts,
true /* forceReloadMainDictionary */,
settingsValues.mAccount, "" /* dictNamePrefix */,
this /* DictionaryInitializationListener */,
Agent.getInstance().obtainDictionaryGetter());
}
… … … … …
private void resetDictionaryFacilitator(final Locale locale) {
… … … … …
// Arguments of mDictionaryFacilitator.resetDictionaries() are changed
mDictionaryFacilitator.resetDictionaries(this /* context */, locale,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */,
settingsValues.mAccount, "" /* dictNamePrefix */,
this /* DictionaryInitializationListener */,
Agent.getInstance().obtainDictionaryGetter());
… … … … …
}
… … … … …
void replaceDictionariesForTest(final Locale locale) {
… … … … …
// Arguments of mDictionaryFacilitator.resetDictionaries() are changed
mDictionaryFacilitator.resetDictionaries(this, locale,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */,
settingsValues.mAccount, "", /* dictionaryNamePrefix */
this /* DictionaryInitializationListener */,
Agent.getInstance().obtainDictionaryGetter());
… … … … …
}
… … … … …
// In Settings.loadSettings(),add Zengine's InputLogic as last argument
void loadSettings() {
… … … … …
mSettings.loadSettings(this, locale, inputAttributes, mInputLogic);
}
… … … … …
public void getSuggestedWords(final int inputStyle, final int sequenceNumber,...)
… … … … …
// remove argument keyboard
mInputLogic.getSuggestedWords(mSettings.getCurrent(),mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback);
… … … … …
}
… … … … …
// change updateStateAfterInputTransaction to public
public void updateStateAfterInputTransaction(final InputTransaction inputTransaction) {
… … … … …
// Please call KeyboardSwitcher.requestUpdatingKeyboardToFirstPage()
if (inputTransaction.mEvent.mKeyCode != CODE_SWITCH_TO_NEXT_ALPHABET_PAGE) {
KeyboardSwitcher.getInstance().requestUpdatingKeyboardToFirstPage();
}
// Please call KeyboardSwitcher.requestUpdatingDeformableKeyState()
KeyboardSwitcher.getInstance()
.requestUpdatingDeformableKeyState(mInputLogic.getTextBeforeCursor(Constants.DEFORMABLE_KEY_CHECK_TEXT_COUNT_BEFORE_CURSOR));
if (inputTransaction.requiresUpdateSuggestions()) {
… … … … …
}
[zengine v1.2]
// Add code down below,
else {
setNeutralSuggestionStrip();
}
}
LatinIME$UIHandler.java:
public class LatinIME extends ZengineInputMethodService{
… … … … …
//UIHandler implements ImeUiHandlerInterface
public static final class UIHandler extends LeakGuardHandlerWrapper<LatinIME>
implements ImeUiHandlerInterface {
… … … … …
// Functions in ImeUiHandlerInterface work the same in LatinIME.UIHandler
… … … … …
@Override
public void handleMessage(final Message msg) {
… … … … …
// KeyboardSwitcher-->IKeyboardSwitcher
final IKeyboardSwitcher switcher = latinIme.mKeyboardSwitcher;
… … … … …
}
}
}
AndroidSpellCheckerService.java:
public class AndroidSpellCheckerService extends SpellCheckerService... {
… … … … …
public SuggestionResults getSuggestionResults(final Locale locale, final ComposedData composedData, final NgramContext ngramContext,
@Nonnull final Keyboard keyboard) {
… … … …
try {
… … … …
// Please change the third parameter in getSuggestionResults
return dictionaryFacilitatorForLocale.getSuggestionResults(composedData
,ngramContext,keyboard.getProximityInfo().getNativeProximityInfo(), …)
}
… … … … …
}
}
DictionaryFacilitatorLruCache.java:
… … … … …
private void resetDictionariesForLocaleLocked() {
… … … … …
//Please add last parameter in Agent.getInstance().obtainDictionaryGetter()
mDictionaryFacilitator.resetDictionaries(mContext, mLocale,
mUseContactsDictionary, false /* usePersonalizedDicts */,
false /* forceReloadMainDictionary */, null /* account */,
mDictionaryNamePrefix, null /* listener */,
Agent.getInstance().obtainDictionaryGetter());
}
… … … … …
EmojiAltPhysicalKeyDetector.java:
… … … … …
final EmojiHotKeys emojiHotKeys = new EmojiHotKeys("emoji", emojiSwitchSet) {
@Override
protected void action() {
//KeyboardSwitcher --> IKeyboardSwitcher
final IKeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
… … … …
}
};
… … … … …
final EmojiHotKeys symbolsHotKeys = new EmojiHotKeys("symbols", symbolsSwitchSet) {
@Override
protected void action() {
//KeyboardSwitcher --> IKeyboardSwitcher
final IKeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
… … … …
}
};
… … … … …
ThemeSettingsFragment.java:
public class ThemeSettingsFragment extends SubScreenFragment implements OnRadioButtonClickedListener {
… … … …
static void updateKeyboardThemeSummary(final Preference pref) {
… … … … …
// Use KeyboardThemeManager's getLastUsedKeyboardTheme instead
final KeyboardTheme keyboardTheme = KeyboardThemeManager.getInstance().getLastUsedKeyboardTheme(context);
}
@Override public void onCreate(final Bundle icicle) {
… … … … …
// Use KeyboardThemeManager's getLastUsedKeyboardTheme instead
final KeyboardTheme keyboardTheme = KeyboardThemeManager.getInstance().getLastUsedKeyboardTheme(context);
}
… … … …
@Override
public void onPause() {
super.onPause();
// Use KeyboardThemeManager's saveLastUsedKeyboardThemeId instead
KeyboardThemeManager.getInstance().saveLastUsedKeyboardThemeId(mSelectedThemeId, getSharedPreferences());
}
… … … …
LatinIME.java:
public class LatinIME extends ZengineInputMethodService implements
// Delete interface:SuggestionStripView.Listener and SuggestionStripViewAccessor
...., S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶.̶L̶i̶s̶t̶e̶n̶e̶r̶,̶ ̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶A̶c̶c̶e̶s̶s̶o̶r̶ {
… … … …
// Delete mSuggestionStripView
p̶r̶i̶v̶a̶t̶e̶ ̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶ ̶m̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶;̶
… … … …
public void setInputView(final View view) {
m̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶ ̶=̶ ̶(̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶)̶v̶i̶e̶w̶.̶f̶i̶n̶d̶V̶i̶e̶w̶B̶y̶I̶d̶(̶R̶.̶i̶d̶.̶s̶u̶g̶g̶e̶s̶t̶i̶o̶n̶_̶s̶t̶r̶i̶p̶_̶v̶i̶e̶w̶)̶;̶
}
… … … …
public void onComputeInsets(final Insets outInsets) {
m̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶.̶s̶e̶t̶M̶o̶r̶e̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶s̶H̶e̶i̶g̶h̶t̶(̶v̶i̶s̶i̶b̶l̶e̶T̶o̶p̶Y̶)̶;̶
}
… … … …
// Delete function down below : hasSuggestionStripView(),setNeutralSuggestionStrip(),
// showSuggestionStrip(), setSuggestedWords(), showImportantNoticeContents()
p̶u̶b̶l̶i̶c̶ ̶b̶o̶o̶l̶e̶a̶n̶ ̶h̶a̶s̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶(̶)̶
p̶r̶i̶v̶a̶t̶e̶ ̶v̶o̶i̶d̶ ̶s̶e̶t̶S̶u̶g̶g̶e̶s̶t̶e̶d̶W̶o̶r̶d̶s̶(̶f̶i̶n̶a̶l̶ ̶S̶u̶g̶g̶e̶s̶t̶e̶d̶W̶o̶r̶d̶s̶ ̶s̶u̶g̶g̶e̶s̶t̶e̶d̶W̶o̶r̶d̶s̶)̶
p̶u̶b̶l̶i̶c̶ ̶v̶o̶i̶d̶ ̶s̶h̶o̶w̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶(̶f̶i̶n̶a̶l̶ ̶S̶u̶g̶g̶e̶s̶t̶e̶d̶W̶o̶r̶d̶s̶ ̶s̶u̶g̶g̶e̶s̶t̶e̶d̶W̶o̶r̶d̶s̶)̶
p̶u̶b̶l̶i̶c̶ ̶v̶o̶i̶d̶ ̶s̶e̶t̶N̶e̶u̶t̶r̶a̶l̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶(̶)̶
p̶u̶b̶l̶i̶c̶ ̶v̶o̶i̶d̶ ̶s̶h̶o̶w̶I̶m̶p̶o̶r̶t̶a̶n̶t̶N̶o̶t̶i̶c̶e̶C̶o̶n̶t̶e̶n̶t̶s̶(̶)̶
… … … …
// Delete ImportantNoticeUtils
public void onRequestPermissionsResult(boolean allGranted) {
I̶m̶p̶o̶r̶t̶a̶n̶t̶N̶o̶t̶i̶c̶e̶U̶t̶i̶l̶s̶.̶u̶p̶d̶a̶t̶e̶C̶o̶n̶t̶a̶c̶t̶s̶N̶o̶t̶i̶c̶e̶S̶h̶o̶w̶n̶(̶t̶h̶i̶s̶ ̶/̶*̶ ̶c̶o̶n̶t̶e̶x̶t̶ ̶*̶/̶)̶;̶
}
input_view.xml:
// Delete SuggestionStripView
<̶c̶o̶m̶.̶a̶n̶d̶r̶o̶i̶d̶.̶i̶n̶p̶u̶t̶m̶e̶t̶h̶o̶d̶.̶l̶a̶t̶i̶n̶.̶s̶u̶g̶g̶e̶s̶t̶i̶o̶n̶s̶.̶S̶u̶g̶g̶e̶s̶t̶i̶o̶n̶S̶t̶r̶i̶p̶V̶i̶e̶w̶
Initialize agent in Application.onCreate().
ExampleApplication.java:
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Agent.getInstance().init(this);
}
… … … …
Need to call lifecycle in LatinIME
For example:
LatinIME.java:
… … … …
public class LatinIME extends ZengineInputMethodService implements
KeyboardActionListener,...{
… … … … …
public void onCreate() {
DebugFlags.init(PreferenceManager.getDefaultSharedPreferences(this));
RichInputMethodManager.init(this);
mRichImm = RichInputMethodManager.getInstance();
Agent.getInstance().onCreate(this, mInputLogic, new LanguageCallback(){
@Override
public void onIMELanguageChanged(InputMethodSubtype subtype) {
onCurrentInputMethodSubtypeChanged(subtype);
}
});
// Set callback to detect keyboard switch
Agent.getInstance().
setKeyboardActionCallback(new IKeyboardActionCallback() {
@Override
// Returns true if you want to use Emoji keyboard provided by Zengine, false otherwise
public boolean onDisplayEmojiKeyboard() {
// Show your own Emoji Keyboard if needed
return false;
}
@Override
public void onKeyboardTypeChange(int keyboardType) {
switch (keyboardType){
case IKeyboardActionCallback.ALPHA_KEYBOARD:
break;
case IKeyboardActionCallback.EMOJI_KEYBOARD:
break;
case IKeyboardActionCallback.SYMBOL_KEYBOARD:
break;
}
});
… … … … …
}
[zengine v1.2]
@Override
public void onStartInput(final EditorInfo editorInfo, final boolean restarting) {
// Please call super.onStartInput(editorInfo, restarting)
super.onStartInput(editorInfo, restarting);
… … … …
}
@Override
public void onStartInputView(final EditorInfo editorInfo, final boolean restarting) {
// Please call super.onStartInputView(editorInfo,restarting)
super.onStartInputView(editorInfo,restarting);
… … … …
}
[zengine v1.2]
@Override
public void onFinishInput() {
// Please call super.onFinishInput()
super.onFinishInput();
… … … …
}
@Override
public void onFinishInputView(final boolean finishingInput) {
// Please call super.onFinishInputView(finishingInput)
super.onFinishInputView(finishingInput);
… … … …
}
@Override
public void onUpdateSelection(final int oldSelStart, final int oldSelEnd,
final int newSelStart, final int newSelEnd,
final int composingSpanStart, final int composingSpanEnd) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
composingSpanStart, composingSpanEnd);
… … … …
// Add code down below
if (isInputViewShown()
&& mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd,
newSelStart, newSelEnd, settingsValues)) {
// Please call KeyboardSwitcher.requestUpdatingShiftState()
KeyboardSwitcher.getInstance()
.requestUpdatingShiftState(getCurrentAutoCapsState(),
getCurrentRecapitalizeState());
// Please call KeyboardSwitcher.requestUpdatingDeformableKeyState()
KeyboardSwitcher.getInstance()
.requestUpdatingDeformableKeyState(mInputLogic.getTextBeforeCursor(Constants.DEFORMABLE_KEY_CHECK_TEXT_COUNT_BEFORE_CURSOR));
}
… … … …
}
Developer only needs to call:
Agent.getInstance().onCreateInputView(ViewGroup container, boolean enable)
in InputMethodService.onCreateInputView(), where container stands for parent view of the KeyboardView. SDK will automatically create KeyboardView and EmojiView, and add them into ViewGroup.
LatinIME.java:
@Override
public View onCreateInputView() {
// XML layout of your project
View currentInputView =
LayoutInflater.from(this).inflate(R.layout.example_input_view, null);
// There is a container...
ViewGroup kbContainer = currentInputView.findViewById(R.id.kb_container);
// Call Agent.getInstance().onCreateInputView() with the container
Agent.getInstance().onCreateInputView(kbContainer, mIsHardwareAcceleratedDrawingEnabled);
// return the View
return currentInputView;
}
Layour example:
example_input_view.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/inputViewStyle">
… … … …
<!-- container for KeybaordView & EmojiView -->
<FrameLayout
android:id="@+id/kb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
… … … …
</RelativeLayout>
Through Agent.getInstance().getAvailableIMELanguageList() one can get supported language list of Zengine. Use Agent.getInstance().addIMELanguage() and Agent.getInstance().removeIMELanguage() to add/remove enabled languages, and use Agent.getInstance().getAddedIMELanguageList() to get a list of enabled languages. Only dictionaries of enabled languages are downloaded.
Initiate dictionary download through calling Agent.getInstance().downloadDictionary(). Downloading progress can be observed by registering a listener through Agent.getInstance().registerDictionaryDownloadListener(). By default, downloading is enabled even on cellular network, if you want to turn this off, please call Agent.getInstance().enableMobileDictionaryDownload(false). dictionaries downloading will be activated under these circumstances:First, add keyboard. Second, add/delete one language. Third, there is an eight-hour gap or above between the time keyboard was downloaded last time and this time while the keyboard is hidden. If would like to turn off auto-download dictionary, call Agent.getInstance().enableDictionaryAutoDownload(false).
Please try to keep detailed input-related settings, for example, sliding input or auto-correction, untouched.
If would like to change layout, call Agent.getInstance().onLayoutChanged(IMELanguage imeLanguage,String newLayout). If would like to fetch the list of layouts under one language, call Agent.getInstance().obtainLayoutList(IMELanguage imeLanguage).
# all ppl want this...
-ignorewarnings
# Keep below for Zengine
-keep class com.nlptech.inputmethod.keyboard.ProximityInfo { *; }
-keep class com.nlptech.inputmethod.latin.DicTraverseSession { *; }
-keep class com.nlptech.inputmethod.latin.BinaryDictionary { *; }
-keep class com.nlptech.inputmethod.latin.utils.BinaryDictionaryUtils { *; }
-keep class com.nlptech.inputmethod.latin.makedict.* { *; }
-keep class com.nlptech.inputmethod.latin.personalization.UserHistoryDictionary { *; }
-keep class com.nlptech.inputmethod.latin.utils.WordInputEventForPersonalization { *; }
-keep class com.nlptech.keyboardtrace.KeyboardTrace { *; }
-keep class com.nlptech.keyboardtrace.KeyboardTraceCallback { *; }
-keep class com.nlptech.keyboardtrace.trace.TraceEventSettingsValues { *; }
-keep class com.nlptech.keyboardtrace.trace.TraceEventSettingsValues$Builder { *; }
-keep class com.nlptech.keyboardtrace.trace.TraceSuggestedWords { *; }
-keep class com.nlptech.keyboardtrace.trace.TraceSuggestedWords$SuggestedWordInfo { *; }
-keep class com.nlptech.keyboardtrace.trace.scepter.domain.** { *; }
-keep class com.nlptech.keyboardtrace.trace.scepter.TraceEvent { *; }
-keep class com.nlptech.keyboardtrace.trace.scepter.TraceEvent$Layout { *; }
-keep class com.nlptech.keyboardtrace.trace.upload.TraceUploadStrategy { *; }
-keep class com.nlptech.keyboardtrace.trace.upload.TraceUploadStrategy$* { *; }
-keep class com.nlptech.keyboardtrace.trace.scepter.TraceEditorInfo { *; }
-keep class com.nlptech.common.domain.** { *; }
-keep class com.nlptech.common.api.ResultData { *; }
-keep class com.nlptech.keyboardtrace.trace.upload.PublicField { *; }
# [zengine v1.1.1]
-keep class com.nlptech.keyboardtrace.trace.aether.AetherEvent { *; }
-keep class com.nlptech.keyboardtrace.trace.tesseract.TesseractEvent { *; }
# [zengine v1.2]
-keep class com.nlptech.keyboardview.suggestions.*{ *; }
-keep class com.android.inputmethod.pinyin.PinyinDecoderService {*;}
# [zengine v1.2.3]
-keep class com.nlptech.inputmethod.latin.ContactsBinaryDictionary { *; }
-keep class com.nlptech.inputmethod.latin.UserBinaryDictionary { *; }
-keep class com.nlptech.inputmethod.latin.personalization.UserHistoryDictionary { *; }
# [zengine v1.2.6]
-keep class com.nlptech.keyboardtrace.AgentWorkManagerInitializer {*;}
# [zengine v1.3.9]
-keep class com.nlptech.keyboardview.theme.download.DownloadThemeDomainData {*;}
-keep class com.nlptech.keyboardview.theme.download.ThemeDownloadInfoBundle {*;}
-keep class com.nlptech.keyboardview.theme.download.ThemeDownloadInfo {*;}
-keep class com.nlptech.keyboardview.theme.download.DownloadThemeInfo {*;}
-keep class com.nlptech.keyboardview.theme.download.api.DownloadThemeApiItem {*;}
After build (By “Android Studio → Build → Make Project”), find erroronus sources and use “Show Intentin Actions → Import Class” or “Auto Import on the fly” to fix issues quickly. But some issues still need manual config.
For example:
1.AppearanceSettingsFragment.java needs extra import:
import com.nlptech.inputmethod.latin.settings.Settings;
2.HardwareKeyboardEventDecoder.java needs extra import:
import com.nlptech.inputmethod.event.Event;
Fix all remaining issue to finish the migration from AOSP to Zengine SDK.