input joystick keyevent 109报错Error: Invalid arguments for command: keyevent

平台

        Android 5.1

问题

        由于没有手柄,用命令模拟手柄按键,但是报错Error: Invalid arguments for command: keyevent,确认格式是按照Usage中说明的格式:

130|root:/ # input joystick keyevent 109
Error: Invalid arguments for command: keyevent
Usage: input [<source>] <command> [<arg>...]

The sources are: 
      mouse
      keyboard
      joystick
      touchnavigation
      touchpad
      trackball
      stylus
      dpad
      touchscreen
      gamepad

The commands and default sources are:
      text <string> (Default: touchscreen)
      keyevent [--longpress] <key code number or name> ... (Default: keyboard)
      tap <x> <y> (Default: touchscreen)
      swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      press (Default: trackball)
      roll <dx> <dy> (Default: trackball)

原因

        5.1的Input.java中,处理keyevent类型的command时做了一个判断,该判断的逻辑有误(对比Android 10),导致只有一个arg时直接走到参数错误的逻辑

解决方法

        由于和处理的问题本身无关,所以没有修改Input.java,若要修改可以参考Android 10的Input.java(下文详细说明)。不修改的话,输入模拟按键命令的时候可以多加一次目标键值,如:input joystick keyevent 109 109

详细内容

        input命令

        input命令其实很简单,输入错误的input命令(input -h等随便什么)查看使用方式:

Usage: input [<source>] <command> [<arg>...]

The sources are: 
      mouse
      keyboard
      joystick
      touchnavigation
      touchpad
      trackball
      stylus
      dpad
      touchscreen
      gamepad

The commands and default sources are:
      text <string> (Default: touchscreen)
      keyevent [--longpress] <key code number or name> ... (Default: keyboard)
      tap <x> <y> (Default: touchscreen)
      swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      press (Default: trackball)
      roll <dx> <dy> (Default: trackball)

        可以看到完整的input命令source+command+arg,source就是模拟的是什么设备,command就是模拟的输入方式,arg就是具体的参数了,模拟手柄按键时,source为joystick,command为keyevent,后面具体键值可以查看KeyEvent.java中定义的。

        Input命令处理(keyevent)

        处理的逻辑位于/frameworks/base/cmds/input/src/com/android/commands/input/Input.java,针对keyevent类型的command,5.1的处理如下:
 

private void run(String[] args) {    //args不包含“input”,从之后算起
        if (args.length < 1) {
            showUsage();
            return;
        }

        //假设串口输入“input joystick keyevent 109”,args此时是“joystick keyevent 109”
        int index = 0;
        String command = args[index];    //command = “joystick”
        int inputSource = InputDevice.SOURCE_UNKNOWN;
        if (SOURCES.containsKey(command)) {
            inputSource = SOURCES.get(command);
            index++;    //index = 1
            command = args[index];    //command = “keyevent”
        }
        final int length = args.length - index;    //记住这个变量,此时是3-1 = 2

        try {
            if (command.equals("text")) {
                ...
            } else if (command.equals("keyevent")) {
                if (length >= 2) {
                    //判断是否有长按标志
                    final boolean longpress = "--longpress".equals(args[index + 1]);
                    final int start = longpress ? index + 2 : index + 1;    //start = 2
                    inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
                    
                    //经过上面的步骤,length = 2,start = 2,不仅如此if,直接出try-catch块到                
                    //最后的错误处理
                    if (length > start) {
                        for (int i = start; i < length; i++) {
                            int keyCode = KeyEvent.keyCodeFromString(args[i]);
                            if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
                                keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
                            }
                            sendKeyEvent(inputSource, keyCode, longpress);
                        }
                        return;
                    }
                }
            } 
            ...
        } catch (NumberFormatException ex) {
        }
        System.err.println(INVALID_ARGUMENTS + command);
        showUsage();
    }

        再看Android 10中的处理,明显不一样的地方就是判断是否有长按标志之后的if条件:

private void run(String[] args) {
        if (args.length < 1) {
            showUsage();
            return;
        }

        int index = 0;
        String command = args[index];
        int inputSource = InputDevice.SOURCE_UNKNOWN;
        if (SOURCES.containsKey(command)) {
            inputSource = SOURCES.get(command);
            index++;
            command = args[index];
        }
        final int length = args.length - index;

        try {
            if (command.equals("text")) {
                ...
            } else if (command.equals("keyevent")) {
                if (length >= 2) {
                    final boolean longpress = "--longpress".equals(args[index + 1]);
                    final int start = longpress ? index + 2 : index + 1;
                    inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);

                    //注意这里使用的是args.length而不是前面计算的length
                    //如果是“input joystick keyevent 109”,args.length = 3, start = 2
                    if (args.length > start) {  
                        for (int i = start; i < args.length; i++) {
                            int keyCode = KeyEvent.keyCodeFromString(args[i]);
                            if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
                                keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
                            }
                            sendKeyEvent(inputSource, keyCode, longpress);
                        }
                        return;
                    }
                }
            } ...
        } catch (NumberFormatException ex) {
        }
        System.err.println(INVALID_ARGUMENTS + command);
        showUsage();
    }

总结       

        都2021年了为啥这公司还在用5.1作为主流版本呀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值