使用FileObserver Android仅检测屏幕截图 [英] Detect only screenshot with FileObserver Android
问题描述
我目前正在为Android开发一个应用程序,想知道如何检测屏幕截图.我尝试使用FileObserver,但问题是检测到所有事件(当设备进入睡眠,消息等状态时).如何仅检测屏幕截图?
I am currently developing an application for Android and wanted to know how to detect a screenshot. I tried with FileObserver but the problem is that all events are detected ( when device goes into sleep, message, etc. ) . How to detect only screenshot ?
提前谢谢!
推荐答案
您如何使用FileObserver
检测屏幕快照的创建?使用FileObserver
时,仅监视屏幕快照目录中的文件创建事件.
How did you use FileObserver
to detect screen shot creation? When using FileObserver
, only monitor the file creation event in screen shot directory.
String path = Environment.getExternalStorageDirectory()
+ File.separator + Environment.DIRECTORY_PICTURES
+ File.separator + "Screenshots" + File.separator;
Log.d(TAG, path);
FileObserver fileObserver = new FileObserver(path, FileObserver.CREATE) {
@Override
public void onEvent(int event, String path) {
Log.d(TAG, event + " " + path);
}
};
fileObserver.startWatching();
别忘了声明访问SD卡中内容的相应权限.
Don't forget to declare corresponding permissions to access content in SD card.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
检测屏幕快照的另一种解决方案是使用ContentObserver
,因为在屏幕快照之后将有一条记录插入到系统媒体数据库中.以下是使用ContentObserver
监视事件的代码段.通过使用ContentObserver
,不必声明write/read external storage
权限,但是您必须对文件名进行一些过滤以确保它是屏幕截图事件.
Another solution to detect the screen shot is using ContentObserver
, because there will be a record inserted to the system media database after screen shot. Following is the code snippet using ContentObserver
to monitor the event. By using ContentObserver
, it's not necessary to declare write/read external storage
permissions, but you have to do some filters on the file name to make sure it's a screen shot event.
HandlerThread handlerThread = new HandlerThread("content_observer");
handlerThread.start();
final Handler handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
getContentResolver().registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
new ContentObserver(handler) {
@Override
public boolean deliverSelfNotifications() {
Log.d(TAG, "deliverSelfNotifications");
return super.deliverSelfNotifications();
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
Log.d(TAG, "onChange " + uri.toString());
if (uri.toString().matches(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + "/[0-9]+")) {
Cursor cursor = null;
try {
cursor = getContentResolver().query(uri, new String[] {
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA
}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
final String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
final String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// TODO: apply filter on the file name to ensure it's screen shot event
Log.d(TAG, "screen shot added " + fileName + " " + path);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
super.onChange(selfChange, uri);
}
}
);
已更新
如果使用第二种方法,则必须在Android M版本之后请求READ_EXTERNAL_STORAGE
,否则它将抛出SecurityException
.有关如何请求运行时权限的更多信息,请在此处.
If you use second method, you have to request READ_EXTERNAL_STORAGE
after version Android M, otherwise it will throw SecurityException
. For more information how to request runtime permission, refer here.
这篇关于使用FileObserver Android仅检测屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!