分享一些实现思路
起因
在2017年中, 微信做了一次更新, 为了让字体排版更舒适, 把聊天界面的 TextView 换成了自定义的 View.
对我来说, 影响最大的就是无法通过 Accessibility Service 获取 View 的 text 值了.
我想了很久, 软件也凉了很久. 直到有一天, 在黄龙的麦当劳, 开着电脑吃薯条的时候, 突然想到了个方法:
我如果在微信上方覆盖一层 Activity, 那微信的新消息就会走通知, 我就能通过 Notification Listener 收到消息!
我十分高兴, 因为手里有 Accessibility Service 的权限, 如同开挂一般, 觉得应该没什么问题.
实现
这个 MaskActivity 必须不能是以悬浮窗的方式覆盖, 这会遇到很多问题:
当微信UI不在前台时, 微信并不会更新从网络收到的消息, 我需要在收到新消息之后移除 Mask, 让它刷新再盖上来.
盖上来之后, 用户的操作就会在我的 MaskActivity 上, 我是否应该接管用户的输入 以保证能截到用户在打字时收到的消息?
我是否应该在用户选择表情的时候也覆盖, 并且在用户点击的时候立刻销毁 Mask 并对底下的微信表情进行点击操作?
我是否应该自己实现一套微信的默认表情, 使得用户可以同时输入文字和表情?
这上面的我都尝试过, 实现了用户在我的 Mask 上输入文字表情, 并点击我Mask上的发送按钮发送消息, 但这太累人了.
我无法支持微信表情选择器的滑动, 因为那需要 api 23 提供的控制滑动, 但即使可以用, 也是极其卡顿的.
而且 有些时候, 我的Mask已经覆盖上来了, 但微信的表情还没渲染完, 导致表情显示不全.
所以我最终决定放弃支持 – 在用户选择表情时也能记录消息
后来测试 觉得用户输入在我的Mask上实在是体验太差. 我在进入微信时覆盖Mask, 但有时如果之前有草稿, 输入框会默认有焦点, 键盘会自动弹出.我需要把微信文本框里的东西放到我的Mask上, 再弹出键盘, 这速度实在是太慢了, 而且屏幕会因为键盘上下闪.
所以我最终还是放弃了支持 – 在用户输入文字时也能记录消息
最终方案
现在我的 Mask 的任务就轻松多了: 在用户想输入时销毁, 不想输入时覆盖.
那问题就是, 如何知道用户什么时候想输入?
判断输入框是否有焦点.
那用户输入完之后, 并没有收起键盘, 但他确实不想输入了, 怎么办?
我选择在检测到用户做了发送消息的动作之后, 清除输入焦点, 并盖上Mask.
那用户输入完之后, 还想再输入, 怎么办?
这个取舍确实比较麻烦, 我选择让用户想输入的时候再点击一次输入框.
因为比起输入完让用户记得关闭键盘, 还是这样可行些,
如果用户实在无法接受, 可以选择关闭”记录微信屏幕消息”
对了, 在聊天时, 顶部是不会有通知消息的, 需要用 Notification Listener cancel 这条通知
在最近的测试中发现, 微信的首页, 也就在是选择聊天的界面时收到的消息也会不提醒, 我需要在此时也覆盖上 Mask, QQ/Tim 主界面同理
至此, 我的 v5.2 feature – 记录微信聊天界面消息 记录微信主界面消息 记录 QQ/Tim 主界面消息 就实现了