By 吴思博 20180428
1. 背景 :
具体来说就是,检测到了用户在应用内有截图,弹出一个分享界面, 在截图下方添加一个二维码,进行分享。
先展示下效果图
2. 前言
Android系统没有直接对截屏事件监听的接口,也没有广播,只能自己动手来丰衣足食,一般有三种方法。
利用FileObserver监听某个目录中资源变化情况
利用ContentObserver监听全部资源的变化
监听截屏快捷按键 ( 由于厂商自定义Android系统的多样性,再加上快捷键的不同以及第三方应用,监听截屏快捷键这事基本不靠谱,可以直接忽略 )
3.Android截屏系统做的事情
通过读源码(TakeScreenshotService 和 GlobalScreenshot )总结Android截屏系统做的事情:
保存截屏Bitmap到本地文件
把图片记录插入到ContentProvider中
发送一个截图相关的Notification
解决方法:
利用FileObserver监听某个目录中资源变化情况
利用ContentObserver监听全部资源的变化
4. FileObserver 与 ContentObserver 比较
对于截图监听有两种常用方案
方案一: 通过FileObserver监听截屏文件夹,当有新的截屏文件产生时,调用设定的回调函数执行相关操作。
优点:
1. 实现简单
缺点:
1. 不同手机默认的截屏路径可能不同,需要做适配处理
2. 不同手机截屏触发的事件名称可能不同,需要测试适配
3. 监听到截屏事件后马上获取图片获取不到,需要延迟一段时间
方案二:通过ContentObserver监听多媒体图片库资源的变化。当手机上有新的图片文件产生时都会通过MediaProvider类向图片数据库插入一条记录,以方便系统的图片库进行图片查询,可以通过ContentObserver接收图片插入事件,并获取插入图片的URI。
优点:
1. 不同手机触发的事件是一样的
缺点:
1. 不同手机截屏文件的前缀可能不同,需要做适配
2. 监听到截屏事件后马上获取图片获取不到,需要延迟一段时间
4.1 FileObserver实现
最开始就是想到这个方法, 当FileObserver监听某个目录中资源变化情况,时候获取到文件路径
a. 关键代码:
监听到截屏事件后马上获取图片获取不到,可能需要延迟一段时间。 做while循环,收到Create时间后,Thread.sleep(600), 当尝试最大次数(MAX_TRYS)失败后放弃。
SNAP_SHOT_FOLDER_PATH 的路径不同手机不一样,要去适配各种手机的路径
需要权限,否则可能收不到事件。
(如果没有收到事件,检查一下权限和监听的目录)
b. 小结:
每一次截屏,有多个事件回调
每一次截屏,不同的手机,事件回调可能有些不同。
不同的手机,默认截屏图片储存的文件夹可能不同
FileObserver只能监听文件夹中子文件和子文件夹的变化情况,不能监听子文件夹内部的资源变化
基于 不同的手机,默认截屏图片储存的文件夹可能不同 和 可能收不到事件,这种方法并不能适用于所有的机型。
4.2 .ContentObserver实现
放弃了FileObserver方法, 最后选择了ContentObserver方法。通过ContentObserver监听多媒体图片库资源的变化。当手机上有新的图片文件产生时都会通过MediaProvider类向图片数据库插入一条记录,以方便系统的图片库进行图片查询,可以通过ContentObserver接收图片插入事件,并获取插入图片的URI。
a.步骤
(1)添加权限
(2)初始化、注册和取消监听
(3)媒体内容观察者 (观察媒体数据库的改变)
(4)数据改变时查询数据库中最后加入的一条数据,处理获取到的第一行数据。
(5)处理监听到的资源, 设置最大等待时间500ms (因为某些魅族手机保存有延迟)
(6)设置回调工具
b.遇到问题:
主要问题都在第五步:
(1)因为某些魅族手机保存有延迟 , 轮询与延迟,设置最大等待时间500ms
(2)要判断是否是截屏,有可能是用户自己再文件夹中添加了一张图片
c. 小结:
ContentObserver会监听到所有图片资源的变化情况,要做好去重过滤工作
根据uri去读取ContentProvider内容时候,记得关闭cursor,防止内存泄漏
关键字可扩展,大大增加的监听的范围,比FileObserver好用多了,但是去重过滤会比FileObserver复杂一些。
5. 二维码拼接(bitmap)
1、Bitmap纵向拼接
补充 :
今天测试时候 ,发现个别手机会自己修改截图文件夹的文件, 截屏功能会误以为是用户在截屏操作,进行捕获。 所以加了一个时间判断
打印观察到截图插入时间不会改变
附上 : 获取插入时间(单位是秒非毫秒)
参考文献
1、Android 截屏事件监听https://juejin.im/entry/58647ee9128fe1006d0f4454
2、严选Android-截图分享功能实现与踩坑分享 http://ks.netease.com/blog?id=7038
3、Android App内截屏监控及涂鸦功能实现 https://www.jianshu.com/p/2e6d52abf115