コード例 #1
0
  /**
   * Moves <code>count</code> units in the specified direction using the current granularity and
   * action.
   *
   * @param count The number of units to move.
   * @param forward <code>true</code> to move <code>count</code> units forward, <code>false</code>
   *     to move backward.
   * @param isShiftPressed <code>true</code> if the shift key is pressed.
   * @return <code>true</code> if successful or <code>false</code> if no input connection was
   *     available or the movement failed
   */
  private boolean moveUnit(int granularity, int count, boolean forward, boolean isShiftPressed) {
    // If the input connection is null or count is 0, no-op.
    AccessibleInputConnection inputConnection = getCurrentInputConnection();
    if (inputConnection == null || !inputConnection.hasExtractedText()) {
      return false;
    } else if (count == 0) {
      return true;
    }

    // If the shift key is held down, force ACTION_EXTEND mode.
    int action = (isShiftPressed ? TextNavigation.ACTION_EXTEND : mAction);

    // Disable sending accessibility events while we send multiple events,
    // then announce only the last event.
    boolean savedSendAccessibilityEvents = inputConnection.isSendAccessibilityEvents();
    inputConnection.setSendAccessibilityEvents(false);
    for (int i = 0; i < count - 1; i++) {
      if (forward) {
        inputConnection.next(granularity, action);
      } else {
        inputConnection.previous(granularity, action);
      }
    }
    inputConnection.setSendAccessibilityEvents(savedSendAccessibilityEvents);

    // Obtain the new position from the final event. If the position is
    // null, we failed to move and should return false.
    Position newPosition = null;
    if (forward) {
      newPosition = inputConnection.next(granularity, action);
    } else {
      newPosition = inputConnection.previous(mGranularity, action);
    }
    return (newPosition != null);
  }
コード例 #2
0
  /**
   * Captures and stores directional pad events. If onKeyUp() preserves default behavior, the
   * original down event will be released.
   */
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (mUserCommandHandler.onKeyDown(event)) {
      return true;
    }

    AccessibleInputConnection aic = getCurrentInputConnection();
    if (aic == null || !aic.hasExtractedText()) {
      return super.onKeyDown(keyCode, event);
    }

    // If we've captured a meta key, capture all subsequent keys.
    if (mPreviousMetaDownEvent != null) {
      mPreviousDpadDownEvent = event;
      return true;
    }

    switch (event.getKeyCode()) {
      case KeyEvent.KEYCODE_DPAD_DOWN:
      case KeyEvent.KEYCODE_DPAD_UP:
      case KeyEvent.KEYCODE_DPAD_LEFT:
      case KeyEvent.KEYCODE_DPAD_RIGHT:
        mPreviousDpadDownEvent = event;
        return true;
      case KeyEvent.KEYCODE_ALT_LEFT:
      case KeyEvent.KEYCODE_ALT_RIGHT:
        {
          mAIC.trySendAccessiblityEvent(mAltString);
          mPreviousMetaDownEvent = event;
          return true;
        }
      case KeyEvent.KEYCODE_SHIFT_LEFT:
      case KeyEvent.KEYCODE_SHIFT_RIGHT:
        {
          mAIC.trySendAccessiblityEvent(mShiftString);
          mPreviousMetaDownEvent = event;
          return true;
        }
      default:
        return super.onKeyDown(keyCode, event);
    }
  }
コード例 #3
0
  /**
   * Sets action to be performed on the current selection.
   *
   * @param action Value could be either {@link TextNavigation#ACTION_MOVE} or {@link
   *     TextNavigation#ACTION_EXTEND}.
   */
  public boolean setAction(int action) {
    AccessibleInputConnection.checkValidAction(action);

    if (mAction == action) {
      return false;
    }

    mAction = action;
    String speak = String.format(mActionSet, mActionTypes[action]);
    getCurrentInputConnection().trySendAccessiblityEvent(speak);
    onActionChanged(action);
    return true;
  }
コード例 #4
0
  /**
   * Sets granularity (unit type) for text navigation.
   *
   * @param granularity Value could be {@link TextNavigation#GRANULARITY_CHAR} , {@link
   *     TextNavigation#GRANULARITY_WORD}, {@link TextNavigation#GRANULARITY_SENTENCE}, {@link
   *     TextNavigation#GRANULARITY_PARAGRAPH} or {@link TextNavigation#GRANULARITY_ENTIRE_TEXT}
   * @return <code>true</code> if granularity changed
   */
  public boolean setGranularity(int granularity) {
    AccessibleInputConnection.checkValidGranularity(granularity);
    String speak = String.format(mGranularitySet, mGranularityTypes[granularity]);
    getCurrentInputConnection().trySendAccessiblityEvent(speak);

    if (mGranularity == granularity) {
      return false;
    }

    mGranularity = granularity;
    onGranularityChanged(granularity);

    return true;
  }
コード例 #5
0
  @Override
  public void onUpdateSelection(
      int oldSelStart,
      int oldSelEnd,
      int newSelStart,
      int newSelEnd,
      int candidatesStart,
      int candidatesEnd) {
    super.onUpdateSelection(
        oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd);

    if (mWasUpDownPressed) {
      mWasUpDownPressed = false;

      android.util.Log.e("AIME", "updown was pressed, speaking");
      mAIC.speakCurrentUnit(mGranularity);
    }
  }
コード例 #6
0
  /**
   * Overrides default directional pad behavior:
   *
   * <ul>
   *   <li>Up/down: Increases/decreases text navigation granularity
   *   <li>Left/right: Moves to previous/next unit of text
   * </ul>
   *
   * <p>If one of the following conditions is met, default behavior is preserved:
   *
   * <ul>
   *   <li>No input connection available
   *   <li>Input view is hidden
   *   <li>Not currently editing text
   *   <li>Cannot move in the specified direction
   * </ul>
   */
  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (mUserCommandHandler.onKeyUp(event)) {
      return true;
    }

    final AccessibleInputConnection aic = getCurrentInputConnection();
    if (aic == null || !aic.hasExtractedText()) {
      return super.onKeyUp(keyCode, event);
    }

    final KeyEvent downEvent = mPreviousDpadDownEvent;
    mPreviousDpadDownEvent = null;

    final KeyEvent metaDownEvent = mPreviousMetaDownEvent;
    mPreviousMetaDownEvent = null;

    if (downEvent != null) {
      boolean captureEvent = false;

      switch (downEvent.getKeyCode()) {
        case KeyEvent.KEYCODE_DPAD_LEFT:
          if (!event.isAltPressed()) {
            captureEvent = previousUnit(mGranularity, 1, event.isShiftPressed());
          } else {
            mWasUpDownPressed = true;
          }
          break;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
          if (!event.isAltPressed()) {
            captureEvent = nextUnit(mGranularity, 1, event.isShiftPressed());
          } else {
            mWasUpDownPressed = true;
          }
          break;
        case KeyEvent.KEYCODE_DPAD_UP:
          if (event.isAltPressed()) {
            adjustGranularity(1);
            captureEvent = true;
          } else {
            mWasUpDownPressed = true;
          }
          break;
        case KeyEvent.KEYCODE_DPAD_DOWN:
          if (event.isAltPressed()) {
            adjustGranularity(-1);
            captureEvent = true;
          } else {
            mWasUpDownPressed = true;
          }
          break;
      }

      if (captureEvent) {
        return true;
      }
    }

    // If we didn't capture the meta event, attempt to send the previous
    // meta down event and then preserve default behavior.
    if (metaDownEvent != null) {
      if (!super.onKeyDown(metaDownEvent.getKeyCode(), metaDownEvent)) {
        aic.sendKeyEvent(metaDownEvent);
      }
    }

    // If we didn't capture the event, attempt to send the previous down
    // event and then preserve default behavior.
    if (downEvent != null) {
      if (!super.onKeyDown(downEvent.getKeyCode(), downEvent)) {
        aic.sendKeyEvent(downEvent);
      }
    }

    if (!super.onKeyUp(keyCode, event)) {
      aic.sendKeyEvent(event);
    }

    return true;
  }