千家信息网

Android系统全局触摸事件监听实例代码

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章主要介绍"Android系统全局触摸事件监听实例代码",在日常操作中,相信很多人在Android系统全局触摸事件监听实例代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对
千家信息网最后更新 2025年01月19日Android系统全局触摸事件监听实例代码

这篇文章主要介绍"Android系统全局触摸事件监听实例代码",在日常操作中,相信很多人在Android系统全局触摸事件监听实例代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Android系统全局触摸事件监听实例代码"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Android系统全局触摸事件监听

Android触摸全局监听指的是调用监听后在任何界面都能获取到触摸事件。

要实现这个功能必须要修改源码添加新的接口,因为系统默认是不暴露这个方法的。

源码

监听系统全局触摸事件的类和相关代码:

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java    @Override    public void registerPointerEventListener(PointerEventListener listener, int displayId) {        Slog.i(TAG, "registerPointerEventListener PointerEventListener = " + listener);        synchronized (mGlobalLock) {            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);            if (displayContent != null) {                displayContent.registerPointerEventListener(listener);            }        }    }    @Override    public void unregisterPointerEventListener(PointerEventListener listener, int displayId) {        synchronized (mGlobalLock) {            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);            if (displayContent != null) {                displayContent.unregisterPointerEventListener(listener);            }        }    }

第一个参数:是中PointerEventListener接口,

里面有MotionEvent对象含有点击事件,比如DOWN、UP、MOVING等其他信息。

package android.view;    public interface WindowManagerPolicyConstants {        interface PointerEventListener {            void onPointerEvent(MotionEvent motionEvent);        }    }

第二个参数,屏幕id,正常用0 ,表示主屏幕id。有些设备有投屏或者第二屏才需要关注这个。

下面介绍如何注册这个服务

1、绑定这个系统服务,这个方法行不通

因为这个服务的aidl接口IWindowManager,并没有暴露这个方法
registerPointerEventListener方法定义在另一个内部接口 WindowManagerFuncs 中

public interface WindowManagerPolicy extends WindowManagerPolicyConstants {    public interface WindowManagerFuncs {            /** Register a system listener for touch events */            void registerPointerEventListener(PointerEventListener listener, int displayId);            /** Unregister a system listener for touch events */            void unregisterPointerEventListener(PointerEventListener listener, int displayId);    }}

2、获取WindowManagerFuncs对象,该对象获取的方式在源码中有多种

参考:

frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.javapublic PhoneWindowManager extends AbsPhoneWindowManager implements WindowManagerPolicy, IHwPhoneWindowManagerInner{    public WindowManagerFuncs getWindowManagerFuncs(){        return mWindowManagerFuncs;     }}

WindowManagerFuncs在源码中是可以直接new的,使用如下:

PhoneWindowManager phoneWindowManager = new PhoneWindowManager();WindowManagerFuncs windowManagerFuncs = phoneWindowManager.getWindowManagerFuncs();windowManagerFuncsEx.registerPointerEventListener(listener, Display.DEFAULT_DISPLAY);

3、在华为Emui源码添加aidl回调

WindowManagerEx有通道直接发送数据到WindowManagerService并可以进行数据监听

(1)添加aidl接口

vendor\huawei\Emui\frameworks\hwCommInterface\base\core\java\com\huawei\android\app\IHwPointEventCallback.aidlpackage com.huawei.android.app;    import android.view.MotionEvent;    oneway interface IHwPointEventCallback {        void onPointerEvent(in MotionEvent motionEvent);    }

(2)WindowManagerEx的修改

vendor\huawei\Emui\frameworks\hwext\hwext\framework\src\com\huawei\android\app\WindowManagerEx.java    private final int TRANSACTION_SET_POINTER_EVENT_LISTENER = android.os.IBinder.FIRST_CALL_TRANSACTION + 2100;    //给WindowManagerService传递监听对象    public static void setPointerEventListener(IHwPointEventCallback listener) {        Log.i(LOG_TAG, "setPointerEventListener listener = " + listener);        IBinder windowManagerBinder = WindowManagerGlobal.getWindowManagerService().asBinder();        if (windowManagerBinder != null) {            Parcel data = Parcel.obtain();            Parcel reply = Parcel.obtain();            try {                data.writeInterfaceToken("android.view.IWindowManager");                //传递aidl监听对象                data.writeStrongBinder(listener != null ? listener.asBinder() : null);               //发送                windowManagerBinder.transact(TRANSACTION_SET_POINTER_EVENT_LISTENER, data, reply, 0);            } catch (RemoteException e){                Log.e(LOG_TAG, "setPointerEventListener exception is " + e.getMessage());            } finally {                data.recycle();                reply.recycle();            }        } else {            Log.w(LOG_TAG, "setPointerEventListener windowManagerBinder is null");        }    }

(3)在WindowManagerService中接收数据并做实际监听

基于尽量不修改源码的理念,Emui中有WindowManagerService的子类HwWindowManagerService,在子类中修改代码即可。

vendor\huawei\Emui\frameworks\base\services\java\huawei\com\android\server\wm\HwWindowManagerService.java    HwWindowManagerService extends WindowManagerService    private final int TRANSACTION_SET_POINTER_EVENT_LISTENER = android.os.IBinder.FIRST_CALL_TRANSACTION + 2100;    private IHwPointEventCallback mIHwPointEventCallback = null;        //接收WindowManagerEx传递过来的数据    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)        throws RemoteException {            switch (code) {                case TRANSACTION_SET_POINTER_EVENT_LISTENER:                    data.enforceInterface("android.view.IWindowManager");                    IHwPointEventCallback observer = IHwPointEventCallback.Stub.asInterface(data.readStrongBinder());                    setPointerEventListener(observer);                    reply.writeNoException();                    return true;        }    }        //在Service中创建唯一的监听对象    private PointerEventListener mPointerEventListener = new PointerEventListener() {        @Override        public void onPointerEvent(MotionEvent motionEvent) {            if(mIHwPointEventCallback != null) {                try {                    mIHwPointEventCallback.onPointerEvent(motionEvent);                } catch (RemoteException e) {                    Slog.e(TAG, "mIHwPointEventCallback error = " + e.getMessage());                }            }        }    };    //添加设置触摸监听方法    private void setPointerEventListener(IHwPointEventCallback listener) {        Slog.i(TAG, "setPointerEventListener PointerEventListener = " + listener);        int uid = Binder.getCallingUid();        if(uid != Process.SYSTEM_UID){            Slog.e(TAG, "setPointerEventListener uid must be "+ Process.SYSTEM_UID +",but now uid = " + uid);            return;        }        mIHwPointEventCallback = listener;        if(listener != null) {            //实际调到父类的注册触摸事件的方法            registerPointerEventListener(mPointerEventListener, Display.DEFAULT_DISPLAY);        }        else {            //实际调到父类的反注册触摸事件的方法            unregisterPointerEventListener(mPointerEventListener, Display.DEFAULT_DISPLAY);        }    }

方法3可以实现在普通app中监听到系统的全局触摸事件,

因为app可以依赖Emui的emui_addons.jar,
调用到里面的部分类,比如WindowManagerEx,就可以监听全局触摸事件。

其他系统环境可以根据实际情况参考上面的实现。

到此,关于"Android系统全局触摸事件监听实例代码"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0