赞
踩
Android系统没有直接对截屏事件监听的接口,也没有广播,只能自己动手来丰衣足食,一般有三种方法。
由于厂商自定义Android系统的多样性,再加上快捷键的不同以及第三方应用,监听截屏快捷键这事基本不靠谱,可以直接忽略。
本文使用的测试手机,一加2(One Plus 2)。
添加权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
代码示例:
- public class ScreenshotActivity extends AppCompatActivity {
-
- private final String TAG = "Screenshot";
-
- private static final String PATH = Environment.getExternalStorageDirectory() + File.separator
- + Environment.DIRECTORY_PICTURES + File.separator + "Screenshots" + File.separator;
-
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_screenshot);
-
- mFileObserver = new CustomFileObserver(PATH);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mFileObserver.startWatching();
- Log.d(TAG, PATH);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- mFileObserver.stopWatching();
- }
-
- /**
- * 目录监听器
- */
- private class CustomFileObserver extends FileObserver {
-
- private String mPath;
-
- public CustomFileObserver(String path) {
- super(path);
- this.mPath = path;
- }
-
- public CustomFileObserver(String path, int mask) {
- super(path, mask);
- this.mPath = path;
- }
-
- @Override
- public void onEvent(int event, String path) {
- Log.d(TAG, path + " " + event);
- // 监听到事件,做一些过滤去重处理操作
- }
- }
- }
打印的日志:
一加2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 256
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 32
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 2
- D/Screenshot: Screenshot_2016-12-16-17-49-18.png 8
三星 S4
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 256
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 32
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 2
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 8
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 32
- D/Screenshot: Screenshot_2016-12-16-19-01-08.png 16
可以通过指定构造函数中的mask,监听某一个事件。
类型 | int值 | 说明 |
---|---|---|
FileObserver.ACCESS | 1 | 读取某个文件 |
FileObserver.MODIFY | 2 | 向某个文件写入数据 |
FileObserver.ATTRIB | 4 | 文件的属性被修改(权限/日期/拥有者) |
FileObserver.CLOSE_WRITE | 8 | 写入数据后关闭 |
FileObserver.CLOSE_NOWRITE | 16 | 只读模式打开文件后关闭 |
FileObserver.OPEN | 32 | 打开某个文件 |
FileObserver.MOVED_FROM | 64 | 有文件或者文件夹从被监听的文件夹中移走 |
FileObserver.MOVED_TO | 128 | 有文件或者文件夹移动到被监听的文件夹 |
FileObserver.CREATE | 256 | 文件或者文件夹被创建 |
FileObserver.DELETE | 512 | 文件被删除 |
FileObserver.DELETE_SELF | 1024 | 被监听的文件或者目录被删除 |
FileObserver.MOVE_SELF | 2048 | 被监听的文件或者目录被移走 |
几点注意事项:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
权限,否则可能收不到事件基于第三点和第四点,这种方法并不能适用于所有的机型。
注意:如果自己写Demo没有收到事件,检查一下权限和监听的目录
ContentObserver用来监听指定uri的所有资源变化,我们可以用它来监听图片资源变化情况,然后做过滤。
添加权限
- <uses-permission android:name="MediaStore.Images.Media.INTERNAL_CONTENT_URI"/>
- <uses-permission android:name="MediaStore.Images.Media.EXTERNAL_CONTENT_URI"/>
代码示例:
- public class ScreenshotActivity extends AppCompatActivity {
- private static final String[] KEYWORDS = {
- "screenshot", "screen_shot", "screen-shot", "screen shot",
- "screencapture", "screen_capture", "screen-capture", "screen capture",
- "screencap", "screen_cap", "screen-cap", "screen cap"
- };
-
- /** 读取媒体数据库时需要读取的列 */
- private static final String[] MEDIA_PROJECTIONS = {
- MediaStore.Images.ImageColumns.DATA,
- MediaStore.Images.ImageColumns.DATE_TAKEN,
- };
-
- /** 内部存储器内容观察者 */
- private ContentObserver mInternalObserver;
-
- /** 外部存储器内容观察者 */
- private ContentObserver mExternalObserver;
-
- private HandlerThread mHandlerThread;
- private Handler mHandler;
-
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_screenshot);
-
- mHandlerThread = new HandlerThread("Screenshot_Observer");
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
-
- // 初始化
- mInternalObserver = new MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, mHandler);
- mExternalObserver = new MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mHandler);
-
- // 添加监听
- this.getContentResolver().registerContentObserver(
- MediaStore.Images.Media.INTERNAL_CONTENT_URI,
- false,
- mInternalObserver
- );
- this.getContentResolver().registerContentObserver(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- false,
- mExternalObserver
- );
- }
-
- protected void onDestroy() {
- super.onDestroy();
- // 注销监听
- this.getContentResolver().unregisterContentObserver(mInternalObserver);
- this.getContentResolver().unregisterContentObserver(mExternalObserver);
- }
-
- private void handleMediaContentChange(Uri contentUri) {
- Cursor cursor = null;
- try {
- // 数据改变时查询数据库中最后加入的一条数据
- cursor = this.getContentResolver().query(
- contentUri,
- MEDIA_PROJECTIONS,
- null,
- null,
- MediaStore.Images.ImageColumns.DATE_ADDED + " desc limit 1"
- );
-
- if (cursor == null) {
- return;
- }
- if (!cursor.moveToFirst()) {
- return;
- }
-
- // 获取各列的索引
- int dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
- int dateTakenIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN);
-
- // 获取行数据
- String data = cursor.getString(dataIndex);
- long dateTaken = cursor.getLong(dateTakenIndex);
-
- // 处理获取到的第一行数据
- handleMediaRowData(data, dateTaken);
-
- } catch (Exception e) {
- e.printStackTrace();
-
- } finally {
- if (cursor != null && !cursor.isClosed()) {
- cursor.close();
- }
- }
- }
-
- /**
- * 处理监听到的资源
- */
- private void handleMediaRowData(String data, long dateTaken) {
- if (checkScreenShot(data, dateTaken)) {
- Log.d(TAG, data + " " + dateTaken);
- } else {
- Log.d(TAG, "Not screenshot event");
- }
- }
-
- /**
- * 判断是否是截屏
- */
- private boolean checkScreenShot(String data, long dateTaken) {
-
- data = data.toLowerCase();
- // 判断图片路径是否含有指定的关键字之一, 如果有, 则认为当前截屏了
- for (String keyWork : KEYWORDS) {
- if (data.contains(keyWork)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * 媒体内容观察者(观察媒体数据库的改变)
- */
- private class MediaContentObserver extends ContentObserver {
-
- private Uri mContentUri;
-
- public MediaContentObserver(Uri contentUri, Handler handler) {
- super(handler);
- mContentUri = contentUri;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- Log.d(TAG, mContentUri.toString());
- handleMediaContentChange(mContentUri);
- }
- }
- }
日志:
- D/Screenshot: content://media/external/images/media
- D/Screenshot: /storage/emulated/0/Pictures/Screenshots/Screenshot_2016-12-19-11-24-02.png 1482117842287
注意事项:
目前这是在网上搜索到的关于截屏监听方法的总结,如果大家还有什么比较好的监听方法,欢迎分享。
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。