Cordova Plugin - Keyboard Events Android
<p>I'm spinning my wheels trying to create a plugin for Cordova on Android that can intercept hardware keyboard events, and feed them to a Javascript listener. I've created other plugins before but I am struggling with this one as I'm not particularly strong in Java to begin with. Everything in the code snippet below compiles fine but nothing comes out on the Javascript side. Any and all help on this one is appreciated!</p>

<p><strong>Update:</strong>
After some more research it looks like key events are disabled in later versions of Android by default. This is due to some BS excuse about better user experience with so many different input devices and methods. The post <a href="https://stackoverflow.com/questions/11429878/read-keyboard-events-in-android-webview">here</a> seems to offer the solution if you're building the app from scratch, but not for Cordova. <a href="https://stackoverflow.com/questions/16499178/cant-get-backspace-to-work-in-codemirror-under-phonegap-on-android-4-x">This post</a> has something that could work for Cordova but it seems to invasive for a plugin. I'd like to override some of the methods in the CordovaWebView but I'd rather not reinitialize it. It's common practice in Javascript; does anyone know how to do it in Java for Android?</p>

<p>KeyboardPlugin.java</p>

<pre><code>package com.otb.cordova.keyboard;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.KeyEvent;
import android.view.*;

public class KeyboardPlugin extends CordovaPlugin implements OnKeyListener{
    private CallbackContext keyup_callback = null;
    private CallbackContext keydown_callback = null;

    @Override
    public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {

        if (action.equalsIgnoreCase("keyUp")) {
            keyup_callback = callbackContext;
        }
        else if(action.equalsIgnoreCase("stopKeyUp")){
            keyup_callback = null;
        }
        else if(action.equalsIgnoreCase("keyDown")){
            keydown_callback = callbackContext;
        }
        else if(action.equalsIgnoreCase("stopKeyDown")){
            keydown_callback = null;
        }
        else {
            // invalid action
            return false;
        }

        PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
        result.setKeepCallback(true);
        callbackContext.sendPluginResult(result);

        return true;
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP) {
            KeyUp(keyCode, event);
        }
        else if (event.getAction() == KeyEvent.ACTION_DOWN) {
            KeyDown(keyCode, event);
        }
        return false;
    }

    private boolean KeyDown(int keyCode, KeyEvent event){
        if(keydown_callback == null){
            return true;
        }
        PluginResult result = new PluginResult(PluginResult.Status.OK, Integer.toString(keyCode));
        result.setKeepCallback(true);
        keydown_callback.sendPluginResult(result);
        return false;
    }

    private boolean KeyUp(int keyCode, KeyEvent event){
        if(keyup_callback == null){
            return true;
        }
        PluginResult result = new PluginResult(PluginResult.Status.OK, Integer.toString(keyCode));
        result.setKeepCallback(true);
        keyup_callback.sendPluginResult(result);
        return false;
    }
}
</code></pre>

<p>plugin.js</p>

<pre><code>    Plugin.keyboardPlugin = {
  onKeyUp: function(callback, onFail){
    cordova.exec(callback, onFail, 'KeyboardPlugin', 'keyUp', []);
  },

  onKeyDown: function(callback, onFail){
    cordova.exec(callback, onFail, 'KeyboardPlugin', 'keyDown', []);
  },

  stopKeyUp: function(callback, onFail){
    cordova.exec(callback, onFail, 'KeyboardPlugin', 'stopKeyUp', []);
  },

  stopKeyDown: function(callback, onFail){
    cordova.exec(callback, onFail, 'KeyboardPlugin', 'stopKeyDown', []);
  }
};
</code></pre>

<p>plugin.xml</p>

<pre><code>    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
        xmlns:android="http://schemas.android.com/apk/res/android"
        id="cordova-plugin-keyboard"
        version="0.0.1"&gt;
    &lt;name&gt;Keyboard Plugin&lt;/name&gt;
    &lt;description&gt;This is a project to read key strokes from Cordova on Android.&lt;/description&gt;
    &lt;license&gt;Apache 2.0&lt;/license&gt;
    &lt;keywords&gt;cordova,plugin,keyboard&lt;/keywords&gt;
    &lt;repo&gt;https://github.com/mircerlancerous/cordova-plugin-keyboard&lt;/repo&gt;
    &lt;issue&gt;https://github.com/mircerlancerous/cordova-plugin-keyboard/issues&lt;/issue&gt;

    &lt;engines&gt;
        &lt;engine name="cordova-android" version="&gt;=3.6.0" /&gt;&lt;!-- Requires CordovaPlugin.preferences --&gt;
    &lt;/engines&gt;


    &lt;js-module src="www/plugin.js" name="keyboardPlugin"&gt;
        &lt;runs/&gt;
    &lt;/js-module&gt;

    &lt;platform name="android"&gt;
        &lt;config-file target="res/xml/config.xml" parent="/*"&gt;
            &lt;feature name="KeyboardPlugin" &gt;
                &lt;param name="android-package" value="com.otb.cordova.keyboard.KeyboardPlugin"/&gt;
                &lt;param name="onload" value="true" /&gt;
            &lt;/feature&gt;
        &lt;/config-file&gt;

        &lt;source-file src="src/android/KeyboardPlugin.java" target-dir="src/com/otb/cordova/keyboard"/&gt;
    &lt;/platform&gt;

&lt;/plugin&gt;
</code></pre>

<p>Here's the link to the github repository.
<a href="https://github.com/mircerlancerous/cordova-plugin-keyboard/" rel="nofollow noreferrer">https://github.com/mircerlancerous/cordova-plugin-keyboard/</a></p>