亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在安卓設備上制作 KeyDown 和 KeyUp?

如何在安卓設備上制作 KeyDown 和 KeyUp?

墨色風雨 2022-05-21 20:18:06
我有個問題。我正在Android 設備上制作Keystroke 動態應用程序?,F在,我用度量字符串和EditText. 我想在軟件鍵盤上捕捉KeyDown和KeyUp事件。我的問題是,使用 Java 在 Android 上捕獲KeyUp和使用的最佳方法是什么?KeyDown如果EditText是一個好的選擇?如果它有方法來捕捉任何按鍵?編輯我想從上面的字符串中檢測鍵并測量按下它的時間,(例如開始測量KeyDown和停止KeyUp)。如果可能的話,我想阻止我的test string(它的9RJhl6aH0n,就像我的屏幕中一樣)中未提及的其他鍵編輯2到目前為止我所取得的成就是這樣的,但是default當我編碼 line: 時,我的應用程序崩潰了measureText.setText("")。它工作得很好,但它仍然不會觸發KeyDown(或KeyPress)。這些方法僅在KeyUp用戶剛剛輸入字母時運行。順序很重要!measureText.addTextChangedListener(new TextWatcher(){        @Override        public void afterTextChanged(Editable arg0) {            switch(measureText.getText().toString()){                case "9":                    break;                case "9R":                    break;                case "9RJ":                    break;                case "9RJh":                    break;                case "9RJhl":                    break;                case "9RJhl6":                    break;                case "9RJhl6a":                    break;                case "9RJhl6a0":                    break;                case "9RJhl6a0n":                    break;                default:                    measureText.getText().clear();                    break;            }            return;        }        @Override        public void beforeTextChanged(CharSequence s, int start, int count, int after) {            // TODO Auto-generated method stub            return;        }        @Override        public void onTextChanged(CharSequence s, int start, int before, int count) {            return;        }    });
查看完整描述

3 回答

?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

我會說,那OnKeyUp&OnKeyDown事件不會削減它,因為軟鍵盤幾乎不會發出任何這些。這是一個粗略的原型,它根據預期的字符串過濾字符的輸入。有很大的改進空間;雖然自定義實現仍然是比嘗試使用框架方法更好的方法,框架方法可能只捕獲?鍵......在FilteredEditText任何輸入出現在屏幕上之前捕獲它 - 為了實現擊鍵模式記錄器,預期的字符串需要被分成一個ArrayList,它也將保持各個擊鍵之間的持續時間;一旦記錄下來,就可以使用收集到的信息進行比較。


/**

 * Filtered {@link AppCompatEditText}

 * @author Martin Zeitler

 */

public class FilteredEditText extends AppCompatEditText {


    private static final String LOG_TAG = FilteredEditText.class.getSimpleName();


    private String expectedString = null;


    public FilteredEditText(Context context) {

        super(context);

    }


    public FilteredEditText(Context context, AttributeSet attrs) {

        super(context, attrs);

    }


    public FilteredEditText(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);

    }


    public void setExpectedString(@NonNull String value) {

        this.expectedString = value;

        this.setupInputFilter();

    }


    public void setupInputFilter() {

        this.setFilters(new InputFilter[] {

            new InputFilter() {

                public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int destStart, int destEnd) {

                    if (source.length() > 0 && source.charAt(end-1) == expectedString.charAt(destEnd)) {


                        /* valid input received */

                        Log.d(LOG_TAG, "input accepted: " + String.valueOf(source.charAt(end-1)));

                        return source;


                    } else {


                        /* invalid input received */

                        Log.d(LOG_TAG, "input rejected: " + String.valueOf(source.charAt(end-1)) + " - expected: " + String.valueOf(expectedString.charAt(destEnd)));

                        return "";

                    }

                }

            }

        });

    }


    /** hardware event  */

    @Override

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        Log.d(LOG_TAG, "onKeyDown()");

        return super.onKeyDown(keyCode, event);

    }


    /** hardware event  */

    @Override

    public boolean onKeyUp(int keyCode, KeyEvent event) {

        Log.d(LOG_TAG, "onKeyUp()");

        return super.onKeyUp(keyCode, event);

    }

}

使用示例:


FilteredEditText mTextInput = findViewById(R.id.text_input);

mTextInput.setExpectedString("9RJhl6aH0n");

日志輸出:


D/FilteredEditText: input accepted: 9

D/FilteredEditText: input rejected: r - expected: R

D/FilteredEditText: input rejected: 4 - expected: R

D/FilteredEditText: input accepted: R

到目前為止,我已經使用軟件鍵盤對其進行了測試……而我目前無法使用 BT 硬件鍵盤對其進行測試,因為電池是空的。我假設,InputFilter捕獲所有輸入。


幾乎沒有任何事件是由軟件鍵盤觸發的OnKeyUp,OnKeyDown因為當知道擊鍵何時被過濾時,這仍然會導致類似的模式——即使無法測量擊鍵的持續時間,也無法測量鍵盤的攻擊速度。擊鍵,由于軟件鍵盤的限制 - 唯一可能的解決方法是強制使用硬件鍵盤或創建一個為所有鍵發出這些事件的軟件鍵盤(與默認值相反GBoard,也不是SwiftKey)。我現在只是想知道滑動打字和語音打字......因為這是物理擊鍵動力學幾乎沒有考慮過的事情。甚至留下了反饋GBoard,因為在某些情況下選擇性地發出鍵碼會很有幫助。


該文檔還明確指出:


在使用類和相關 API 處理鍵盤事件時KeyEvent,您應該期望此類鍵盤事件僅來自硬件鍵盤。您永遠不應依賴接收軟輸入法(屏幕鍵盤)上任何鍵的鍵事件。


人們仍然可以使用硬件事件,同時擁有發出它們的按鈕;例如:


/**

 * Fake Hardware {@link AppCompatButton}

 * @see <a href="https://developer.android.com/reference/android/view/KeyEvent">KeyEvent</a>

 * @author Martin Zeitler

 */

public class FakeHardwareButton extends AppCompatButton {


    private BaseInputConnection  mInputConnection;


    private int keyCode = KeyEvent.KEYCODE_9;

    private KeyEvent keyDown;

    private KeyEvent keyUp;


    public FakeHardwareButton(Context context) {

        this(context, null);

    }


    public FakeHardwareButton(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }


    public FakeHardwareButton(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

    }


    @SuppressLint("ClickableViewAccessibility")

    private void setupInputConnection(View targetView) {


       this.mInputConnection = new BaseInputConnection(targetView, true);

       this.keyDown = new KeyEvent(KeyEvent.ACTION_DOWN, this.keyCode);

       this.keyUp = new KeyEvent(KeyEvent.ACTION_UP, this.keyCode);


       this.setOnTouchListener(new View.OnTouchListener() {


            @Override

            public boolean onTouch(View v, MotionEvent event) {

                switch(event.getAction()) {

                    case MotionEvent.ACTION_DOWN:

                        mInputConnection.sendKeyEvent(keyDown);

                        return true;


                    case MotionEvent.ACTION_UP:

                        mInputConnection.sendKeyEvent(keyUp);

                        return true;

                }

                return false;

            }

        });

    }

}

問題只是,例如。KeyEvent.KEYCODE_9并且KeyEvent.KEYCODE_NUMPAD_9不一樣,因此String在數字鍵的情況下總是必須比較表示。


查看完整回答
反對 回復 2022-05-21
?
鳳凰求蠱

TA貢獻1825條經驗 獲得超4個贊

您只需使用活動的調度事件


像這樣:


 @Override

    public boolean dispatchTouchEvent(MotionEvent ev) {

        switch (ev.getAction() & MotionEvent.ACTION_MASK) {

            case MotionEvent.ACTION_POINTER_DOWN:

                break;

            case MotionEvent.ACTION_POINTER_UP:

                break;

            case MotionEvent.ACTION_UP:

                break;

            case MotionEvent.ACTION_DOWN:

                break;

        }

            return super.dispatchTouchEvent(ev);

    }

這樣,您可以輕松控制 KeyDown 和 KeyUp 事件。


在這里你可以找到所有的 MotionEvents


對于軟鍵,您只能使用TextChangeListener


    editText.addTextChangedListener(new TextWatcher(){


        @Override

        public void afterTextChanged(Editable arg0) {

            // TODO Auto-generated method stub

  switch (arg0.toString()) {

                    case "9":

                        break;

                    case "9R":

                        break;

                    case "9RJ":

                        break;

                    case "9RJh":

                        break;

                    case "9RJhl":

                        break;

                    case "9RJhl6":

                        break;

                    case "9RJhl6a":

                        break;

                    case "9RJhl6a0":

                        break;

                    case "9RJhl6a0n":

                        break;

                    default:

                        arg0.clear();

                        break;


                }

                return;


        }


        @Override

        public void beforeTextChanged(CharSequence s, int start, int count,

                int after) {

            // TODO Auto-generated method stub


        }


        @Override

        public void onTextChanged(CharSequence s, int start, int before, int count) {

            // here right logic for getting last char and show it on toast


        }


    });  


查看完整回答
反對 回復 2022-05-21
?
浮云間

TA貢獻1829條經驗 獲得超4個贊

您需要仔細覆蓋以下功能:


@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {


    switch (keyCode) {

        case KeyEvent.KEYCODE_A:

        {

            //your Action code

            return true;

        }

    }

    return super.onKeyDown(keyCode, event);

}

對于edittext:


mMyEditText.addTextChangedListener(new TextWatcher(){


    public void afterTextChanged(Editable s) 

    {

    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) 

    {


    }

    public void onTextChanged(CharSequence s, int start, int before, int count) 

    {

    }

);


查看完整回答
反對 回復 2022-05-21
  • 3 回答
  • 0 關注
  • 274 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號