Android系统截屏监听的实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android系统截屏监听的实现
1. 原理
Android系统并没有提供截屏通知相关的API,需要我们自己利用系统能提供的相关特性变通实现。Android系统有一个媒体数据库,每拍一张照片,或使用系统截屏截取一张图片,都会把这张图片的详细信息加入到这个媒体数据库,并发出内容改变通知,我们可以利用内容观察者(ContentObserver)监听媒体数据库的变化,当数据库有变化时,获取最后插入的一条图片数据,如果该图片符合特定的规则,则认为被截屏了。
需要ContentObserver监听的资源URI:
MediaStore.Images.Media.INTERNAL_CONTENT_URI
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
读取外部存储器资源,需要添加权限:
android.permission.READ_EXTERNAL_STORAGE
2. 截屏判断依据
当ContentObserver监听到媒体数据库的数据改变, 在有数据改变时获取最后插入数据库的一条图片数据, 如果符合以下规则, 则认为截屏了:
1、时间判断,图片的生成时间在开始监听之后, 并与当前时间相隔10秒内:开始监听后生成的图片才有意义,相隔10秒内说明是刚刚生成的
2、尺寸判断,图片的尺寸没有超过屏幕的尺寸:图片尺寸超过屏幕尺寸,不可能是截屏图片
3、路径判断,图片路径符合包含特定的关键词:这一点是关键,截屏图片的保存路径通常包含“screenshot”
PS:这些判断是为了增加截屏检测结果的可靠性,防止误报,防止遗漏。其中截屏图片的路径正常Android系统保存的路径格式为:“外部存储器/Pictures/Screenshots/Screenshot_20161001-164643.png”,但Android系统碎片化严重,加上其他第三方截屏APP等,所以路径关键字除了检查是否包含“screenshot”外,还可以适当增加其他关键字,详见最后的监听器完整代码。这种监听截屏的方法也不是100%准确,例如某些被root的机器使用第三方截屏APP自定义保存路径,还比如通过ADB命令在电脑上获取手机屏幕快照均不能监听到,但这也是目前可行性最高的方法,对于绝大多数用户都比较靠谱。
3. 监听器的封装与使用
我把ContentObserver对媒体数据库的的监听,以及对结果的判断全都封装在一个独立的类中(ScreenShotListenManager),使用步骤相当简单:
1、在AndroidManifest.xml中添加权限:
1
1
2、监听器的调用:
ScreenShotListenManager manager = ScreenShotListenManager.newInstance(context);
manager.setListener(
new OnScreenShotListener() {
public void onShot(String imagePath) {
// do something
}
}
manager.startListen();
...
manager.stopListen();
监听器类(ScreenShotListenManager)完整代码实现:
package com.xiets.screenshotlistener;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import .Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import ng.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* 截屏监听管理器
*
*
* 截屏判断依据: 监听媒体数据库的数据改变, 在有数据改变时获取最后
* 插入数据库的一条图片数据, 如果符合以下规则, 则认为截屏了:
*
* 1. 时间判断, 图片的生成时间在开始监听之后, 并与当前时间相隔10秒内;
* 2. 尺寸判断, 图片的尺寸没有超过屏幕的尺寸;
* 3. 路径判断, 图片路径符合包含特定的关键词。
*
*
* Demo:
*
{@code*
* // Requires Permission: android.permission.READ_EXTERNAL_STORAGE
*
* ScreenShotListenManager manager = ScreenShotListenManager.newInstance(context);