android input命令模拟事件以及事件注入实现

input命令的参数

进入adb shell 输入input查看指令帮助

127|emulator_x86_64:/ # input                                                  
Usage: input [<source>] [-d DISPLAY_ID] <command> [<arg>...]

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

-d: specify the display ID.
      (Default: -1 for key event, 0 for motion event if not specified.)
The commands and default sources are:
      text <string> (Default: touchscreen)
      keyevent [--longpress|--doubletap] <key code number or name> ... (Default: keyboard)
      tap <x> <y> (Default: touchscreen)
      swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      draganddrop <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      press (Default: trackball)
      roll <dx> <dy> (Default: trackball)
      motionevent <DOWN|UP|MOVE|CANCEL> <x> <y> (Default: touchscreen)
      keycombination [-t duration(ms)] <key code 1> <key code 2> ... (Default: keyboard, the key order is important here.)

代码路径:frameworks/base/services/core/java/com/android/server/input/InputShellCommand.java
例如:adb shell input tap 500 100
在坐标(500,100)的位置模拟点击事件
tap点击事件对应于源码:

    private void sendTap(int inputSource, float x, float y, int displayId) {
        final long now = SystemClock.uptimeMillis();
        injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, now, x, y, 1.0f,
                displayId);
        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, now, x, y, 0.0f, displayId);
    }

参数解析:
int inputSource:表示模拟事件的类型
float x, float y:表示事件坐标点
int displayId:在哪个屏幕上触发事件(一般用于多屏)

触摸事件注入

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i("TAG:","onClick");
                injectClick();
            }
        });
        void injectClick() {
        Log.i("TAG:","injectClick");
        new Thread(new Runnable() {
            @Override
            public void run() {
                Instrumentation instrumentation = new Instrumentation();
                final long now = SystemClock.uptimeMillis();
                int action = MotionEvent.ACTION_DOWN;
                float x = 500;
                float y = 100;
                MotionEvent clickDown = MotionEvent.obtain(now,now,action,x,y,0);
                instrumentation.sendPointerSync(clickDown);
                action = MotionEvent.ACTION_UP;
                MotionEvent clickUp = MotionEvent.obtain(now,now,action,x,y,0);
                instrumentation.sendPointerSync(clickUp);
            }
        }).start();
    }

点击某个按钮,在坐标(500,100)的位置相应点击事件

key事件注入

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i("TAG:","onClick");
                injectHome();
            }
        });
		void injectHome() {
		        Log.i("TAG:","injectHome");
		        new Thread(new Runnable() {
		            @Override
		            public void run() {
		                Instrumentation instrumentation = new Instrumentation();
		                final long now = SystemClock.uptimeMillis();
		                int action = KeyEvent.ACTION_DOWN;
		                KeyEvent homeDown = new KeyEvent(action,KeyEvent.KEYCODE_HOME);
		                instrumentation.sendKeySync(homeDown);
		                action = KeyEvent.ACTION_UP;
		                KeyEvent homeUp = new KeyEvent(action,KeyEvent.KEYCODE_HOME);
		                instrumentation.sendKeySync(homeUp);
		
		            }
		        }).start();
		    }

点击某个按钮,相应HOME事件

事件注入权限问题

我们在自己写的应用中也会有权限报错

在这里插入图片描述

查看AndroidManifest源码frameworks/base/core/res/AndroidManifest.xml

    <!-- @SystemApi Allows an application to inject user events (keys, touch, trackball)
         into the event stream and deliver them to ANY window.  Without this
         permission, you can only deliver events to windows in your own process.
         <p>Not for use by third-party applications.
         @hide
    -->
    <permission android:name="android.permission.INJECT_EVENTS"
        android:protectionLevel="signature" />

从源码中可以看出,三方应用无法是使用该权限

使用内置应用的方式解决权限问题

通过make内置应用的方式解决权限问题
1.在package/apps/目录下创建相应的文件夹,如:MyInject
2.在Android Studio中构建好apk,并创建一个mk文件,放入此文件夹中
在这里插入图片描述
配置mk文件

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyInject
LOCAL_MODULE_TAGS := optional 
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_CERTIFICATE := PRESIGNED
LOCAL_CERTIFICATE := platform
include $(BUILD_PREBUILT)

3.编译apk

. build/envsetup.sh
lunch sdk_phone_x86_64 #must this
make MyInject

4.安装
构建好的apk在out/target/product/emulator_x86_64/system/app/MyInject/目录下
通过adb install MyInject.apk安装即可

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值