android 应用内页面,截屏监听
来源:互联网 发布:淘宝信誉度怎么说 编辑:程序博客网 时间:2024/04/27 14:39
公司的项目由于安全需要,对某一特定的页面需要监听是否被用户截屏了。
简单搜了一下,很少有这方面的问题,没办法,只能自己折腾了。
目前想到三种思路:
1、监听广播
当然,前提是系统在截屏的时候发送某一广播,然而并没有。
2、监听按键
android手机按下“电源键+音量减”会进行截屏,此外大部分手机状态栏下拉的页面中也会有截屏按钮。遗憾的是,监听这两处的操作并不是一件让人开心的事儿~~。
3、监听手机中图片的变化
开始只想到了MediaStore这个类,可以通过它拿到手机中的所有图片,每隔一段时间监听图片数量。这似乎是个不错的主意,直到我转角遇到了ContentObserver。
从名字就可以知道,它是一个内容观察者。通过给ContentProvider注册ContentObserver,可以实现对数据的监听。
public class ScreenshotContentObserver extends ContentObserver { private Context mContext; private int imageNum; private static ScreenshotContentObserver instance; private ScreenshotContentObserver(Context context) { super(null); mContext = context; } public static void startObserve() { if (instance == null) { instance = new ScreenshotContentObserver(Facade.context()); } instance.register(); } public static void stopObserve() { instance.unregister(); } private void register() { mContext.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, this); } private void unregister() { mContext.getContentResolver().unregisterContentObserver(this); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); String[] columns = { MediaStore.MediaColumns.DATE_ADDED, MediaStore.MediaColumns.DATA, }; Cursor cursor = null; try { cursor = mContext.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, MediaStore.MediaColumns.DATE_MODIFIED + " desc"); if (cursor == null) { return; } int count = cursor.getCount(); if (imageNum == 0) { imageNum = count; } else if (imageNum >= count) { return; } imageNum = count; if (cursor.moveToFirst()) { String filePath = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)); long addTime = cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED)); if (matchAddTime(addTime) && matchPath(filePath) && matchSize(filePath)) { doReport(filePath); } } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { try { cursor.close(); } catch (Exception e) { e.printStackTrace(); } } } } /** * 添加时间与当前时间不超过1.5s,大部分时候不超过1s。 * * @param addTime 图片添加时间,单位:秒 */ private boolean matchAddTime(long addTime) { return System.currentTimeMillis() - addTime * 1000 < 1500; } /** * 尺寸不大于屏幕尺寸(发现360奇酷手机可以对截屏进行裁剪) */ private boolean matchSize(String filePath) { Point size = Util.getScreenWidthAndHeight(mContext);//获取屏幕尺寸 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); return size.x >= options.outWidth && size.y >= options.outHeight; } /** * 已调查的手机截屏图片的路径中带有screenshot */ private boolean matchPath(String filePath) { String lower = filePath.toLowerCase(); return lower.contains("screenshot"); } private void doReport(String filePath) { //删除截屏 File file = new File(filePath); file.delete(); //TODO: }}
上面通过register()和unregister()两个静态方法进行监听器的注册和反注册。建议在onStart()方法中进行注册,在onStop()方法中进行反注册,因为截屏并不会引起当前页面生命周期的变化。
在onChange()回调方法中,通过查询,拿到最近添加的那张图片,从创建时间、尺寸、路径3个方面进行匹配,判断是否是截屏图片。
- 创建时间:大多时候,截屏图片的创建时间和当前系统时间不超过1000ms
- 图片尺寸:大多数手机截屏之后,直接保存图片,所以尺寸和屏幕尺寸一致。但有些手机,比如360奇酷手机,截屏后允许用户裁剪。所以图片尺寸的判断放宽到不大于屏幕尺寸
- 图片路径:目前,大多数手机的截屏路径中包含“screenshot”,还未发现例外
匹配成功后,就可以在doReport中做自己想做的事了~~
1 0
- android 应用内页面,截屏监听
- Android 监听应用内Activity生命周期
- Android 监听应用内Activity生命周期
- Android 应用内某些页面禁止截屏与截屏工具类
- android 应用内悬浮框,并在指定页面显示
- Android 监听应用卸载
- android监听当前应用
- Android 应用内禁止截屏功能的实现
- Android应用内支付
- Android应用内截图
- ANDROID应用内截图
- Android 实现匿名内部类监听
- android App内监听截图加二维码
- 开发android <通信监听>应用
- android监听新安装应用
- android应用如何监听错误报告
- Android应用卸载广播监听
- 给页面内嵌iframe绑定监听事件
- Error:SDK location not found. Define location with sdk.dir in the local.properties file or with an A
- tomcat 调优案例
- 【PS4开发】如何通过unity3d发布ps4应用
- 编译内核的保存中间文件
- Android5.x之RecyclerView使用(4)上下拉刷新
- android 应用内页面,截屏监听
- 计算机程序的构造和解释 练习 1.30
- 单源最短路径之Bellman-Ford
- MySql修改数据库编码为UTF8
- php 下载网络图片到本地服务器
- Intellij IDEA 设置字体的大小
- 通讯录(三)----文件实现
- 获得EntityFramework生成的SQL语句
- 【bzoj4600】【SDOI2016】【硬币游戏】【博弈论+dp】