Android Open Source - HexaKey Hexa Key






From Project

Back to project page HexaKey.

License

The source code is released under:

Apache License

If you think the Android project HexaKey listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2008-2009 The Android Open Source Project
 */*from  w  w  w .j ava 2s  . c  o  m*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package es.csc.android.hexakey;

import android.annotation.TargetApi;
import android.app.Dialog;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.os.Build;
import android.os.IBinder;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;

import java.util.List;

import es.csc.android.hexakey.R;

public class HexaKey extends InputMethodService 
        implements KeyboardView.OnKeyboardActionListener {
    static final boolean DEBUG = false;

    private InputMethodManager inputMethodManager;

    private LatinKeyboardView inputView;
    
    private int lastDisplayWidth;
    private boolean isRotation;
    private boolean wasShiftedBeforeRotation;
    
    private LatinKeyboardSet keyboardSet;
    
    private String wordSeparators;
    
    /**
     * Main initialization of the input method component.  Be sure to call
     * to super class.
     */
    @Override 
    public void onCreate() {
        super.onCreate();
        inputMethodManager = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
        wordSeparators = getResources().getString(R.string.word_separators);
    }
    
    /**
     * This is the point where you can do all of your UI initialization.  It
     * is called after creation and any configuration change.
     */
    @Override 
    public void onInitializeInterface() {
        if (keyboardSet == null) {
            final InputMethodSubtype subtype = inputMethodManager.getCurrentInputMethodSubtype();
          keyboardSet = new LatinKeyboardSet(this, subtype);
        }
        else if (isScreenSizeChange()) {
          keyboardSet.recreateKeyboards();
        }
        
        lastDisplayWidth = getMaxWidth();
    }
    
    private boolean isScreenSizeChange() {
      return getMaxWidth() != lastDisplayWidth;
    }    

    /**
     * This is the main point where we do our initialization of the input method
     * to begin operating on an application.  At this point we have been
     * bound to the client, and are now receiving all of the detailed information
     * about the target of our edits.
     */
    @Override 
    public void onStartInput(EditorInfo attribute, boolean restarting) {
        super.onStartInput(attribute, restarting);
        
        isRotation = restarting;
        wasShiftedBeforeRotation = inputView == null? false : inputView.isShifted();
        
        if (inputView != null && !keyboardSet.isKeyboardType(attribute)) {
          inputView.clearBackground();
        }
        
        if (!restarting) {
          keyboardSet.updateKeyboardType(attribute);                  
        }
                
        keyboardSet.setImeOptions(getResources(), attribute.imeOptions);
    }
    
    /**
     * Called by the framework when your view for creating input needs to
     * be generated.  This will be called the first time your input method
     * is displayed, and every time it needs to be re-created such as due to
     * a configuration change.
     */
    @Override 
    public View onCreateInputView() {        
        inputView = (LatinKeyboardView) getLayoutInflater()
                .inflate(R.layout.input, null);
        inputView.autoAdjustPadding(getMaxWidth());
        inputView.setOnKeyboardActionListener(this);
        
        return inputView;
    }
    
    /**
     * Called by the framework when your view for showing candidates needs to
     * be generated, like {@link #onCreateInputView}.
     */
    @Override 
    public View onCreateCandidatesView() {
       return null;
    }    
    
    @Override 
    public void onStartInputView(EditorInfo attribute, boolean restarting) {
        super.onStartInputView(attribute, restarting);
        
        setLatinKeyboard(keyboardSet.getCurrentKeyboard());
        inputView.closing();
        
        if (isRotation) {
          inputView.setShifted(wasShiftedBeforeRotation);
        }
        else {
          updateCapsLockState(attribute);
        }
        
        final InputMethodSubtype subtype = inputMethodManager.getCurrentInputMethodSubtype();
        inputView.setSubtypeOnSpaceKey(subtype);
    }
    
    @TargetApi(Build.VERSION_CODES.KITKAT) 
    private void setLatinKeyboard(LatinKeyboard nextKeyboard) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
          final boolean shouldSupportLanguageSwitchKey =
                  inputMethodManager.shouldOfferSwitchingToNextInputMethod(getToken());
          nextKeyboard.setLanguageSwitchKeyVisibility(shouldSupportLanguageSwitchKey);
      }
        inputView.setKeyboard(nextKeyboard);
    }

    @Override
    public void onFinishInputView (boolean finishingInput) {
      isRotation = false;
        keyboardSet.resetStatus();
        inputView.setShifted(false);
        super.onFinishInputView(finishingInput);
    }

    /**
     * This is called when the user is done editing a field.  We can use
     * this to reset our state.
     */
    @Override 
    public void onFinishInput() {
        super.onFinishInput();
        
        if (inputView != null) {
            inputView.closing();
        }
    }
    
    @Override
    public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
        inputView.setSubtypeOnSpaceKey(subtype);
    }

    /**
     * Deal with the editor reporting movement of its cursor.
     */
    @Override 
    public void onUpdateSelection(int oldSelStart, int oldSelEnd,
            int newSelStart, int newSelEnd,
            int candidatesStart, int candidatesEnd) {
        super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
                candidatesStart, candidatesEnd);
    }
    
    /**
     * Use this to monitor key events being delivered to the application.
     * We get first crack at them, and can either resume them or let them
     * continue to the app.
     */
    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                // The InputMethodService already takes care of the back
                // key for us, to dismiss the input method if it is shown.
                // However, our keyboard could be showing a pop-up window
                // that back should dismiss, so we first allow it to do that.
                if (event.getRepeatCount() == 0 && inputView != null) {
                    if (inputView.handleBack()) {
                        return true;
                    }
                }
                break;
                
            case KeyEvent.KEYCODE_DEL:
                break;
                
            case KeyEvent.KEYCODE_ENTER:
                // Let the underlying text editor always handle these.
                return false;                
        }
        
        return super.onKeyDown(keyCode, event);
    }

    private void updateCapsLockState(EditorInfo attr) {
        if (attr != null && inputView != null 
            && keyboardSet.isKeyboardType(LatinKeyboardSet.LETTERS_KEYBOARD)) {
            inputView.setShifted( keyboardSet.isCapsLockEnabled() || isFirstCapitalLetter(attr) );            
        }
    }

  private boolean isFirstCapitalLetter(EditorInfo attr) {
    boolean firstLetterAndCapital = false;
    
    EditorInfo ei = getCurrentInputEditorInfo();
    if (ei != null && ei.inputType != InputType.TYPE_NULL) {
      // For some weird reason, sometimes the result is false in the first call and true in the second...
        firstLetterAndCapital = getCurrentInputConnection().getCursorCapsMode(attr.inputType) != 0
                    || getCurrentInputConnection().getCursorCapsMode(attr.inputType) != 0;     
    }
    return firstLetterAndCapital;
  }
    
    /**
     * Helper to send a key down / key up pair to the current editor.
     */
    private void keyDownUp(int keyEventCode) {
        getCurrentInputConnection().sendKeyEvent(
                new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
        getCurrentInputConnection().sendKeyEvent(
                new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
    }
    
    /**
     * Helper to send a character to the editor as raw key events.
     */
    private void sendKey(int keyCode) {
        switch (keyCode) {
            case '\n':
                keyDownUp(KeyEvent.KEYCODE_ENTER);
                break;
            default:
                if (keyCode >= '0' && keyCode <= '9') {
                    keyDownUp(keyCode - '0' + KeyEvent.KEYCODE_0);
                } else {
                    getCurrentInputConnection().commitText(String.valueOf((char) keyCode), 1);
                }
                break;
        }
    }

    // Implementation of KeyboardViewListener

    public void onKey(int primaryCode, int[] keyCodes) {
        if (isWordSeparator(primaryCode)) {
            sendKey(primaryCode);
            updateCapsLockState(getCurrentInputEditorInfo());
        } 
        else if (primaryCode == Keyboard.KEYCODE_DELETE) {
            handleBackspace();
        } 
        else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
            handleShift();
        } 
        else if (primaryCode == LatinKeyboard.KEYCODE_LANGUAGE_SWITCH) {
            handleLanguageSwitch();
            return;
        } 
        else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) {
            // Show a menu or somethin'
        } 
        else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
                && inputView != null) {
          keyboardSet.changeKeyboardMode();
          setLatinKeyboard(keyboardSet.getCurrentKeyboard());
        } 
        else {
            handleCharacter(primaryCode, keyCodes);
        }
    }

    public void onText(CharSequence text) {
        InputConnection ic = getCurrentInputConnection();
        if (ic == null) return;
        ic.beginBatchEdit();
        ic.commitText(text, 0);
        ic.endBatchEdit();
        updateCapsLockState(getCurrentInputEditorInfo());
    }
    
    public void setSuggestions(List<String> suggestions, boolean completions,
            boolean typedWordValid) {
        if (suggestions != null && suggestions.size() > 0) {
            setCandidatesViewShown(true);
        } else if (isExtractViewShown()) {
            setCandidatesViewShown(true);
        }
    }
    
    private void handleBackspace() {
        keyDownUp(KeyEvent.KEYCODE_DEL);
        updateCapsLockState(getCurrentInputEditorInfo());
    }

    private void handleShift() {
        if (inputView == null) {
            return;
        }
        
        LatinKeyboard preShifted = keyboardSet.getCurrentKeyboard();
        keyboardSet.handleShift();
        if (preShifted == keyboardSet.getCurrentKeyboard()) {
          inputView.setShifted( keyboardSet.isCapsLockEnabled() || !inputView.isShifted() );          
        }    
        else {
          setLatinKeyboard(keyboardSet.getCurrentKeyboard());
        }
    }
    
     private void handleCharacter(int primaryCode, int[] keyCodes) {
        if (isInputViewShown()) {
            if (inputView.isShifted()) {
                primaryCode = Character.toUpperCase(primaryCode);
            }
        }
                        
        getCurrentInputConnection().commitText(
                    String.valueOf((char) primaryCode), 1);
        
        if (isAlphabet(primaryCode)) {            
          updateCapsLockState(getCurrentInputEditorInfo());
        }
    }
    
    private boolean isAlphabet(int code) {
        if (Character.isLetter(code)) {
            return true;
        } else {
            return false;
        }
    }

    private void handleClose() {
        requestHideSelf(0);
        inputView.closing();
    }

    private IBinder getToken() {
        final Dialog dialog = getWindow();
        if (dialog == null) {
            return null;
        }
        final Window window = dialog.getWindow();
        if (window == null) {
            return null;
        }
        return window.getAttributes().token;
    }

    private void handleLanguageSwitch() {
        final InputMethodSubtype previousSubtype = inputMethodManager.getCurrentInputMethodSubtype();
        inputMethodManager.switchToNextInputMethod(getToken(), true);
        final InputMethodSubtype newSubtype = inputMethodManager.getCurrentInputMethodSubtype();
        
        if (previousSubtype != newSubtype) {          
          keyboardSet = new LatinKeyboardSet(this, newSubtype);
          setLatinKeyboard(keyboardSet.getCurrentKeyboard());
        }
    }
    
    private String getWordSeparators() {
        return wordSeparators;
    }
    
    public boolean isWordSeparator(int code) {
        String separators = getWordSeparators();
        return separators.contains(String.valueOf((char)code));
    }

    public void swipeRight() {
    }
    
    public void swipeLeft() {
        handleBackspace();
    }

    public void swipeDown() {
        handleClose();
    }

    public void swipeUp() {
    }
    
    public void onPress(int primaryCode) {
    }
    
    public void onRelease(int primaryCode) {
    }
}




Java Source Code List

es.csc.android.hexakey.HexaKey.java
es.csc.android.hexakey.ImePreferences.java
es.csc.android.hexakey.LatinKeyboardSet.java
es.csc.android.hexakey.LatinKeyboardView.java
es.csc.android.hexakey.LatinKeyboard.java
es.csc.android.hexakey.LetterRecourcesCache.java
es.csc.android.hexakey.inputmethodcommon.InputMethodSettingsFragment.java
es.csc.android.hexakey.inputmethodcommon.InputMethodSettingsImpl.java
es.csc.android.hexakey.inputmethodcommon.InputMethodSettingsInterface.java