Android 截屏监听(截图分享功能)

一、需求背景

如果检测到用户在 app 中有截图行为,那么弹出一个分享提示框,提示用户去分享这个截图。

本文主要从三个方面来讲:

1、截图检测的具体实现

2、截图检测踩到的坑

3、截图合成

二、截图分享实现

1、截图分享实现分为两个部分,首先是截图事件的监听。安卓系统并没有提供 api 来监听系统截图事件,也没有什么广播可以用来监听这类事件,那要

怎么解决呢?我们先来看下截图源码。

两个类都在目录framework/base/package/SystemUI/src/com/android/systemui/screenshot 下

Android 截屏监听(截图分享功能)_第1张图片
Android 截屏监听(截图分享功能)_第2张图片
Android 截屏监听(截图分享功能)_第3张图片

从代码里可以看到,截图之后做的主要事情是:

a、保存截屏 Bitmap 到本地文件

b、把图片记录插入到 ContentProvider 中

c、发送一个截图相关的 Notification

那么看到这里,我们大致可以想到两种用来监听截图事件的方式:

监听 ContentProvider 数据改变

监听截图文件目录数据改变

监听截图事件的三种方式

2、截图检测遇到的问题

坑1:监听截图事件的三种方式,这个方法有个问题就是:无法监听到通知栏中提供的截图按键。

坑2:TakeScreenshotService 所运行的进程名为 com.android.systemui.screenshot这个方法在主流的 ROM 上经过测试,目前没有发现问题,

但是这个方案最终没有用在App上,主要担心的就是某些奇葩的国产 ROM 把进程名给改了,导致这个函数判断出错。

坑3:其次是截图文件获取的问题,从之前的系统源码里我们看到,GlobalScreenShot 截图之后,做的工作首先是保存图片,然后再去修改图片数

据库,所以在某些没有大改的系统里,我们在 ContentObserver 的 onChange 回调里是可以获取到图片文件的。但是后来在魅族的系统上测试时,

发现在 onChange 里 获取不到图片文件,大概原因猜测就是魅族把这部分的源码修改了,先通知数据库改变,再保存文件。

要解决这个问题,大概有两种办法:

1. FileObserver 监听文件写完成事件,我们只要监听 CLOSE_WRITE 即可

Android 截屏监听(截图分享功能)_第4张图片

坑4:按照剧本来说,这里的代码大概是没有问题的,然后放到魅族系统上测试了一下,只监听到了 CREATE 事件,这个方案被迫放弃。

2.轮询+延迟

Android 截屏监听(截图分享功能)_第5张图片

坑5:因为某些魅族手机保存有延迟 , 轮询与延迟,设置最大等待时间500ms

坑6:要判断是否是截屏,有可能是用户自己再文件夹中添加了一张图片

坑7:个别手机会自己修改截图文件夹的文件, 截屏功能会误以为是用户在截屏操作,进行捕获。 所以加了一个时间判断

坑8:部分机器写入截图实在是太慢,给个800ms延迟去通知显示分享

三、终上所述,两种方案实现截屏监听分享:

方案1:监听截图文件目录数据改变。

继承FileObserver类,筛选择出手机截屏文件夹,监听截屏文件事件变化,由于某些魅族手机保存有延迟且某些魅族系统上只监听到了CREATE事

件,那么同时监听CLOSE_WRITE(8)、CREATE(256)事件分别做特殊处理;

方案2:监听 ContentProvider 数据改变。

继承ContentObserver类,在handleMediaContentChange方法内处理数据。主要注意点:1、要判断是否是截屏,有可能是用户自己再文件夹中添

加了一张图片;2、个别手机会自己修改截图文件夹的文件, 截屏功能会误以为是用户在截屏操作,进行捕获。 所以加一个时间判断;

四、图片合成

截图图片合成主要做的工作大概就是图片的大小控制了。假如我们把全质量的截图读取到内存中,那么对于小屏幕手机来说,可能影响不大,但

是对于配有2k屏的手机来说,这就是一场灾难了。

坑10:注意bitmap oom

坑11:若需求要去掉顶部状态栏和底部栏

总结:

最终我采用方案1完美实现截图分享功能。

拿来即用,项目GitHub地址 ScreenshotsShare,喜欢关注一个吧。


一个变种需求:H5截屏监听分享功能

同理:App本地利用上述方式监听截图,发送特定指令给H5(需两端提前约定指令\回调方法)即可

你可能感兴趣的:(Android 截屏监听(截图分享功能))