Bluetooth Keyboard malfunction and customizing terminal-ide

My bluetooth Logitech tablet keyboard is partially malfunctioning. Sometimes, some of the keys when pressed are not converted to keycode.

The keys that are malfunctioning: 1, 4, r, g, l, z, ], del (backspace)

In Terminal-ide, the "External Keyboard Mappings" options allow one to map a keycode value of another key to the backspace key. However, it does not provide any options to map another keycode to the normal keys (the number, the alphabet, and the symbols).

I have modified the Terminal-ide codes to allow mapping other keycodes to the normal keys.
Modification to TermIDE/src/com/spartacusrex/spartacuside/util/hardkeymappings.java is done to provide the options to map another keycode to the normal keys.

A new preference hardmap_normal is added to the application default shared preferences. Edit the preference file com.spartacusrex.spartacuside_preferences.xml and add the hardmap_normal preference as follows for example.

1     <string name="hardmap_normal">129:1,88:4,85:r,87:g,164:l,118:z,25:]</string>
2

The value contains the mappings (from keycode to character) concatenated by comma.
In the example, keycode 129 is mapped to character 1, keycode 88 is mapped to character 4 and so on.

In the below code, these mappings are stored in the variable mCharMap by the function initCharMappings. The checkKeyCode function is modified to check whether a keycode is one of these mappings and if it is, it will return the mapped character code value. Otherwise, it proceeds as before, returning the index of the originally supported HARDKEY with a matching keycode.

  1     /*
2 * hardkeymappings.java
3 *
4 */
5
6 package com.spartacusrex.spartacuside.util;
7
8 import android.content.SharedPreferences;
9 import android.preference.EditTextPreference;
10
11 import java.util.HashMap;
12
13
14 /**
15 *
16 * @author Spartacus Rex
17 */
18 public class hardkeymappings {
19
20 public int TOTAL_HARDMAP_NUMBER = 21;
21
22 public static final int HARDKEY_CTRL_LEFT = 0;
23 public static final int HARDKEY_CTRL_RIGHT = 1;
24 public static final int HARDKEY_ALT_LEFT = 2;
25 public static final int HARDKEY_ALT_RIGHT = 3;
26 public static final int HARDKEY_ESCAPE = 4;
27 public static final int HARDKEY_FUNCTION = 5;
28
29 public static final int HARDKEY_TAB = 6;
30 public static final int HARDKEY_LSHIFT = 7;
31 public static final int HARDKEY_RSHIFT = 8;
32 public static final int HARDKEY_SPACE = 9;
33 public static final int HARDKEY_ENTER = 10;
34 public static final int HARDKEY_DELETE = 11;
35 public static final int HARDKEY_BACKSPACE = 12;
36
37 public static final int HARDKEY_UP = 13;
38 public static final int HARDKEY_DOWN = 14;
39 public static final int HARDKEY_LEFT = 15;
40 public static final int HARDKEY_RIGHT = 16;
41
42 public static final int HARDKEY_PGUP = 17;
43 public static final int HARDKEY_PGDOWN = 18;
44 public static final int HARDKEY_HOME = 19;
45 public static final int HARDKEY_END = 20;
46
47 // public static final int HARDKEY_EXCLAMATION = 21;
48 // public static final int HARDKEY_AMPERSAND = 22;
49 // public static final int HARDKEY_HASH = 23;
50 // public static final int HARDKEY_DOLLAR = 24;
51 // public static final int HARDKEY_PERCENT = 25;
52
53 int[] mKeyMappings;
54 boolean mEnabled = false;
55
56 SharedPreferences mPrefs;
57
58 // sky: allow normal char mappings
59 HashMap mCharMap = new HashMap();
60
61
62 private int getStringPref(SharedPreferences zPrefs, String zKey, String zDefault){
63 int ival = -1;
64 try {
65 String value = zPrefs.getString(zKey, zDefault);
66 ival = Integer.parseInt(value);
67 } catch (NumberFormatException numberFormatException) {
68 return -1;
69 }
70 return ival;
71 }
72
73 public hardkeymappings(){
74 mKeyMappings = new int[TOTAL_HARDMAP_NUMBER];
75 for(int i=0;i<TOTAL_HARDMAP_NUMBER;i++){
76 mKeyMappings[i] = -1;
77 }
78 }
79
80 public boolean isEnabled(){
81 return mEnabled;
82 }
83
84 public void resetAllMappings(){
85 SharedPreferences.Editor editor = mPrefs.edit();
86
87 editor.putString("hardmap_ctrlLeft", "-1");
88 editor.putString("hardmap_ctrlRight", "-1");
89 editor.putString("hardmap_altLeft", "-1");
90 editor.putString("hardmap_altRight", "-1");
91 editor.putString("hardmap_escape", "-1");
92 editor.putString("hardmap_function", "-1");
93
94 editor.putString("hardmap_tab", "-1");
95 editor.putString("hardmap_leftshift", "-1");
96 editor.putString("hardmap_rightshift", "-1");
97 editor.putString("hardmap_space", "-1");
98 editor.putString("hardmap_enter", "-1");
99 editor.putString("hardmap_delete", "-1");
100 editor.putString("hardmap_backspace", "-1");
101
102 editor.putString("hardmap_up", "-1");
103 editor.putString("hardmap_down", "-1");
104 editor.putString("hardmap_left", "-1");
105 editor.putString("hardmap_right", "-1");
106
107 editor.putString("hardmap_pageup", "-1");
108 editor.putString("hardmap_pagedown", "-1");
109 editor.putString("hardmap_home", "-1");
110 editor.putString("hardmap_end", "-1");
111
112 // sky: allow normal char mappings
113 editor.putString("hardmap_normal", "");
114 mCharMap.clear();
115
116 editor.commit();
117
118 //Now reset them
119 for(int i=0;i<TOTAL_HARDMAP_NUMBER;i++){
120 mKeyMappings[i] = -1;
121 }
122 }
123
124 public void setKeyMappings(SharedPreferences zPrefs){
125 mPrefs = zPrefs;
126
127 mEnabled = ( getStringPref(zPrefs, "hardmap_enable", "0") == 1 );
128
129 mKeyMappings[HARDKEY_CTRL_LEFT] = getStringPref(zPrefs,"hardmap_ctrlLeft", "-1");
130 mKeyMappings[HARDKEY_CTRL_RIGHT] = getStringPref(zPrefs,"hardmap_ctrlRight", "-1");
131 mKeyMappings[HARDKEY_ALT_LEFT] = getStringPref(zPrefs,"hardmap_altLeft", "-1");
132 mKeyMappings[HARDKEY_ALT_RIGHT] = getStringPref(zPrefs,"hardmap_altRight", "-1");
133 mKeyMappings[HARDKEY_ESCAPE] = getStringPref(zPrefs,"hardmap_escape", "-1");
134 mKeyMappings[HARDKEY_FUNCTION] = getStringPref(zPrefs,"hardmap_function", "-1");
135
136 mKeyMappings[HARDKEY_TAB] = getStringPref(zPrefs,"hardmap_tab", "-1");
137 mKeyMappings[HARDKEY_LSHIFT] = getStringPref(zPrefs,"hardmap_leftshift", "-1");
138 mKeyMappings[HARDKEY_RSHIFT] = getStringPref(zPrefs,"hardmap_rightshift", "-1");
139 mKeyMappings[HARDKEY_SPACE] = getStringPref(zPrefs,"hardmap_space", "-1");
140 mKeyMappings[HARDKEY_ENTER] = getStringPref(zPrefs,"hardmap_enter", "-1");
141 mKeyMappings[HARDKEY_DELETE] = getStringPref(zPrefs,"hardmap_delete", "-1");
142 mKeyMappings[HARDKEY_BACKSPACE] = getStringPref(zPrefs,"hardmap_backspace", "-1");
143
144 mKeyMappings[HARDKEY_UP] = getStringPref(zPrefs,"hardmap_up", "-1");
145 mKeyMappings[HARDKEY_DOWN] = getStringPref(zPrefs,"hardmap_down", "-1");
146 mKeyMappings[HARDKEY_LEFT] = getStringPref(zPrefs,"hardmap_left", "-1");
147 mKeyMappings[HARDKEY_RIGHT] = getStringPref(zPrefs,"hardmap_right", "-1");
148
149 mKeyMappings[HARDKEY_PGUP] = getStringPref(zPrefs,"hardmap_pageup", "-1");
150 mKeyMappings[HARDKEY_PGDOWN] = getStringPref(zPrefs,"hardmap_pagedown", "-1");
151 mKeyMappings[HARDKEY_HOME] = getStringPref(zPrefs,"hardmap_home", "-1");
152 mKeyMappings[HARDKEY_END] = getStringPref(zPrefs,"hardmap_end", "-1");
153
154 // sky: allow normal char mappings
155 String value = zPrefs.getString("hardmap_normal", null);
156 initCharMappings(value);
157 }
158
159 public int checkKeyCode(int zKeyCode){
160 // sky: allow normal char mappings
161 Integer c = (Integer) mCharMap.get(zKeyCode);
162 if (c != null)
163 return c.intValue();
164
165 //Cycle through and check
166 for(int i=0;i<TOTAL_HARDMAP_NUMBER;i++){
167 if(mKeyMappings[i] == zKeyCode){
168 return i;
169 }
170 }
171
172 return -1;
173 }
174
175 // sky: allow normal char mappings (keycode:char)
176 // 29:a,30:b,
177 private void initCharMappings(String desc) {
178 if ((desc == null) || desc.isEmpty())
179 return;
180 String[] pairs = desc.split(",");
181 String[] codeChar;
182 int code;
183 int c;
184 for (int i = 0; i < pairs.length; i++) {
185 codeChar = pairs[i].split(":");
186 if (codeChar.length != 2)
187 continue;
188 try {
189 code = Integer.parseInt(codeChar[0]);
190 } catch (NumberFormatException numberFormatException) {
191 continue;
192 }
193 c = Character.codePointAt(codeChar[1], 0);
194 // accept if c > ' '
195 if (c > 32)
196 mCharMap.put(code, c);
197 }
198 }
199
200 }
201

Modification to TermIDE/src/com/spartacusrex/spartacuside/EmulatorView.java is done to provide the functional behavior of actually changing the original keycode the user is typing to the keycode representing the mapped character (defined in the preference hardmap_normal).

Only the handleKeyCodeMapper function is being modified here. It checks that if the returned value of TermService.isSpecialKeyCode is greater than 32, then the mapping is treated as the mapping of keycode to a normal character, and proceed to replace the typed keycode with the keycode representing the mapped character. Otherwise, it proceeds as before.

 1     // sky: allow normal char mappings (keycode:char)
2 private final KeyCharacterMap keyCharMap = KeyCharacterMap.load(
3 KeyCharacterMap.VIRTUAL_KEYBOARD);
4
5
6 private KeyEvent handleKeyCodeMapper(int zAction, int zKeyCode){
7 //Check with HardKey Mappings..!
8 KeyEvent newevent = new KeyEvent(zAction, zKeyCode);
9
10 if(TermService.isHardKeyEnabled()){
11 int hardmap = TermService.isSpecialKeyCode(zKeyCode);
12
13 //Valid.. ?
14 if(hardmap != -1){
15 // sky: allow normal char mappings (keycode:char)
16 if (hardmap > 32) {
17 // convert char to keycode
18 char[] chars = { '\0' };
19 Character.toChars(hardmap, chars, 0);
20 KeyEvent[] keyEvents = keyCharMap.getEvents(chars);
21 if (keyEvents != null) {
22 newevent = new KeyEvent(zAction, keyEvents[0].getKeyCode());
23 }
24 return newevent;
25 }
26 //Its a special key code..
27 if(hardmap == hardkeymappings.HARDKEY_CTRL_LEFT || hardmap == hardkeymappings.HARDKEY_CTRL_RIGHT){
28 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_CTRL_LEFT);
29
30 }else if(hardmap == hardkeymappings.HARDKEY_ALT_LEFT || hardmap == hardkeymappings.HARDKEY_ALT_RIGHT){
31 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_ALT_LEFT);
32
33 }else if(hardmap == hardkeymappings.HARDKEY_ESCAPE){
34 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_ESCAPE);
35
36 }else if(hardmap == hardkeymappings.HARDKEY_FUNCTION){
37 //Just Update the Function Key Settings
38 mKeyListener.handleFunctionKey(false);
39 return null;
40
41 }else if(hardmap == hardkeymappings.HARDKEY_TAB){
42 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_TAB);
43
44 }else if(hardmap == hardkeymappings.HARDKEY_LSHIFT || hardmap == hardkeymappings.HARDKEY_RSHIFT){
45 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_SHIFT_LEFT);
46
47 }else if(hardmap == hardkeymappings.HARDKEY_SPACE){
48 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_SPACE);
49
50 }else if(hardmap == hardkeymappings.HARDKEY_ENTER){
51 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_ENTER);
52
53 }else if(hardmap == hardkeymappings.HARDKEY_DELETE){
54 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_FORWARD_DEL);
55
56 }else if(hardmap == hardkeymappings.HARDKEY_BACKSPACE){
57 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_DEL);
58
59 }else if(hardmap == hardkeymappings.HARDKEY_UP){
60 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_DPAD_UP);
61
62 }else if(hardmap == hardkeymappings.HARDKEY_DOWN){
63 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_DPAD_DOWN);
64
65 }else if(hardmap == hardkeymappings.HARDKEY_LEFT){
66 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_DPAD_LEFT);
67
68 }else if(hardmap == hardkeymappings.HARDKEY_RIGHT){
69 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_DPAD_RIGHT);
70
71 }else if(hardmap == hardkeymappings.HARDKEY_PGUP){
72 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_PAGE_UP);
73
74 }else if(hardmap == hardkeymappings.HARDKEY_PGDOWN){
75 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_PAGE_DOWN);
76
77 }else if(hardmap == hardkeymappings.HARDKEY_HOME){
78 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_MOVE_HOME);
79
80 }else if(hardmap == hardkeymappings.HARDKEY_END){
81 newevent = new KeyEvent(zAction, TermKeyListener.KEYCODE_MOVE_END);
82 }
83 }
84 }
85
86 return newevent;
87 }
88
89

I use the dex2jar tool to just compile the 2 modified java files and repack the apk file.

1     $ d2j-dex2jar.sh -f -o com.spartacusrex.spartacuside-dex2jar.jar com.spartacusrex.spartacuside-1.apk
2 $ unzip com.spartacusrex.spartacuside-dex2jar.jar
3 # compile the java files, replacing the original class files.
4 $ jar cvf TermIDE.jar .
5 $ d2j-jar2dex.sh -f -o classes.dex TermIDE.jar
6 $ cp com.spartacusrex.spartacuside-1.apk TermIDE.apk
7 $ zip -r TermIDE.apk classes.dex
8

After the apk file TermIDE.apk is updated, we need to sign the apk file. Then, we need to uninstall the original Terminal-ide, before installing with the new apk file.

Related:
Android terminal-ide and Bluetooth Keyboard

Comments

blog comments powered by Disqus