Android中实时拦截剪切板请求的实现思路

PaulPerkenstein 2026-08-01 10:46 1

起因

我本身非常讨厌应用一打开就读取我的剪切板。感觉很火大我开发了一款全局作用域的xposed模块仅放行Gboard的剪切板读取请求。

但是问题是Android的应用内长按粘贴请求也被拦截了只能在gboard内手动粘贴。

我发现在ios中应用主动请求剪切板内容和应用请求剪切板是分离的。在ios下应用想要读取剪切板会弹出一个弹窗让用户选择是否允许,在我看到后就知道这就是我想要的然后就开始了我模块的改进工程。


遇到的问题

在我询问LLM剪切板的调用链条时我发现这是一个非常复杂的任务。Android的剪切板读取是通过aidl向system_service进程直接请求的同步方法。这就让我非常困扰。

首先hook点位应该在哪?我是应该在应用进程里把同步的函数进行移异步实现还是在system_service内的ClipboardService进行修改呢?



  • 方案1 如果修改应用进程内的函数实现应该是最简单的,但是我不想这样。首先每个人应用都会被xposed注入而且在lsposed框架下只有被勾选的应用才能生效,和我之前的全局生效的比还开了倒车

  • 方案2 如果hook点位在ClipboardService如何把这个同步函数改为异步实现?弹窗又该怎么弹出?


尝试过程

尝试过程过多过于冗长知道过程也没什么价值,先省略有可能之后会更新


解决方案

既然为了全局生效且不注入应用程序层这一需求。需要选择的hook点位一定是ClipboardService的权限判断函数。既然hook函数确定了怎么把弹窗弹出来呢?

经过尝试得知system_service进程无法弹出,那么弹窗只能由app进行实现。

经过尝试最终敲定了hook和app通信方案。我在App中实现了一个Service,让system_service进程在开机时自动连接app通过aidl进行通信。如发现断开则立刻重连。这样的设计不止可以用于普通通信还可以实现配置文件的实时更新。

在ClipboardService读取请求触发后向app发送一个剪切板读取请求然后阻塞等待返回结构,应用在受到请求后弹出弹窗请求是否返回。根据用户返回结果判断是否放行。由于这是在system_service进行的阻塞有系统彻底卡死的风险需要在hook的阻塞端加上超时机制一旦超时则不再等待返回结果直接拒绝。

还有需要解决的问题就是一旦阻塞超过5秒ANR会弹出未响应弹窗。初版方案把超时时间设定在了5秒不过时间有点太短了。在后续的改进版本中为了解决该问题添加了为当前阻塞应用授予临时特权的代码实现并将超时时间延长到了10秒


总结

由于Android的api设计的历史遗留问题过于严重。想要完美复现ios内的剪切板体验还是没有做到只有一个我个人尽力而为的妥协实现。应用内长按粘贴也会呼出弹窗不过这也是没办法的事情。

由于我的模块的实现范围已经从简单的权限拒绝拓展为了系统里的幕府将军。属于从Android的框架中另立朝廷只进行剪切板修改就有点太浪费了,我就把这个模块从简单的剪切板拦截模块拓展了一系列其他的功能不过这都是后话了

最新回复 (2)
  • zc741 08-01 13:38
    1

    佬用的什么Android机,系统设置里面有没有剪贴板的权限设置,我用的 vivo 是带有管理权限的,可以设置每个应用是否能访问剪贴板。

  • PaulPerkenstein 楼主 08-01 15:02
    2

    我用的是类原生系统确实没这个选项。不过可以用adb设置权限。但我希望我的默认行为是拒绝或询问剪切板而不是手动设置才编写了这个模块

* 帖子来源Linux.do
返回