我是Android环境的新手,所以请耐心等待我:
我一直在努力开发软键盘,作为我正在创作的词汇构建应用程序的一部分。当我运行应用程序时,通过Android Studio(v2.3),应用程序成功启动,但输入法服务似乎被忽略了,键盘没有列在系统的输入法中(我得到的地方)通过输入设置 - >语言和输入 - >当前键盘 - >选择键盘)。我使用的是Nexus 5和Android版本6.0.1,如果有帮助的话。
为了创建键盘,我一直在关注Android开发者指南(在"创建输入法"下),以及那里引用的示例键盘(" SoftKeyboard& #34;,Link)。我不需要SoftKeyboard示例提供的所有功能(例如,候选人),因此我只将示例项目的一部分改编为我自己的;这可能是问题的原因。
为了澄清,该应用程序成功启动,但键盘服务似乎被忽略。我已经搜索了日志,发现了一个与输入法有关的错误,但看起来很小。可以找到完整日志here(注意错误从第274行开始)。
此外,这里有一些我认为对问题很重要的代码片段(当然,我可以提供任何其他请求的文件):
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.akuros.glossa.keyboard">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- Declares the input method service -->
<service android:name="GlossaKeyboard"
android:label="greek_keyboard"
android:permission="android.permission.BIND_INPUT_METHOD"
>
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data android:name="android.view.im"
android:resource="@xml/method" />
</service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
method.xml:
<?xml version="1.0" encoding="utf-8"?>
<InputMethod
xmlns:android="http://schemas.android.com/apk/res/android"
android:supportsSwitchingToNextInputMethod="true"
>
<Subtype
android:label="@string/keyboard_grk_label"
android:imeSubtypeLocale="el_Gr"
android:imeSubtypeMode="keyboard"
/>
</InputMethod>
和中心类(扩展InputMethodService),GlossaKeyboard:
package com.akuros.glossa.keyboard;
/*
* This class defines the Greek Keyboard used by this application.
*
* Created by Nitzan on 15/02/2017.
*/
//TODO have the keyboard adapt its state according to the language needed
import android.app.Dialog;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.os.IBinder;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import static android.inputmethodservice.Keyboard.KEYCODE_DELETE;
import static android.inputmethodservice.Keyboard.KEYCODE_SHIFT;
public class GlossaKeyboard extends InputMethodService
implements KeyboardView.OnKeyboardActionListener
{
//------ Key Codes ------//
private static final int KEYCODE_ENGLISH = -101;
private static final int KEYCODE_LANGUAGE_SWITCH = -102;
private static final int KEYCODE_CAPS = -103;
//------ Fields ------ //
private GlossaKeyboardView keyboardView;
private StringBuilder composing;
private InputMethodManager imm;
private Keyboard greekKeyboard;
private Keyboard englishKeyboard;
private Keyboard currKeyboard;
private int shiftState;
@Override
public void onCreate()
{
super.onCreate();
imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
composing = new StringBuilder();
shiftState = 0;
}
@Override
public void onInitializeInterface()
{
greekKeyboard = new Keyboard(this, R.xml.qwerty_greek);
englishKeyboard = new Keyboard(this, R.xml.qwerty_english);
}
@Override
public View onCreateInputView()
{
keyboardView = (GlossaKeyboardView) getLayoutInflater().inflate(
R.layout.keyboard_greek, null);
keyboardView.setOnKeyboardActionListener(this);
keyboardView.setKeyboard(greekKeyboard);
return keyboardView;
}
@Override
public void onStartInput(EditorInfo attribute, boolean restarting)
{
super.onStartInput(attribute, restarting);
composing.setLength(0);
shiftState = 0;
currKeyboard = greekKeyboard;
}
@Override
public void onFinishInput()
{
super.onFinishInput();
composing.setLength(0);
if (keyboardView != null)
keyboardView.closing();
}
/* Interface Required Methods */
@Override
public void onPress(int primaryCode)
{
}
@Override
public void onRelease(int primaryCode)
{
}
@Override
//note the static import of Keyboard's KEYCODE values
public void onKey(int primaryCode, int[] keyCodes)
{
switch (primaryCode)
{
case KEYCODE_SHIFT:
shiftState = (shiftState == 0) ? 1 : 0;
break;
case KEYCODE_CAPS:
shiftState = (shiftState == 0) ? 2 : 0;
break;
case KEYCODE_DELETE:
handleBackspace();
break;
case KEYCODE_LANGUAGE_SWITCH:
handleLanguageSwitch();
break;
case KEYCODE_ENGLISH:
handleEnglishSwitch();
break;
default:
handleCharacter(primaryCode);
break;
}
updateShiftKeyState(getCurrentInputEditorInfo());
}
@Override
public void onText(CharSequence text)
{
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
if (composing.length() > 0)
commitTyped(ic);
ic.commitText(text, 0); //not sure why this call needs to exist, commitText(ic) should already
//do the work.
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
}
//------ Private methods ------//
/* Handlers */
private void handleCharacter(int primaryCode)
{
if(isInputViewShown())
{
if(keyboardView.isShifted())
primaryCode = Character.toUpperCase(primaryCode);
}
CharSequence str = String.valueOf((char) primaryCode);
getCurrentInputConnection().commitText(str, 1);
}
private void handleBackspace()
{
final int length = composing.length();
if(length > 1)
{
composing.delete(length - 1, length);
getCurrentInputConnection().setComposingText(composing,1);
}
else if(length > 0)
{
composing.setLength(0);
getCurrentInputConnection().commitText("", 0);
}
else
{
keyDownUp(KeyEvent.KEYCODE_DEL);
}
updateShiftKeyState(getCurrentInputEditorInfo());
}
private void handleLanguageSwitch()
{
imm.switchToNextInputMethod(getToken(), false);
}
private void handleEnglishSwitch()
{
if(currKeyboard != englishKeyboard )
{
currKeyboard = englishKeyboard;
keyboardView.setKeyboard(englishKeyboard);
}
}
/* Helper Methods */
public IBinder getToken() {
final Dialog dialog = getWindow();
if (dialog == null) {
return null;
}
final Window window = dialog.getWindow();
if (window == null) {
return null;
}
return window.getAttributes().token;
}
private void commitTyped(InputConnection ic)
{
if (composing.length() > 0)
{
ic.commitText(composing, composing.length());
composing.setLength(0);
}
}
private void keyDownUp(int keyEventCode)
{
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
}
private void updateShiftKeyState(EditorInfo attr)
{
if (attr != null && keyboardView != null)
{
Keyboard keyboard = keyboardView.getKeyboard();
if (keyboard == greekKeyboard
|| keyboard == englishKeyboard)
{
int caps = 0;
EditorInfo ei = getCurrentInputEditorInfo();
if (ei != null && ei.inputType != InputType.TYPE_NULL)
{
caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
}
keyboardView.setShifted(shiftState > 0 || caps != 0);
}
}
if (shiftState == 1)
shiftState = 0;
}
/* Unused Methods */
//These methods are implemented simply because the OnKeyboardActionListener interface demands it.
//their implementation is empty.
@Override
public void swipeLeft()
{
//do nothing
}
@Override
public void swipeRight()
{
//do nothing
}
@Override
public void swipeDown()
{
//do nothing
}
@Override
public void swipeUp()
{
//do nothing
}
}
到目前为止,我已经尝试过了:
将所有与输入法相关的文件移动到一个单独的项目中,然后运行(相同的结果)
调试项目(从未到达GlossaKeyboard类的断点)
搜索日志(如上所述,未找到任何内容)
将我的文件与SoftKeyboard示例应用程序中的文件进行比较(我的版本中没有发现任何错误;除了不需要的功能[例如单词建议,拼写检查等]之外,没有发现任何遗漏)
感谢任何帮助。