• Android 实现禁止复制


    需求是想要实现应用内复制的文字不被粘贴到应用外的效果

    刚开始是通过将应用放到后台就清除剪贴板,但是切换到别的应用输入法会自动将刚才的内容弹出来,即使输入法不弹出,也有一些机型,清除无效,清除了,还是不影响粘贴,还是能粘贴从应用复制的内容,因此判断应用不可见后清除剪贴板的方案应该是不可行的

    经过调研发现可以通过 Hook 的方式,拦截系统剪贴板的复制,粘贴和剪切功能。
    然后查找了开源的 Hook 框架,最后使用的是 SandHook,集成方式如上篇博客:Android SandHook 使用

    拦截剪贴板

    复制粘贴的原理就是使用Android 系统剪贴板 ClipboardManagersetPrimaryClip(复制和剪切) 方法 和 getPrimaryClip (粘贴)方法,因此可以将这两个方法拦截,将数据存下来,粘贴的时候重新返回,这样即可实现禁止复制应用内内容到外部,并且系统剪贴板的内容依然保留,退出应用后还可以粘贴之前在系统中复制过的内容。
    代码如下:

    @HookClass(ClipboardManager.class)
    public class CopyHooker {
        @HookMethodBackup("setPrimaryClip")
        @MethodParams(ClipData.class)
        static Method onCreateBackup;
        @HookMethodBackup("getPrimaryClip")
        static HookWrapper.HookEntity getPrimaryClip;
    //    @HookMethodBackup("clearPrimaryClip")
    //    static HookWrapper.HookEntity clearPrimaryClip;
        // 内部剪贴板数据
        static ClipData text;
    
        @HookMethod("setPrimaryClip")
        @MethodParams(ClipData.class)
        public static void setPrimaryClip(ClipboardManager thiz, ClipData clip) throws Throwable {
            Timber.i("setPrimaryClip" + clip);
            if (cantCopy) {
                text = clip;
            } else {
                text = null;
                SandHook.callOriginByBackup(onCreateBackup, thiz, clip);
            }
        }
    
        @HookMethod("getPrimaryClip")
        public static ClipData getPrimaryClip(ClipboardManager thiz) throws Throwable {
            Timber.i("getPrimaryClip");
            // 未打开禁止复制;或者内部剪贴板无数据
            if (cantCopy && text != null) {
                return text;
            } else {
                text = null;
                return (ClipData) getPrimaryClip.callOrigin(thiz);
            }
        }
    
    //    @HookMethod("clearPrimaryClip")
    //    public static ClipData clearPrimaryClip(ClipboardManager thiz) throws Throwable {
    //        Timber.i("clearPrimaryClip");
    //        text = null;
    //        return (ClipData) clearPrimaryClip.callOrigin(thiz);
    //    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    清空剪贴板方法也可以重写,不过没有使用,就先注释掉了

    同时不要忘记通过SandHook.addHookClass来添加这个类,方式同样可以参考 SandHook 使用

    缺陷

    使用这个方式还有一个缺陷,就是 SandHook 已经很久没有更新了,现在仅支持到 Android 11, Android 11 以上版本可能暂时不能使用,还需要寻找其他的 Hook 框架

    结论

    通过上述方法即可实现:应用内复制的数据,不能被粘贴到应用外,有此类需求的小伙伴可以尝试一下。

  • 相关阅读:
    Angular 集成 StreamSaver 大文件下载
    6-9 二叉树的遍历 (二叉树的前历、后序、中序、层序遍历)
    【实验】Hadoop-2.7.2+zookeeper-3.4.6完全分布式环境搭建(HDFS、YARN HA)转载
    web安全渗透测试十大常规项(一):web渗透测试之任意文件读取
    D2-读论文D2&算法题D2(复习:单链表、双链表、模拟栈)
    android的USB开发时 mUsbManager.getDeviceList()获取都为空
    并查集 rank 的优化
    你被MySQL 中的反斜杠 \\坑过吗?
    如何快速集成Android版AGConnect认证服务-VK篇
    【全开源】Java无人共享棋牌室茶室台球室系统JAVA版本支持微信小程序+微信公众号
  • 原文地址:https://blog.csdn.net/lebulangzhen/article/details/126766225