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

扫描二维码关注公众号,回复: 16879484 查看本文章
. 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安装即可

猜你喜欢

转载自blog.csdn.net/yimelancholy/article/details/130496623