截屏事件监听实现
来源:互联网 发布:汽车行业的大数据应用 编辑:程序博客网 时间:2024/05/02 00:46
现在很多app都有监听截屏的功能,可以提示用户分享或者发送截屏图片,进一步提升app的用户体验。例如,微信在截屏后,点击输入框+号,会提示发送刚才的截屏图片,非常方便实用。其实,微信不光对截屏的图片进行了监听,你的手机sdcard里的大部分目录下新增图片时,都会被监听到。比如,你可以直接复制一张相册里的图片,微信也会提示。之前以为微信只是监听了系统截屏时发送的广播,然而查了文档并没有发现任何截屏类的广播。上述微信的例子也很好的解释了,其实对于截屏以及其他新增图片的监听是通过对sdcard文件内容变动的监听。
实现截屏监听主要有两种方式,使用FileObserver和ContentObserver,顾名思义,一个是基于文件或者目录的监听,一个是基于内容的监听。下面利用这两种方式简单实现了对于图片文件变动的监听。
FileObserver
FileObserver主要用于监听指定路径的目录或者文件的变动情况,包括监听目录下的子目录和文件以及目录本身,同时也可以指定监听文件变动的形式,例如创建、删除、移动、修改等,或者全部事件都监听。例如这里我们需要监听sdcard截屏目录,并且指定监听事件为FileObserver.CREATE,这样当screenshots目录下新增截屏图片时,onEvent事件就会触发,并且回调了截屏文件的相对路径,拿到路径我们就可以做想做的事情了。主要测试代码如下:
private void addFileObserver() { String screenPath = getScreenshotPath(); fileObserver = new ScreenshotFileObserver(screenPath, FileObserver.CREATE); fileObserver.startWatching(); // 开始监听}class ScreenshotFileObserver extends FileObserver { public ScreenshotFileObserver(String path) { super(path); } public ScreenshotFileObserver(String path, int mask) { super(path, mask); } @Override public void onEvent(int event, final String path) { if (event == FileObserver.CREATE) { Log.d("screenshot", path); File file = new File(getScreenshotPath() + path); // todo sth. with the screenshot picture ... } }}
需要注意的是使用FileObserver可能需要声明WRITE_EXTERNAL_STORAGE和MOUNT_UNMOUNT_FILESYSTEMS权限,虽然官方文档并没有提到这点,但是不加权限可能导致FileObserver不能正常工作,但仅仅是监听不到文件变动而已,程序不会crash。
FileObserver用法非常简单,但是一个FileObserver只能监听一个目录。如果需要监听多个目录会比较麻烦,可能你会觉得直接监听sdcard根目录可以搞定,但是那样sdcard下任何一个文件的变动都会被监听,效率和性能可能是个问题。而且有时候我们其实并不清楚需要监听的目录的具体路径,比如不同厂商的手机保存截屏的目录可能不尽相同。
另外,FileObserver在android 6.0以上存在bug,监听不到目录的变动,只能监听指定的具体文件,具体讨论可见:https://code.google.com/p/android/issues/detail?id=189231。
ContentObserver
ContentObserver主要用于监听ContentProvider内容的变动,例如图片数据、音频数据、视频数据等。当有内容变动时,系统会相应修改其在ContentProvider中的记录。不同于FileObserver监听的是具体的文件或者目录路径,ContentObserver监听的是一个指定的Uri,通常可以理解为需要监听的数据类型。例如,这里我们需要监听截屏,可以向ContentResolver注册一个ContentObserver,并指定uri为系统媒体图片,那么当图片数据发生变化时,onChange方法就会被回调。根据回调返回的Uri,我们可以判断变动是否来自截屏图片,这样就可以实现对截屏事件的监听。
private void addContentObserver() { contentObserver = new ScreenshotContentObserver(new Handler(getMainLooper())); Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; getContentResolver().registerContentObserver(uri, false, contentObserver);}class ScreenshotContentObserver extends ContentObserver { public ScreenshotContentObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); // 处理uri获取真实的filepath,判断是否是截屏图片,通常filepath会包含screenshot关键字 ... }}
ContentObserver监听的仅仅只是ContentProvider的记录变动,实际对应文件的变动可能还没有完成,两者可能是个异步的过程或者是操作顺序的问题。例如监听截屏事件,测试时发现onChange被回调了,但是立即操作回调的uri对应的文件却无法得到正确的结果。这是因为截屏文件还没有完全写入导致的,通常的解决方法是提供给用户一个交互界面来缓冲下。
- 截屏事件监听实现
- 自己实现事件监听
- 实现事件监听
- php实现监听事件
- PHP实现监听事件
- 监听手机截屏事件
- Android截屏事件监听
- Android截屏事件监听
- Android截屏事件监听
- Android截屏事件监听
- vue监听滚动事件实现滚动监听
- android实现双击事件监听
- Fragment实现onTouchEvent事件监听
- js实现键盘监听事件
- android实现摇一摇事件监听
- ReactNative实现通知监听事件
- 监听截屏(HOME+Power)事件
- java中的事件监听是怎样实现随时监听的
- APP登陆协议的分析
- h5+css 菜单导航---改变宽度
- 不通过App Store装MAC系统
- 产生随机数可以提高网络安全的新方法(New method of producing random numbers could improve cybersecurity)
- 队列的实现
- 截屏事件监听实现
- 设计模式——4.装饰模式
- javascript字符操作大全
- Android开发环境部署 及 常见问题解决
- leetcode题解日练--2016.7.3
- 【树莓派之旅】第01期:一根网线搞定树莓派可视化界面
- Python 语言及其应用 Chapter_4_Note_5 全局变量和局部变量
- 求一个已排序旋转数组中的最小的数
- Java+Mac+Selenium入门