I am trying to detect screenshot on an Android app. I am using contentObserver to detect the change in the media directory, not using FileObserver because of known issue with it on Android M.
Here is the code snippet:
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 void onChange(boolean selfChange, Uri uri) {
Log.d(TAG, "URL : " + uri.toString());
//Code to query using content resolver
if (uri.toString().matches(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString())) {
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()) {
//Logic to filter if it is a screenshot file
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
super.onChange(selfChange, uri);
}
}
);
When onChange is called (after screenshot is taken / any other changes in media folder) the URI is "content://media/external/images/media" instead of the whole URI containing the resource ID as well, something like: content://media/external/images/media/12345, this happens for most of the devices I tried - Moto G3 (Android 6.0.1), Nexus 5 (Android 6.0), where as, I get the whole URI (including ID) on Samsung S5 running 6.0.1.
Is this is a known issue?
How can I get the ID as well?
It is not an optimized solution to iterate over the whole media directory and find if a screenshot was taken when the app was active, rather getting the resource ID in the content URI would solve the problem as we can directly fetch the file's path and detect if it is a screenshot file, the observer still observes for all the media content changes though (for example, it also observes a WhatsApp image download happening in the background).