Naruto
Naruto

Reputation: 73

numeric soft keyboard in android using ndk

I have a java code that displays the numeric soft keyboard in Android:

public class MainActivity extends Activity {
    EditText ed1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ed1 = (EditText) findViewById(R.id.editText1);
        ed1.setInputType(InputType.TYPE_CLASS_NUMBER);
    }
}

My activity_main.xml file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="numberkeypad.inputmethod.MainActivity" >

<EditText
    android:id="@+id/editText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:ems="10" >
</EditText>

The output is: numeric soft keyboard

enter image description here

I want to display the same keyboard using NDK JNI call and no EditText. I have implemented the default keyboard in this way using the following link:

How to show the soft keyboard on native activity

But I am facing a lot of trouble using the same methodology for the numeric keyboard. Any help would be great..Thanks!

Upvotes: 1

Views: 558

Answers (1)

Naruto
Naruto

Reputation: 73

Could not find a way to do this directly, had to override the onCreateInputConnection method of View class, and then make a JNI call to a function using the overridden method.

public class NumbersView extends View {
    public NumbersView(Context context) {
        super(context);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection inputConnection =  super.onCreateInputConnection(outAttrs);
        switch(SystemKeyboardType){
            case InputType.TYPE_CLASS_PHONE:
                outAttrs.inputType |= InputType.TYPE_CLASS_PHONE;
                break;
            case InputType.TYPE_CLASS_TEXT:
                outAttrs.inputType |= InputType.TYPE_CLASS_TEXT;
                break;
            case InputType.TYPE_CLASS_NUMBER:
                outAttrs.inputType |= InputType.TYPE_CLASS_NUMBER;
                break;
            case InputType.TYPE_CLASS_DATETIME:
                outAttrs.inputType |= InputType.TYPE_CLASS_DATETIME;
                break;
            default:
                outAttrs.inputType |= InputType.TYPE_CLASS_TEXT;
                break;
        }

        return inputConnection;
    }
}

 **/
@Override
protected void onCreate(Bundle savedInstanceState) {
    calculateDeviceDPI();
    super.onCreate(savedInstanceState);
    myView = new NumbersView(getApplicationContext());
    addContentView(myView,new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
    myView.setFocusable(true);
    myView.setFocusableInTouchMode(true);
    //myView.requestFocus();

    mContext = this;
}

public void displaySystemKeyboard(String keyboardType){
    if(keyboardType.equals("text")) {
        SystemKeyboardType = InputType.TYPE_CLASS_TEXT;
    }
    else if(keyboardType.equals("phone")) {
        SystemKeyboardType = InputType.TYPE_CLASS_PHONE;
    }
    else if(keyboardType.equals("number")) {
        SystemKeyboardType = InputType.TYPE_CLASS_NUMBER;
    }
    else if(keyboardType.equals("datetime")) {
        SystemKeyboardType = InputType.TYPE_CLASS_DATETIME;
    }
    else {
        SystemKeyboardType = InputType.TYPE_CLASS_DATETIME;
    }


    Context ctx = getApplicationContext();

    InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);

    myView.requestFocus();
    // only will trigger it if no physical keyboard is open
    mgr.restartInput(myView);
    mgr.showSoftInput(myView, 0);
}

public void hideSystemKeyboard(){
    Context ctx = getApplicationContext();
    View myView = this.getWindow().getDecorView();
    InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
    mgr.hideSoftInputFromWindow(myView.getWindowToken(), 0);
}

And finally made a JNI call to the function:

 if(pShow){
    jmethodID showSysKeys = lJNIEnv->GetMethodID(lClassDeviceAPI,"displaySystemKeyboard","(Ljava/lang/String;)V");
    if(showSysKeys == NULL){
         LOGI("displaySystemKeyboard::Couldn't get void displaySystemKeyboard Method");
         return;
    }

    jstring keyboardType = lJNIEnv->NewStringUTF(KeyboardType.c_str());
    if(!keyboardType)
    {
        LOGI( "failed to alloc param string in java." );
        return;
    };

    lJNIEnv->CallVoidMethod(lObjDeviceAPI,showSysKeys, keyboardType);
}
else{
    jmethodID hideSysKeys = lJNIEnv->GetMethodID(lClassDeviceAPI,"hideSystemKeyboard","()V");
    if(hideSysKeys == NULL){
         LOGI("hideSystemKeyboard::Couldn't get void hideSystemKeyboard Method");
         return;
    }

    lJNIEnv->CallVoidMethod(lObjDeviceAPI,hideSysKeys);
}

lJavaVM->DetachCurrentThread();

Upvotes: 2

Related Questions