安卓自定义键盘,以下类无法实例化:

5
我已经为我的应用程序创建了一个自定义键盘。您可以在下面看到我的键盘代码。我在xml查看器中遇到了错误。 类似的问题已经被问过了: Android - Unsupported Service: audio 但是没有人回答。
我的自定义键盘代码:
public class KeyboardViewExtend extends KeyboardView implements KeyboardView.OnKeyboardActionListener
    {

    private SymjaBase _parent = null;
    private Keyboard _myKeyboard = null;


    public KeyboardViewExtend(Context c, AttributeSet atts, int defStyle) {
        super(c, atts, defStyle);
        // Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
        if (!isInEditMode()) {
            _parent = (SymjaBase)c; 
        }
        init(c);
    }

    public KeyboardViewExtend(Context c, AttributeSet atts) {
        super(c, atts);
        // Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
        if (!isInEditMode()) {
            _parent = (SymjaBase)c; 
        }
        init(c);
    }


    private void init(Context c) {
        setOnKeyboardActionListener(this);
        setEnabled(true);  
        setPreviewEnabled(true);   
        setFocusable(false);
        setFocusableInTouchMode(false);
        setBackgroundColor( Color.BLACK );
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0);
        lp.gravity = Gravity.BOTTOM;
        setLayoutParams(lp);
        makeKeyboardView();
    }

XML 图形化查看器出现错误

The following classes could not be instantiated:
- org.matheclipse.android.KeyboardViewExtend (Open Class, Show Error Log)
See the Error Log (Window > Show View) for more details.
Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse

java.lang.UnsupportedOperationException: Unsupported Service: audio
    at com.android.layoutlib.bridge.android.BridgeContext.getSystemService(BridgeContext.java:448)
    at android.inputmethodservice.KeyboardView.<init>(KeyboardView.java:376)
    at android.inputmethodservice.KeyboardView.<init>(KeyboardView.java:279)
    at org.matheclipse.android.KeyboardViewExtend.<init>(KeyboardViewExtend.java:35)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(    at sun.reflect.NativeConstructorAccessorImpl.newInstance(    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(    at java.lang.reflect.Constructor.newInstance(    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:413)
    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:170)
    at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
    at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:135)
    at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:746)
    at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:718)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:372)

请帮我解决这个问题。


你能展示一下 KeyboardView 的代码吗?你在某处调用了 getSystemService() - Cat
KeyboardView 是 Android 类,我没有修改过它。而且我也没有调用这个函数。在我的自定义编辑框中也遇到了类似的错误,但是使用 isInEdit() 函数后问题得到了解决。 - Shakti Malik
我问了你提到的另一个问题。我从未找到解决方案,主要是因为它对我来说变得不相关了——我们用较好的辅助功能服务替换了自定义键盘,这更适合我们正在做的事情。尽管如此,我们的自定义键盘在出现错误的情况下仍然可以使用。 - Ian
是的,我的自定义键盘也运行良好。但是XML图形布局无法显示键盘,这使得可视化变得困难。我在自定义editText中也遇到了同样的问题,通过使用“isInEditMode()”解决了该问题。但是键盘问题仍未解决。如果有人能帮忙,我将不胜感激。 - Shakti Malik
1
你搞定了吗?我也遇到了同样的问题。:( - Swayam
@Swayam 我已经尝试了所有的方法,但仍然没有成功。如果您能解决这个问题,请分享一下。 - Shakti Malik
1个回答

2

请参考以下问题和答案:Android - Unsupported Service: audio

简而言之: 这是Android源代码的一个bug,但我找到了解决方法。

使用KeyboardViewFix替换KeyboardView

public class KeyboardViewFix extends KeyboardView {
    public static boolean inEditMode = true;

    @TargetApi(21) // Build.VERSION_CODES.L
    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(inEditMode ? new ContextWrapperInner(context) : context, attrs, defStyleAttr, defStyleRes);
    }

    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr) {
        super(inEditMode ? new ContextWrapperInner(context) : context, attrs, defStyleAttr);
    }

    public KeyboardViewFix(Context context, AttributeSet attrs) {
        super(inEditMode ? new ContextWrapperInner(context) : context, attrs);
    }

    public static class ContextWrapperInner extends ContextWrapper {
        Context base;
        public ContextWrapperInner(Context base) {
            super(base);
            this.base = base;
        }
        public Object getSystemService(String name) {
            return Context.AUDIO_SERVICE.equals(name) ? null : base.getSystemService(name);
        }       
    }
}

请注意:在启动您的应用程序之前,需要在任何其他代码之前设置KeyboardViewFix.inEditMode = false;,否则可能会出现一些错误。


永远不要只添加链接作为答案,而是自己编写答案。你可以复制/粘贴答案,这样至少可以保证链接不会更改或失效。 - Bonatti
在其他问题中,我被警告不要复制/粘贴相同的答案。好的,我在这里复制了答案。 - Enyby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接