mirror of
https://github.com/yuliskov/LeanKeyboard.git
synced 2026-05-03 05:12:36 -04:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2d8ce5aab | ||
|
|
7dfaac0683 | ||
|
|
cc3f605970 | ||
|
|
ac637c79f4 | ||
|
|
cb13108a11 | ||
|
|
43ef8324bf | ||
|
|
70cfd73ac8 | ||
|
|
0a42892d2d | ||
|
|
c5c88e622d | ||
|
|
6e7db94a30 | ||
|
|
80b76e9d1e | ||
|
|
8c1c36cf0e |
22
README.md
22
README.md
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
__LeanKeyKeyboard: Keyboard for Android-based set-top boxes and TVs:__
|
__LeanKeyKeyboard: Keyboard for Android-based set-top boxes and TVs:__
|
||||||
|
|
||||||
Visit Google Play page:
|
* <a href="https://t.me/LeanKeyKeyboard">Telegram group</a>
|
||||||
* <a href="https://play.google.com/store/apps/details?id=org.liskovsoft.androidtv.rukeyboard" target="_blank">[APP] LeanKeyKeyboard</a>
|
* <a href="https://play.google.com/store/apps/details?id=org.liskovsoft.androidtv.rukeyboard" target="_blank">Google Play page</a>
|
||||||
|
|
||||||
__NOTE: Google Play release is outdated. So I recommend to obtain new releases [here](https://github.com/yuliskov/LeanKeyKeyboard/releases).__
|
__NOTE: Google Play release is outdated. So I recommend to obtain new releases [here](https://github.com/yuliskov/LeanKeyKeyboard/releases).__
|
||||||
|
|
||||||
@@ -17,7 +17,9 @@ __NOTE: Google Play release is outdated. So I recommend to obtain new releases [
|
|||||||
* Doesn't depend on Google Services.
|
* Doesn't depend on Google Services.
|
||||||
* __No root required!__
|
* __No root required!__
|
||||||
|
|
||||||
__Switch to other language performed with 'world' button, menu key or long press on the space bar.__
|
__Tip: Switch to other language with language button or by long press on the space bar__
|
||||||
|
|
||||||
|
__Tip: Do long press on the language button to choose between available languages__
|
||||||
|
|
||||||
### Screenshots:
|
### Screenshots:
|
||||||
* __[Open screenshots](#screens)__
|
* __[Open screenshots](#screens)__
|
||||||
@@ -31,9 +33,15 @@ __Standard installation via ADB__
|
|||||||
* <a href="https://github.com/yuliskov/LeanKeyKeyboard/releases" target="_blank">Download latest LeanKeyKeyboard APK</a> and sideload/install with adb:
|
* <a href="https://github.com/yuliskov/LeanKeyKeyboard/releases" target="_blank">Download latest LeanKeyKeyboard APK</a> and sideload/install with adb:
|
||||||
* *adb install -r LeanKeyKeyboard.apk*
|
* *adb install -r LeanKeyKeyboard.apk*
|
||||||
* Enjoy :)
|
* Enjoy :)
|
||||||
|
|
||||||
|
### Donation:
|
||||||
|
If you want to support my developments you are welcome to buy me a cup of coffee :)
|
||||||
|
* [__Donation Alerts (RU)__](https://www.donationalerts.ru/r/firsthash)
|
||||||
|
* [__PrivatBank (UA)__](https://privatbank.ua/ru/sendmoney?payment=73ab18516e24ad365808eec66192e756879dde16)
|
||||||
|
* __BTC__: 1JAT5VVWarVBkpVbNDn8UA8HXNdrukuBSx
|
||||||
|
|
||||||
### Reviews / Articles:
|
### Reviews / Articles:
|
||||||
* Just google for "LeanKey Keyboard"
|
* [__XDA Discussion__](https://forum.xda-developers.com/fire-tv/general/guide-change-screen-keyboard-to-leankey-t3527675)
|
||||||
|
|
||||||
### Changelog:
|
### Changelog:
|
||||||
* [Check releases page for changelog ..](https://github.com/yuliskov/LeanKeyKeyboard/releases)
|
* [Check releases page for changelog ..](https://github.com/yuliskov/LeanKeyKeyboard/releases)
|
||||||
@@ -45,12 +53,6 @@ __Standard installation via ADB__
|
|||||||
### Developer:
|
### Developer:
|
||||||
* __[yuliskov](https://github.com/yuliskov)__ (design & coding)
|
* __[yuliskov](https://github.com/yuliskov)__ (design & coding)
|
||||||
|
|
||||||
### Donation:
|
|
||||||
If you want to support my developments you are welcome to buy me a cup of coffee :)
|
|
||||||
* BTC: 1JAT5VVWarVBkpVbNDn8UA8HXNdrukuBSx
|
|
||||||
* WMZ: Z375157140784
|
|
||||||
* WMU: U449339012933
|
|
||||||
|
|
||||||
### Screens:
|
### Screens:
|
||||||

|

|
||||||

|

|
||||||
|
|||||||
@@ -14,14 +14,14 @@ buildscript {
|
|||||||
// https://stackoverflow.com/questions/20404476/how-to-define-common-android-properties-for-all-modules-using-gradle
|
// https://stackoverflow.com/questions/20404476/how-to-define-common-android-properties-for-all-modules-using-gradle
|
||||||
// Gradle constants example: https://github.com/google/ExoPlayer
|
// Gradle constants example: https://github.com/google/ExoPlayer
|
||||||
ext {
|
ext {
|
||||||
compileSdkVersion = 26
|
compileSdkVersion = 28
|
||||||
buildToolsVersion = "26.0.2"
|
buildToolsVersion = "28.0.3"
|
||||||
minSdkVersion = 14
|
minSdkVersion = 14
|
||||||
targetSdkVersion = 26
|
targetSdkVersion = 26
|
||||||
appCompatVersion = 'com.android.support:appcompat-v7:26.+'
|
appCompatVersion = 'com.android.support:appcompat-v7:28.+'
|
||||||
espressoCoreVersion = 'com.android.support.test.espresso:espresso-core:2.2.2'
|
espressoCoreVersion = 'com.android.support.test.espresso:espresso-core:2.2.2'
|
||||||
junitVersion = 'junit:junit:4.12'
|
junitVersion = 'junit:junit:4.12'
|
||||||
supportVersion = 'com.android.support:support-v4:26.+'
|
supportVersion = 'com.android.support:support-v4:28.+'
|
||||||
robolectricVersion = 'org.robolectric:robolectric:3.5.1'
|
robolectricVersion = 'org.robolectric:robolectric:3.5.1'
|
||||||
crashlyticsVersion = 'com.crashlytics.sdk.android:crashlytics:2.8.0@aar'
|
crashlyticsVersion = 'com.crashlytics.sdk.android:crashlytics:2.8.0@aar'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "org.liskovsoft.leankeykeyboard.pro"
|
applicationId "org.liskovsoft.leankeykeyboard.pro"
|
||||||
minSdkVersion project.properties.minSdkVersion
|
minSdkVersion project.properties.minSdkVersion
|
||||||
targetSdkVersion project.properties.targetSdkVersion
|
targetSdkVersion project.properties.targetSdkVersion
|
||||||
versionCode 76
|
versionCode 80
|
||||||
versionName "4.3.26"
|
versionName "4.3.30"
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
|
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
|
||||||
<application android:banner="@drawable/banner_app" android:label="@string/ime_name" android:icon="@drawable/ic_launcher" tools:targetApi="21">
|
<application android:banner="@drawable/banner_app" android:label="@string/ime_name" android:icon="@drawable/ic_launcher" tools:targetApi="21">
|
||||||
<activity android:launchMode="singleTop" android:name="com.liskovsoft.other.SettingsActivity">
|
<activity android:launchMode="singleTop" android:name="com.liskovsoft.other.GenericLaunchActivity">
|
||||||
<meta-data android:name="package" android:value="com.android.settings"/>
|
<meta-data android:name="package" android:value="com.android.settings"/>
|
||||||
<meta-data android:name="class" android:value="com.android.settings.Settings$InputMethodAndLanguageSettingsActivity"/>
|
<meta-data android:name="class" android:value="com.android.settings.Settings$LanguageAndInputSettingsActivity"/>
|
||||||
|
<!-- "Languages & input" on old api -->
|
||||||
|
<meta-data android:name="package_alt" android:value="com.android.settings"/>
|
||||||
|
<meta-data android:name="class_alt" android:value="com.android.settings.Settings$InputMethodAndLanguageSettingsActivity"/>
|
||||||
|
<!-- Last try (if above not found) -->
|
||||||
|
<meta-data android:name="intent" android:value="android.settings.INPUT_METHOD_SETTINGS"/>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
|||||||
@@ -446,23 +446,23 @@ public class LeanbackKeyboardContainer {
|
|||||||
boolean overestimateHeight = false;
|
boolean overestimateHeight = false;
|
||||||
switch (focus.type) {
|
switch (focus.type) {
|
||||||
case KeyFocus.TYPE_MAIN:
|
case KeyFocus.TYPE_MAIN:
|
||||||
|
boolean showScale = false;
|
||||||
|
overestimateHeight = true;
|
||||||
if (focus.code != LeanbackKeyboardView.ASCII_SPACE) {
|
if (focus.code != LeanbackKeyboardView.ASCII_SPACE) {
|
||||||
overestimateWidth = true;
|
overestimateWidth = true;
|
||||||
} else {
|
showScale = true;
|
||||||
overestimateWidth = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LeanbackKeyboardView mainView = mMainKeyboardView;
|
LeanbackKeyboardView mainView = mMainKeyboardView;
|
||||||
int index = focus.index;
|
int index = focus.index;
|
||||||
|
|
||||||
|
boolean isClicked = false;
|
||||||
if (mTouchState == TOUCH_STATE_CLICK) {
|
if (mTouchState == TOUCH_STATE_CLICK) {
|
||||||
overestimateHeight = true;
|
isClicked = true;
|
||||||
} else {
|
|
||||||
overestimateHeight = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mainView.setFocus(index, overestimateHeight, overestimateWidth);
|
mainView.setFocus(index, isClicked, showScale);
|
||||||
mPrevView = mMainKeyboardView;
|
mPrevView = mMainKeyboardView;
|
||||||
overestimateHeight = true;
|
|
||||||
break;
|
break;
|
||||||
case KeyFocus.TYPE_VOICE:
|
case KeyFocus.TYPE_VOICE:
|
||||||
mVoiceButtonView.setMicFocused(true);
|
mVoiceButtonView.setMicFocused(true);
|
||||||
@@ -594,7 +594,12 @@ public class LeanbackKeyboardContainer {
|
|||||||
mSelector.setX(translatedX);
|
mSelector.setX(translatedX);
|
||||||
mSelector.setY(translatedY);
|
mSelector.setY(translatedY);
|
||||||
} else {
|
} else {
|
||||||
mSelector.animate().x(translatedX).y(translatedY).setInterpolator(sMovementInterpolator).setDuration(MOVEMENT_ANIMATION_DURATION).start();
|
mSelector.animate()
|
||||||
|
.x(translatedX)
|
||||||
|
.y(translatedY)
|
||||||
|
.setInterpolator(sMovementInterpolator)
|
||||||
|
.setDuration(MOVEMENT_ANIMATION_DURATION)
|
||||||
|
.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,7 +858,7 @@ public class LeanbackKeyboardContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVoiceVisible() {
|
public boolean isVoiceVisible() {
|
||||||
return mVoiceButtonView.getVisibility() == 0;
|
return mVoiceButtonView.getVisibility() == View.VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onInitInputView() {
|
public void onInitInputView() {
|
||||||
@@ -1031,6 +1036,10 @@ public class LeanbackKeyboardContainer {
|
|||||||
setKbFocus(focus, false, true);
|
setKbFocus(focus, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFocus(LeanbackKeyboardContainer.KeyFocus focus, final boolean animate) {
|
||||||
|
setKbFocus(focus, false, animate);
|
||||||
|
}
|
||||||
|
|
||||||
public void setSelectorToFocus(Rect rect, boolean overestimateWidth, boolean overestimateHeight, boolean animate) {
|
public void setSelectorToFocus(Rect rect, boolean overestimateWidth, boolean overestimateHeight, boolean animate) {
|
||||||
if (this.mSelector.getWidth() != 0 && this.mSelector.getHeight() != 0 && rect.width() != 0 && rect.height() != 0) {
|
if (this.mSelector.getWidth() != 0 && this.mSelector.getHeight() != 0 && rect.width() != 0 && rect.height() != 0) {
|
||||||
final float width = (float) rect.width();
|
final float width = (float) rect.width();
|
||||||
@@ -1132,7 +1141,7 @@ public class LeanbackKeyboardContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateAddonKeyboard() {
|
public void updateAddonKeyboard() {
|
||||||
mKeyboardManager = new KeyboardManager(mContext, mAbcKeyboard);
|
mKeyboardManager = new KeyboardManager(mContext);
|
||||||
switchToNextKeyboard();
|
switchToNextKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.google.android.leanback.ime;
|
package com.google.android.leanback.ime;
|
||||||
|
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.inputmethodservice.Keyboard.Key;
|
import android.inputmethodservice.Keyboard.Key;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -51,7 +50,7 @@ public class LeanbackKeyboardController implements LeanbackKeyboardContainer.Voi
|
|||||||
private LeanbackKeyboardContainer.KeyFocus mTempFocus;
|
private LeanbackKeyboardContainer.KeyFocus mTempFocus;
|
||||||
private PointF mTempPoint;
|
private PointF mTempPoint;
|
||||||
private LeanbackKeyboardController.TouchEventListener mTouchEventListener;
|
private LeanbackKeyboardController.TouchEventListener mTouchEventListener;
|
||||||
private long prevTime;
|
private long mPrevTime;
|
||||||
private boolean mShowInput;
|
private boolean mShowInput;
|
||||||
private int mLastEditorIdPhysicalKeyboardWasUsed;
|
private int mLastEditorIdPhysicalKeyboardWasUsed;
|
||||||
private boolean mHideKeyboardWhenPhysicalKeyboardUsed = true;
|
private boolean mHideKeyboardWhenPhysicalKeyboardUsed = true;
|
||||||
@@ -500,15 +499,39 @@ public class LeanbackKeyboardController implements LeanbackKeyboardContainer.Voi
|
|||||||
updatePositionToCurrentFocus();
|
updatePositionToCurrentFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCallAllowed(int periodMillis) {
|
/**
|
||||||
|
* Simple throttle routine.
|
||||||
|
* @param callInterval interval
|
||||||
|
* @return is allowed
|
||||||
|
*/
|
||||||
|
private boolean isCallAllowedOrigin(int callInterval) {
|
||||||
long currTimeMS = System.currentTimeMillis();
|
long currTimeMS = System.currentTimeMillis();
|
||||||
if (this.prevTime != 0L && currTimeMS - this.prevTime <= (long) (periodMillis * 3)) {
|
long timeDelta = currTimeMS - mPrevTime;
|
||||||
if (currTimeMS - this.prevTime > (long) periodMillis) {
|
if (mPrevTime != 0 && timeDelta <= (callInterval * 3)) {
|
||||||
this.prevTime = 0L;
|
if (timeDelta > callInterval) {
|
||||||
|
mPrevTime = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.prevTime = currTimeMS;
|
mPrevTime = currTimeMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple throttle routine. Simplified comparing to previous. Not tested yet!!!!
|
||||||
|
* @param interval interval
|
||||||
|
* @return is allowed
|
||||||
|
*/
|
||||||
|
private boolean isCallAllowed2(int interval) {
|
||||||
|
long currTimeMS = System.currentTimeMillis();
|
||||||
|
long timeDelta = currTimeMS - mPrevTime;
|
||||||
|
if (mPrevTime == 0) {
|
||||||
|
mPrevTime = currTimeMS;
|
||||||
|
return true;
|
||||||
|
} else if (timeDelta > interval) {
|
||||||
|
mPrevTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -540,13 +563,10 @@ public class LeanbackKeyboardController implements LeanbackKeyboardContainer.Voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void moveSelectorToPoint(float x, float y) {
|
private void moveSelectorToPoint(float x, float y) {
|
||||||
LeanbackKeyboardContainer container = this.mContainer;
|
LeanbackKeyboardContainer container = mContainer;
|
||||||
LeanbackKeyboardContainer.KeyFocus focus = this.mTempFocus;
|
LeanbackKeyboardContainer.KeyFocus focus = mTempFocus;
|
||||||
container.getBestFocus(new Float(x), new Float(y), focus);
|
container.getBestFocus(x, y, focus);
|
||||||
this.mContainer.setFocus(this.mTempFocus);
|
mContainer.setFocus(mTempFocus, false);
|
||||||
container = this.mContainer;
|
|
||||||
Rect rect = this.mTempFocus.rect;
|
|
||||||
container.alignSelector((float) rect.centerX(), (float) rect.centerY(), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean onDirectionalMove(int dir) {
|
private boolean onDirectionalMove(int dir) {
|
||||||
@@ -634,21 +654,21 @@ public class LeanbackKeyboardController implements LeanbackKeyboardContainer.Voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to handle on hover event
|
* Control keyboard from the mouse. Movement catching
|
||||||
* @param view active view
|
* @param view active view
|
||||||
* @param event event object
|
* @param event event object
|
||||||
* @return is hover handled
|
* @return is hover handled
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean onHover(View view, MotionEvent event) {
|
public boolean onHover(View view, MotionEvent event) {
|
||||||
boolean allowed = isCallAllowed(300);
|
boolean handled = false;
|
||||||
if (allowed) {
|
if (event.getAction() == MotionEvent.ACTION_HOVER_MOVE) {
|
||||||
if (event.getAction() == MotionEvent.ACTION_HOVER_MOVE) {
|
PointF pos = getRelativePosition(mContainer.getView(), event);
|
||||||
PointF pos = getRelativePosition(mContainer.getView(), event);
|
moveSelectorToPoint(pos.x, pos.y);
|
||||||
moveSelectorToPoint(pos.x, pos.y);
|
handled = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allowed;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -523,8 +523,12 @@ public class LeanbackKeyboardView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mCurrentFocusView = mKeyImageViews[indexFull];
|
mCurrentFocusView = mKeyImageViews[indexFull];
|
||||||
mCurrentFocusView.animate().scaleX(scale).scaleY(scale).setInterpolator(LeanbackKeyboardContainer.sMovementInterpolator)
|
mCurrentFocusView.animate()
|
||||||
.setDuration((long) mClickAnimDur).start();
|
.scaleX(scale)
|
||||||
|
.scaleY(scale)
|
||||||
|
.setInterpolator(LeanbackKeyboardContainer.sMovementInterpolator)
|
||||||
|
.setDuration((long) mClickAnimDur)
|
||||||
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
mFocusIndex = indexFull;
|
mFocusIndex = indexFull;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class KeyboardManager {
|
public class KeyboardManager {
|
||||||
private final Keyboard mEnglishKeyboard;
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final KeyboardStateManager mStateManager;
|
private final KeyboardStateManager mStateManager;
|
||||||
private List<? extends KeyboardBuilder> mKeyboardBuilders;
|
private List<? extends KeyboardBuilder> mKeyboardBuilders;
|
||||||
@@ -17,13 +16,8 @@ public class KeyboardManager {
|
|||||||
|
|
||||||
private int mKeyboardIndex = 0;
|
private int mKeyboardIndex = 0;
|
||||||
|
|
||||||
public KeyboardManager(Context ctx, int keyboardResId) {
|
public KeyboardManager(Context ctx) {
|
||||||
this(ctx, new Keyboard(ctx, keyboardResId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyboardManager(Context ctx, Keyboard englishKeyboard) {
|
|
||||||
mContext = ctx;
|
mContext = ctx;
|
||||||
mEnglishKeyboard = englishKeyboard;
|
|
||||||
mStateManager = new KeyboardStateManager(mContext, this);
|
mStateManager = new KeyboardStateManager(mContext, this);
|
||||||
mStateManager.restore();
|
mStateManager.restore();
|
||||||
init();
|
init();
|
||||||
@@ -37,7 +31,6 @@ public class KeyboardManager {
|
|||||||
|
|
||||||
private List<Keyboard> buildAllKeyboards() {
|
private List<Keyboard> buildAllKeyboards() {
|
||||||
List<Keyboard> keyboards = new ArrayList<>();
|
List<Keyboard> keyboards = new ArrayList<>();
|
||||||
keyboards.add(mEnglishKeyboard);
|
|
||||||
if (!mKeyboardBuilders.isEmpty()) {
|
if (!mKeyboardBuilders.isEmpty()) {
|
||||||
for (KeyboardBuilder builder : mKeyboardBuilders) {
|
for (KeyboardBuilder builder : mKeyboardBuilders) {
|
||||||
keyboards.add(builder.createKeyboard());
|
keyboards.add(builder.createKeyboard());
|
||||||
|
|||||||
@@ -21,26 +21,37 @@ public class ResKeyboardFactory implements KeyboardFactory {
|
|||||||
@Override
|
@Override
|
||||||
public List<? extends KeyboardBuilder> getAllAvailableKeyboards(Context context) {
|
public List<? extends KeyboardBuilder> getAllAvailableKeyboards(Context context) {
|
||||||
List<KeyboardBuilder> result = new ArrayList<>();
|
List<KeyboardBuilder> result = new ArrayList<>();
|
||||||
|
|
||||||
List<KeyboardInfo> infos = ResKeyboardInfo.getAllKeyboardInfos(context);
|
List<KeyboardInfo> infos = ResKeyboardInfo.getAllKeyboardInfos(context);
|
||||||
final Resources resources = mContext.getResources();
|
|
||||||
|
|
||||||
for (final KeyboardInfo info : infos) {
|
for (final KeyboardInfo info : infos) {
|
||||||
if (!info.isEnabled()) {
|
if (!info.isEnabled()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.add(new KeyboardBuilder() {
|
result.add(createKeyboard(info.getLangCode()));
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Keyboard createKeyboard() {
|
|
||||||
return new Keyboard(mContext, resources.getIdentifier("qwerty_" + info.getLangCode(), "xml", mContext.getPackageName()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// at least one kbd should be enabled
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
KeyboardInfo firstKbd = infos.get(0);
|
||||||
|
result.add(createKeyboard(firstKbd.getLangCode()));
|
||||||
|
firstKbd.setEnabled(true);
|
||||||
|
ResKeyboardInfo.updateAllKeyboardInfos(mContext, infos);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyboardBuilder createKeyboard(final String langCode) {
|
||||||
|
return new KeyboardBuilder() {
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Keyboard createKeyboard() {
|
||||||
|
return new Keyboard(mContext, mContext.getResources().getIdentifier("qwerty_" + langCode, "xml", mContext.getPackageName()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean needUpdate() {
|
public boolean needUpdate() {
|
||||||
return ResKeyboardInfo.needUpdate();
|
return ResKeyboardInfo.needUpdate();
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package com.liskovsoft.other;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GenericLaunchActivity extends Activity
|
||||||
|
{
|
||||||
|
private static final String META_PACKAGE_NAME = "package";
|
||||||
|
private static final String META_CLASS_NAME = "class";
|
||||||
|
private static final String META_PACKAGE_NAME_ALT = "package_alt";
|
||||||
|
private static final String META_CLASS_NAME_ALT = "class_alt";
|
||||||
|
private static final String META_INTENT_NAME = "intent";
|
||||||
|
private List<Intent> mIntents = new ArrayList<>();
|
||||||
|
|
||||||
|
protected void onCreate(final Bundle bundle) {
|
||||||
|
super.onCreate(bundle);
|
||||||
|
launchApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant")
|
||||||
|
private void addCommonIntentFlags(final Intent intent) {
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant")
|
||||||
|
private ActivityInfo getCurrentActivityInfo() {
|
||||||
|
try {
|
||||||
|
return getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES);
|
||||||
|
}
|
||||||
|
catch (NameNotFoundException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
makeLongToast(ex.getLocalizedMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchApp() {
|
||||||
|
makeIntentList();
|
||||||
|
startIntents();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startIntents() {
|
||||||
|
for (Intent intent : mIntents) {
|
||||||
|
boolean result = startIntent(intent);
|
||||||
|
if (result) { // run until first successful attempt
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeIntentList() {
|
||||||
|
final ActivityInfo activityInfo = getCurrentActivityInfo();
|
||||||
|
if (activityInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Bundle metaData = activityInfo.metaData;
|
||||||
|
|
||||||
|
String metaPackageName = metaData.getString(META_PACKAGE_NAME);
|
||||||
|
String metaClassName = metaData.getString(META_CLASS_NAME);
|
||||||
|
mIntents.add(createIntent(metaPackageName, metaClassName));
|
||||||
|
|
||||||
|
String metaPackageNameAlt = metaData.getString(META_PACKAGE_NAME_ALT);
|
||||||
|
String metaClassNameAlt = metaData.getString(META_CLASS_NAME_ALT);
|
||||||
|
mIntents.add(createIntent(metaPackageNameAlt, metaClassNameAlt));
|
||||||
|
|
||||||
|
String metaIntentName = metaData.getString(META_INTENT_NAME);
|
||||||
|
mIntents.add(createIntent(metaIntentName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Intent createIntent(String intentName) {
|
||||||
|
if (intentName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Intent intent = new Intent();
|
||||||
|
intent.setAction(intentName);
|
||||||
|
addCommonIntentFlags(intent);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Intent createIntent(String packageName, String className) {
|
||||||
|
if (packageName == null || className == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Intent intent = new Intent();
|
||||||
|
intent.setComponent(new ComponentName(packageName, className));
|
||||||
|
addCommonIntentFlags(intent);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeLongToast(final String s) {
|
||||||
|
makeLongToast(s, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeLongToast(final String s, int nums) {
|
||||||
|
int n;
|
||||||
|
for (n = nums / 2, nums = 0; nums < n; ++nums) {
|
||||||
|
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean startIntent(final Intent intent) {
|
||||||
|
if (intent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
catch (ActivityNotFoundException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
//
|
|
||||||
// Decompiled by Procyon v0.5.30
|
|
||||||
//
|
|
||||||
|
|
||||||
package com.liskovsoft.other;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.widget.Toast;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.app.Activity;
|
|
||||||
|
|
||||||
public class SettingsActivity extends Activity
|
|
||||||
{
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
private void addIntentFlags(final Intent intent) {
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
private ActivityInfo getCurrentActivityInfo() {
|
|
||||||
try {
|
|
||||||
return getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES);
|
|
||||||
}
|
|
||||||
catch (NameNotFoundException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
makeLongToast(ex.getLocalizedMessage(), 10);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void launchApp() {
|
|
||||||
final Intent intent = makeIntent(getCurrentActivityInfo());
|
|
||||||
addIntentFlags(intent);
|
|
||||||
startIntent(intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Intent makeIntent(final ActivityInfo activityInfo) {
|
|
||||||
final Bundle metaData = activityInfo.metaData;
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
if (metaData.getString("intent") != null) {
|
|
||||||
intent.setAction(metaData.getString("intent"));
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
intent.setComponent(new ComponentName(metaData.getString("package"), metaData.getString("class")));
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeLongToast(final String s, int nums) {
|
|
||||||
int n;
|
|
||||||
for (n = nums / 2, nums = 0; nums < n; ++nums) {
|
|
||||||
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startIntent(final Intent intent) {
|
|
||||||
try {
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
catch (ActivityNotFoundException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
makeLongToast(ex.getLocalizedMessage(), 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onCreate(final Bundle bundle) {
|
|
||||||
super.onCreate(bundle);
|
|
||||||
launchApp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="additional_languages">
|
<string-array name="additional_languages">
|
||||||
<item>Swedish|sv</item>
|
<item>English|us</item>
|
||||||
<item>Arabic|ar</item>
|
<item>Arabic|ar</item>
|
||||||
<item>Bulgarian|bg</item>
|
<item>Bulgarian|bg</item>
|
||||||
<item>Dutch|nl</item>
|
<item>Dutch|nl</item>
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
<item>Italian|it</item>
|
<item>Italian|it</item>
|
||||||
<item>Persian|fa</item>
|
<item>Persian|fa</item>
|
||||||
<item>Russian|ru</item>
|
<item>Russian|ru</item>
|
||||||
|
<item>Swedish|sv</item>
|
||||||
<item>Thai|th</item>
|
<item>Thai|th</item>
|
||||||
<item>Turkish|tr</item>
|
<item>Turkish|tr</item>
|
||||||
<item>Ukrainian|uk</item>
|
<item>Ukrainian|uk</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user