Como desenvolver um teclado virtual para Android? [fechadas]

110

Eu gostaria de brincar com algumas idéias e desenvolver um teclado virtual para Android para substituir o padrão.

  • Existe alguma informação geral sobre o desenvolvimento de teclado virtual para Android? Quaisquer práticas recomendadas ou diretrizes?

  • Posso fazer com meu aplicativo de teclado praticamente qualquer coisa que faria com um aplicativo Android normal?

  • Posso fazer conexões HTTP para sincronizar os dados do teclado com um banco de dados em nuvem e outros telefones que tenho?

  • Posso abrir outras janelas / telas ao pressionar uma tecla, por exemplo, para exibir uma interface de entrada personalizada diferente de uma interface QWERTY normal. Se isso não funcionar, posso usar uma caixa de diálogo pop-up?

znq
fonte

Respostas:

82

Algumas dicas:

Sobre suas perguntas:

Um inputMethod é basicamente um Android Service, então sim, você pode fazer HTTP e todas as coisas que você pode fazer em um Service.

Você pode abrir Activitiese diálogos do InputMethod. Mais uma vez, é apenas um Service.

Estou desenvolvendo um IME, pergunte novamente se tiver algum problema.

Macarse
fonte
1
Ei, acabei de encontrar este post. Eu queria saber como construir o teclado LatinIME. Eu clonei o repo, mas quando tento construir a parte java, parece que reclama da parte nativa, e não consigo descobrir como fazer o ndk construir a parte certa. Alguma dica?
Ibrahim
1
Eu tenho um problema com relação ao teclado. Eu adicionei o método de entrada de acordo com as etapas fornecidas acima, embora minha opção de teclado personalizado esteja mostrando a opção de configuração com teclado embutido, mas na verdade quando eu seleciono meu teclado personalizado para substituir o teclado embutido em meu aplicativo batendo. Você tem alguma ideia de onde estou errando?
Aniket,
3
o link para o repositório LatinIME parece estar fora do ar
Bruce
o link para o repositório LatinIME parece estar fora do ar @Bruce
Karan Mavadhiya
@Macarse Eu segui com o tutorial mencionado e estou preso em redimensionar a altura do teclado. Quaisquer direções?
Prateek
12

Criar teclado personalizado para o próprio EditText

Baixar o código inteiro

Neste post eu criei um teclado simples que contém algumas teclas especiais como (teclas da França) e é compatível com letras maiúsculas e minúsculas e teclas numéricas e alguns símbolos.

package sra.keyboard;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;

public class Main extends Activity implements OnTouchListener, OnClickListener,
  OnFocusChangeListener {
 private EditText mEt, mEt1; // Edit Text boxes
 private Button mBSpace, mBdone, mBack, mBChange, mNum;
 private RelativeLayout mLayout, mKLayout;
 private boolean isEdit = false, isEdit1 = false;
 private String mUpper = "upper", mLower = "lower";
 private int w, mWindowWidth;
 private String sL[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
   "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
   "x", "y", "z", "ç", "à", "é", "è", "û", "î" };
 private String cL[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
   "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
   "X", "Y", "Z", "ç", "à", "é", "è", "û", "î" };
 private String nS[] = { "!", ")", "'", "#", "3", "$", "%", "&", "8", "*",
   "?", "/", "+", "-", "9", "0", "1", "4", "@", "5", "7", "(", "2",
   "\"", "6", "_", "=", "]", "[", "<", ">", "|" };
 private Button mB[] = new Button[32];

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  try {
   setContentView(R.layout.main);
   // adjusting key regarding window sizes
   setKeys();
   setFrow();
   setSrow();
   setTrow();
   setForow();
   mEt = (EditText) findViewById(R.id.xEt);
   mEt.setOnTouchListener(this);
   mEt.setOnFocusChangeListener(this);
   mEt1 = (EditText) findViewById(R.id.et1);

   mEt1.setOnTouchListener(this);
   mEt1.setOnFocusChangeListener(this);
   mEt.setOnClickListener(this);
   mEt1.setOnClickListener(this);
   mLayout = (RelativeLayout) findViewById(R.id.xK1);
   mKLayout = (RelativeLayout) findViewById(R.id.xKeyBoard);

  } catch (Exception e) {
   Log.w(getClass().getName(), e.toString());
  }

 }

 @Override
 public boolean onTouch(View v, MotionEvent event) {
  if (v == mEt) {
   hideDefaultKeyboard();
   enableKeyboard();

  }
  if (v == mEt1) {
   hideDefaultKeyboard();
   enableKeyboard();

  }
  return true;
 }

 @Override
 public void onClick(View v) {

  if (v == mBChange) {

   if (mBChange.getTag().equals(mUpper)) {
    changeSmallLetters();
    changeSmallTags();
   } else if (mBChange.getTag().equals(mLower)) {
    changeCapitalLetters();
    changeCapitalTags();
   }

  } else if (v != mBdone && v != mBack && v != mBChange && v != mNum) {
   addText(v);

  } else if (v == mBdone) {

   disableKeyboard();

  } else if (v == mBack) {
   isBack(v);
  } else if (v == mNum) {
   String nTag = (String) mNum.getTag();
   if (nTag.equals("num")) {
    changeSyNuLetters();
    changeSyNuTags();
    mBChange.setVisibility(Button.INVISIBLE);

   }
   if (nTag.equals("ABC")) {
    changeCapitalLetters();
    changeCapitalTags();
   }

  }

 }

 @Override
 public void onFocusChange(View v, boolean hasFocus) {
  if (v == mEt && hasFocus == true) {
   isEdit = true;
   isEdit1 = false;

  } else if (v == mEt1 && hasFocus == true) {
   isEdit = false;
   isEdit1 = true;

  }

 }

 private void addText(View v) {
  if (isEdit == true) {
   String b = "";
   b = (String) v.getTag();
   if (b != null) {
    // adding text in Edittext
    mEt.append(b);

   }
  }

  if (isEdit1 == true) {
   String b = "";
   b = (String) v.getTag();
   if (b != null) {
    // adding text in Edittext
    mEt1.append(b);

   }

  }

 }

 private void isBack(View v) {
  if (isEdit == true) {
   CharSequence cc = mEt.getText();
   if (cc != null && cc.length() > 0) {
    {
     mEt.setText("");
     mEt.append(cc.subSequence(0, cc.length() - 1));
    }

   }
  }

  if (isEdit1 == true) {
   CharSequence cc = mEt1.getText();
   if (cc != null && cc.length() > 0) {
    {
     mEt1.setText("");
     mEt1.append(cc.subSequence(0, cc.length() - 1));
    }
   }
  }
 }
 private void changeSmallLetters() {
  mBChange.setVisibility(Button.VISIBLE);
  for (int i = 0; i < sL.length; i++)
   mB[i].setText(sL[i]);
  mNum.setTag("12#");
 }
 private void changeSmallTags() {
  for (int i = 0; i < sL.length; i++)
   mB[i].setTag(sL[i]);
  mBChange.setTag("lower");
  mNum.setTag("num");
 }
 private void changeCapitalLetters() {
  mBChange.setVisibility(Button.VISIBLE);
  for (int i = 0; i < cL.length; i++)
   mB[i].setText(cL[i]);
  mBChange.setTag("upper");
  mNum.setText("12#");

 }

 private void changeCapitalTags() {
  for (int i = 0; i < cL.length; i++)
   mB[i].setTag(cL[i]);
  mNum.setTag("num");

 }

 private void changeSyNuLetters() {

  for (int i = 0; i < nS.length; i++)
   mB[i].setText(nS[i]);
  mNum.setText("ABC");
 }

 private void changeSyNuTags() {
  for (int i = 0; i < nS.length; i++)
   mB[i].setTag(nS[i]);
  mNum.setTag("ABC");
 }

 // enabling customized keyboard
 private void enableKeyboard() {

  mLayout.setVisibility(RelativeLayout.VISIBLE);
  mKLayout.setVisibility(RelativeLayout.VISIBLE);

 }

 // Disable customized keyboard
 private void disableKeyboard() {
  mLayout.setVisibility(RelativeLayout.INVISIBLE);
  mKLayout.setVisibility(RelativeLayout.INVISIBLE);

 }

 private void hideDefaultKeyboard() {
  getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

 }

 private void setFrow() {
  w = (mWindowWidth / 13);
  w = w - 15;
  mB[16].setWidth(w);
  mB[22].setWidth(w + 3);
  mB[4].setWidth(w);
  mB[17].setWidth(w);
  mB[19].setWidth(w);
  mB[24].setWidth(w);
  mB[20].setWidth(w);
  mB[8].setWidth(w);
  mB[14].setWidth(w);
  mB[15].setWidth(w);
  mB[16].setHeight(50);
  mB[22].setHeight(50);
  mB[4].setHeight(50);
  mB[17].setHeight(50);
  mB[19].setHeight(50);
  mB[24].setHeight(50);
  mB[20].setHeight(50);
  mB[8].setHeight(50);
  mB[14].setHeight(50);
  mB[15].setHeight(50);

 }

 private void setSrow() {
  w = (mWindowWidth / 10);
  mB[0].setWidth(w);
  mB[18].setWidth(w);
  mB[3].setWidth(w);
  mB[5].setWidth(w);
  mB[6].setWidth(w);
  mB[7].setWidth(w);
  mB[26].setWidth(w);
  mB[9].setWidth(w);
  mB[10].setWidth(w);
  mB[11].setWidth(w);
  mB[26].setWidth(w);

  mB[0].setHeight(50);
  mB[18].setHeight(50);
  mB[3].setHeight(50);
  mB[5].setHeight(50);
  mB[6].setHeight(50);
  mB[7].setHeight(50);
  mB[9].setHeight(50);
  mB[10].setHeight(50);
  mB[11].setHeight(50);
  mB[26].setHeight(50);
 }

 private void setTrow() {
  w = (mWindowWidth / 12);
  mB[25].setWidth(w);
  mB[23].setWidth(w);
  mB[2].setWidth(w);
  mB[21].setWidth(w);
  mB[1].setWidth(w);
  mB[13].setWidth(w);
  mB[12].setWidth(w);
  mB[27].setWidth(w);
  mB[28].setWidth(w);
  mBack.setWidth(w);

  mB[25].setHeight(50);
  mB[23].setHeight(50);
  mB[2].setHeight(50);
  mB[21].setHeight(50);
  mB[1].setHeight(50);
  mB[13].setHeight(50);
  mB[12].setHeight(50);
  mB[27].setHeight(50);
  mB[28].setHeight(50);
  mBack.setHeight(50);

 }

 private void setForow() {
  w = (mWindowWidth / 10);
  mBSpace.setWidth(w * 4);
  mBSpace.setHeight(50);
  mB[29].setWidth(w);
  mB[29].setHeight(50);

  mB[30].setWidth(w);
  mB[30].setHeight(50);

  mB[31].setHeight(50);
  mB[31].setWidth(w);
  mBdone.setWidth(w + (w / 1));
  mBdone.setHeight(50);

 }

 private void setKeys() {
  mWindowWidth = getWindowManager().getDefaultDisplay().getWidth(); // getting
  // window
  // height
  // getting ids from xml files
  mB[0] = (Button) findViewById(R.id.xA);
  mB[1] = (Button) findViewById(R.id.xB);
  mB[2] = (Button) findViewById(R.id.xC);
  mB[3] = (Button) findViewById(R.id.xD);
  mB[4] = (Button) findViewById(R.id.xE);
  mB[5] = (Button) findViewById(R.id.xF);
  mB[6] = (Button) findViewById(R.id.xG);
  mB[7] = (Button) findViewById(R.id.xH);
  mB[8] = (Button) findViewById(R.id.xI);
  mB[9] = (Button) findViewById(R.id.xJ);
  mB[10] = (Button) findViewById(R.id.xK);
  mB[11] = (Button) findViewById(R.id.xL);
  mB[12] = (Button) findViewById(R.id.xM);
  mB[13] = (Button) findViewById(R.id.xN);
  mB[14] = (Button) findViewById(R.id.xO);
  mB[15] = (Button) findViewById(R.id.xP);
  mB[16] = (Button) findViewById(R.id.xQ);
  mB[17] = (Button) findViewById(R.id.xR);
  mB[18] = (Button) findViewById(R.id.xS);
  mB[19] = (Button) findViewById(R.id.xT);
  mB[20] = (Button) findViewById(R.id.xU);
  mB[21] = (Button) findViewById(R.id.xV);
  mB[22] = (Button) findViewById(R.id.xW);
  mB[23] = (Button) findViewById(R.id.xX);
  mB[24] = (Button) findViewById(R.id.xY);
  mB[25] = (Button) findViewById(R.id.xZ);
  mB[26] = (Button) findViewById(R.id.xS1);
  mB[27] = (Button) findViewById(R.id.xS2);
  mB[28] = (Button) findViewById(R.id.xS3);
  mB[29] = (Button) findViewById(R.id.xS4);
  mB[30] = (Button) findViewById(R.id.xS5);
  mB[31] = (Button) findViewById(R.id.xS6);
  mBSpace = (Button) findViewById(R.id.xSpace);
  mBdone = (Button) findViewById(R.id.xDone);
  mBChange = (Button) findViewById(R.id.xChange);
  mBack = (Button) findViewById(R.id.xBack);
  mNum = (Button) findViewById(R.id.xNum);
  for (int i = 0; i < mB.length; i++)
   mB[i].setOnClickListener(this);
  mBSpace.setOnClickListener(this);
  mBdone.setOnClickListener(this);
  mBack.setOnClickListener(this);
  mBChange.setOnClickListener(this);
  mNum.setOnClickListener(this);

 }

}
sravan
fonte
1
Eu desenvolvi um teclado personalizado e meu código é semelhante ao postado acima, quando eu crio o apk ele está rodando com sucesso em qualquer dispositivo Android (já que está funcionando como aplicativo do usuário). Mas o problema surge quando eu preciso adicionar meu aplicativo como aplicativo de sistema (para isso usei o método de entrada) em qualquer dispositivo, substituindo o teclado existente atualmente, ele está mostrando o nome do meu teclado nas configurações, mas quando eu seleciono meu teclado me dá um erro como "Infelizmente, a placa MyKey parou". Alguém tem alguma ideia sobre isso ??? .....
Aniket
11

Um bom lugar para começar é o aplicativo de amostra fornecido nos documentos do desenvolvedor .

  • As diretrizes seriam apenas torná-lo o mais utilizável possível. Dê uma olhada nas outras disponíveis no mercado para ver o que você deve buscar
  • Sim, os serviços podem fazer a maioria das coisas, incluindo internet; desde que você tenha solicitado essas permissões
  • Você pode abrir atividades e fazer o que quiser se tiver problemas ao fazer algumas coisas no teclado. Por exemplo, o teclado da HTC possui um botão para abrir as configurações de atividade e outro para abrir uma caixa de diálogo para alterar os idiomas.

Dê uma olhada em outros IMEs para ver o que você deve almejar. Alguns (como o oficial) são de código aberto.

matto 1990
fonte
4

em primeiro lugar, você deve definir um arquivo .xml e fazer a interface do usuário do teclado nele:

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="12.50%p"
android:keyHeight="7%p">
<!--
android:horizontalGap="0.50%p"
android:verticalGap="0.50%p"
NOTE When we add a horizontalGap in pixels, this interferes with keyWidth in percentages adding up to 100%
NOTE When we have a horizontalGap (on Keyboard level) of 0, this make the horizontalGap (on Key level) to move from after the key to before the key... (I consider this a bug) 
-->
<Row>
    <Key android:codes="-5" android:keyLabel="remove"  android:keyEdgeFlags="left" />
    <Key android:codes="48"    android:keyLabel="0" />
    <Key android:codes="55006" android:keyLabel="clear" />
</Row>
<Row>
    <Key android:codes="49"    android:keyLabel="1"  android:keyEdgeFlags="left" />
    <Key android:codes="50"    android:keyLabel="2" />
    <Key android:codes="51"    android:keyLabel="3" />
</Row>
<Row>
    <Key android:codes="52"    android:keyLabel="4"  android:keyEdgeFlags="left" />
    <Key android:codes="53"    android:keyLabel="5" />
    <Key android:codes="54"    android:keyLabel="6" />
</Row>

<Row>
    <Key android:codes="55"    android:keyLabel="7"  android:keyEdgeFlags="left" />
    <Key android:codes="56"    android:keyLabel="8" />
    <Key android:codes="57"    android:keyLabel="9" />
</Row>

Neste exemplo, você tem 4 linhas e em cada linha você tem 3 chaves. também você pode colocar um ícone em cada tecla que desejar.

Em seguida, você deve adicionar a tag xml em sua IU de atividades como este:

<android.inputmethodservice.KeyboardView
        android:id="@+id/keyboardview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:visibility="visible" />

Também em seu arquivo de atividade .java, você deve definir o teclado e atribuí-lo a um EditText:

CustomKeyboard mCustomKeyboard1 = new CustomKeyboard(this,
            R.id.keyboardview1, R.xml.horizontal_keyboard);
    mCustomKeyboard1.registerEditText(R.id.inputSearch);

Este código atribui inputSearch (que é um EditText) ao seu teclado.

import android.app.Activity;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.text.Editable;
import android.text.InputType;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;


public class CustomKeyboard {

/** A link to the KeyboardView that is used to render this CustomKeyboard. */
private KeyboardView mKeyboardView;
/** A link to the activity that hosts the {@link #mKeyboardView}. */
private Activity mHostActivity;

/** The key (code) handler. */
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {

    public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
    public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
    public final static int CodePrev = 55000;
    public final static int CodeAllLeft = 55001;
    public final static int CodeLeft = 55002;
    public final static int CodeRight = 55003;
    public final static int CodeAllRight = 55004;
    public final static int CodeNext = 55005;
    public final static int CodeClear = 55006;

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        // NOTE We can say '<Key android:codes="49,50" ... >' in the xml
        // file; all codes come in keyCodes, the first in this list in
        // primaryCode
        // Get the EditText and its Editable
        View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
        if (focusCurrent == null
                || focusCurrent.getClass() != EditText.class)
            return;
        EditText edittext = (EditText) focusCurrent;
        Editable editable = edittext.getText();
        int start = edittext.getSelectionStart();
        // Apply the key to the edittext
        if (primaryCode == CodeCancel) {
            hideCustomKeyboard();
        } else if (primaryCode == CodeDelete) {
            if (editable != null && start > 0)
                editable.delete(start - 1, start);
        } else if (primaryCode == CodeClear) {
            if (editable != null)
                editable.clear();
        } else if (primaryCode == CodeLeft) {
            if (start > 0)
                edittext.setSelection(start - 1);
        } else if (primaryCode == CodeRight) {
            if (start < edittext.length())
                edittext.setSelection(start + 1);
        } else if (primaryCode == CodeAllLeft) {
            edittext.setSelection(0);
        } else if (primaryCode == CodeAllRight) {
            edittext.setSelection(edittext.length());
        } else if (primaryCode == CodePrev) {
            View focusNew = edittext.focusSearch(View.FOCUS_BACKWARD);
            if (focusNew != null)
                focusNew.requestFocus();
        } else if (primaryCode == CodeNext) {
            View focusNew = edittext.focusSearch(View.FOCUS_FORWARD);
            if (focusNew != null)
                focusNew.requestFocus();
        } else { // insert character
            editable.insert(start, Character.toString((char) primaryCode));
        }
    }

    @Override
    public void onPress(int arg0) {
    }

    @Override
    public void onRelease(int primaryCode) {
    }

    @Override
    public void onText(CharSequence text) {
    }

    @Override
    public void swipeDown() {
    }

    @Override
    public void swipeLeft() {
    }

    @Override
    public void swipeRight() {
    }

    @Override
    public void swipeUp() {
    }
};

/**
 * Create a custom keyboard, that uses the KeyboardView (with resource id
 * <var>viewid</var>) of the <var>host</var> activity, and load the keyboard
 * layout from xml file <var>layoutid</var> (see {@link Keyboard} for
 * description). Note that the <var>host</var> activity must have a
 * <var>KeyboardView</var> in its layout (typically aligned with the bottom
 * of the activity). Note that the keyboard layout xml file may include key
 * codes for navigation; see the constants in this class for their values.
 * Note that to enable EditText's to use this custom keyboard, call the
 * {@link #registerEditText(int)}.
 * 
 * @param host
 *            The hosting activity.
 * @param viewid
 *            The id of the KeyboardView.
 * @param layoutid
 *            The id of the xml file containing the keyboard layout.
 */
public CustomKeyboard(Activity host, int viewid, int layoutid) {
    mHostActivity = host;
    mKeyboardView = (KeyboardView) mHostActivity.findViewById(viewid);
    mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
    mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview
                                            // balloons
    mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
    // Hide the standard keyboard initially
    mHostActivity.getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

/** Returns whether the CustomKeyboard is visible. */
public boolean isCustomKeyboardVisible() {
    return mKeyboardView.getVisibility() == View.VISIBLE;
}

/**
 * Make the CustomKeyboard visible, and hide the system keyboard for view v.
 */
public void showCustomKeyboard(View v) {
    mKeyboardView.setVisibility(View.VISIBLE);
    mKeyboardView.setEnabled(true);
    if (v != null)
        ((InputMethodManager) mHostActivity
                .getSystemService(Activity.INPUT_METHOD_SERVICE))
                .hideSoftInputFromWindow(v.getWindowToken(), 0);
}

/** Make the CustomKeyboard invisible. */
public void hideCustomKeyboard() {
    mKeyboardView.setVisibility(View.GONE);
    mKeyboardView.setEnabled(false);
}

/**
 * Register <var>EditText<var> with resource id <var>resid</var> (on the
 * hosting activity) for using this custom keyboard.
 * 
 * @param resid
 *            The resource id of the EditText that registers to the custom
 *            keyboard.
 */
public void registerEditText(int resid) {
    // Find the EditText 'resid'
    EditText edittext = (EditText) mHostActivity.findViewById(resid);
    // Make the custom keyboard appear
    edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
        // NOTE By setting the on focus listener, we can show the custom
        // keyboard when the edit box gets focus, but also hide it when the
        // edit box loses focus
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus)
                showCustomKeyboard(v);
            else
                hideCustomKeyboard();
        }
    });
    edittext.setOnClickListener(new OnClickListener() {
        // NOTE By setting the on click listener, we can show the custom
        // keyboard again, by tapping on an edit box that already had focus
        // (but that had the keyboard hidden).
        @Override
        public void onClick(View v) {
            showCustomKeyboard(v);
        }
    });
    // Disable standard keyboard hard way
    // NOTE There is also an easy way:
    // 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a
    // cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
    edittext.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            EditText edittext = (EditText) v;
            int inType = edittext.getInputType(); // Backup the input type
            edittext.setInputType(InputType.TYPE_NULL); // Disable standard
                                                        // keyboard
            edittext.onTouchEvent(event); // Call native handler
            edittext.setInputType(inType); // Restore input type
            return true; // Consume touch event
        }
    });
    // Disable spell check (hex strings look like words to Android)
    edittext.setInputType(edittext.getInputType()
            | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}

}

// NOTE How can we change the background color of some keys (like the
// shift/ctrl/alt)?
// NOTE What does android:keyEdgeFlags do/mean
SerCna
fonte
2
Mais explicações sobre isso: fampennings.nl/maarten/android/09keyboard/index.htm
TWiStErRob