Tôi đã thực hiện dự án git cho ảnh chụp màn hình android.
Tôi đã sử dụng Trình theo dõi nội dung.
làm việc tốt từ API 14 lên phiên bản gần đây
Bạn có thể kiểm tra here
1.ScreenShotContentObserver .class
(ảnh chụp màn hình ban đầu xóa -> thông báo cho ảnh chụp màn hình chụp và đưa ảnh chụp màn hình bitmap)
public class ScreenShotContentObserver extends ContentObserver {
private final String TAG = this.getClass().getSimpleName();
private static final String[] PROJECTION = new String[]{
MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATA,
MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.ImageColumns._ID
};
private static final long DEFAULT_DETECT_WINDOW_SECONDS = 10;
private static final String SORT_ORDER = MediaStore.Images.Media.DATE_ADDED + " DESC";
public static final String FILE_POSTFIX = "FROM_ASS";
private static final String WATERMARK = "Scott";
private ScreenShotListener mListener;
private ContentResolver mContentResolver;
private String lastPath;
public ScreenShotContentObserver(Handler handler, ContentResolver contentResolver, ScreenShotListener listener) {
super(handler);
mContentResolver = contentResolver;
mListener = listener;
}
@Override
public boolean deliverSelfNotifications() {
Log.e(TAG, "deliverSelfNotifications");
return super.deliverSelfNotifications();
}
@Override
synchronized public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//above API 16 Pass~!(duplicated call...)
return;
}
Log.e(TAG, "[Start] onChange : " + selfChange);
try {
process(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Log.e(TAG, "[Finish] general");
} catch (Exception e) {
Log.e(TAG, "[Finish] error : " + e.toString(), e);
}
}
@Override
synchronized public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
Log.e(TAG, "[Start] onChange : " + selfChange + "/uri : " + uri.toString());
if (uri.toString().startsWith(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString())) {
try {
process(uri);
Log.e(TAG, "[Finish] general");
} catch (Exception e) {
Log.e(TAG, "[Finish] error : " + e.toString(), e);
}
} else {
Log.e(TAG, "[Finish] not EXTERNAL_CONTENT_URI ");
}
}
public void register() {
Log.d(TAG, "register");
mContentResolver.registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, this);
}
public void unregister() {
Log.d(TAG, "unregister");
mContentResolver.unregisterContentObserver(this);
}
private boolean process(Uri uri) throws Exception {
Data result = getLatestData(uri);
if (result == null) {
Log.e(TAG, "[Result] result is null!!");
return false;
}
if (lastPath != null && lastPath.equals(result.path)) {
Log.e(TAG, "[Result] duplicate!!");
return false;
}
long currentTime = System.currentTimeMillis()/1000;
if (matchPath(result.path) && matchTime(currentTime, result.dateAdded)) {
lastPath = result.path;
Uri screenUri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + "/" + result.id);
Log.e(TAG, "[Result] This is screenshot!! : " + result.fileName + " | dateAdded : " + result.dateAdded + "/" + currentTime);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContentResolver, screenUri);
Bitmap copyBitmap = bitmap.copy(bitmap.getConfig(), true);
bitmap.recycle();
int temp = mContentResolver.delete(screenUri, null, null);
Log.e(TAG, "Delete Result : " + temp);
if (mListener != null) {
mListener.onScreenshotTaken(copyBitmap, result.fileName);
}
return true;
} else {
Log.e(TAG, "[Result] No ScreenShot : " + result.fileName);
}
return false;
}
private Data getLatestData(Uri uri) throws Exception {
Data data = null;
Cursor cursor = null;
try {
cursor = mContentResolver.query(uri, PROJECTION, null, null, SORT_ORDER);
if (cursor != null && cursor.moveToFirst()) {
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID));
String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
long dateAdded = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
if (fileName.contains(FILE_POSTFIX)) {
if (cursor.moveToNext()) {
id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID));
fileName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
dateAdded = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
} else {
return null;
}
}
data = new Data();
data.id = id;
data.fileName = fileName;
data.path = path;
data.dateAdded = dateAdded;
Log.e(TAG, "[Recent File] Name : " + fileName);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return data;
}
private boolean matchPath(String path) {
return (path.toLowerCase().contains("screenshots/") && !path.contains(FILE_POSTFIX));
}
private boolean matchTime(long currentTime, long dateAdded) {
return Math.abs(currentTime - dateAdded) <= DEFAULT_DETECT_WINDOW_SECONDS;
}
class Data {
long id;
String fileName;
String path;
long dateAdded;
}
}
Util.class
public static void saveImage(Context context, Bitmap bitmap, String title) throws Exception {
OutputStream fOut = null;
title = title.replaceAll(" ", "+");
int index = title.lastIndexOf(".png");
String fileName = title.substring(0, index) + ScreenShotContentObserver.FILE_POSTFIX + ".png";
final String appDirectoryName = "Screenshots";
final File imageRoot = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appDirectoryName);
imageRoot.mkdirs();
final File file = new File(imageRoot, fileName);
fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "XXXXX");
values.put(MediaStore.Images.Media.DESCRIPTION, "description here");
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.ImageColumns.BUCKET_ID, file.hashCode());
values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName());
values.put("_data", file.getAbsolutePath());
ContentResolver cr = context.getContentResolver();
Uri newUri = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, newUri));
}
'FileObserver' không làm việc cho tôi, nhưng cách hoạt động ContentProvider , mặc dù cần một số sửa đổi. Chúng ta cần nội dung hình ảnh truy vấn với thứ tự 'DESC', để có được hình ảnh mới nhất gây ra sự kiện' onChange' này. – Piasy
ContentObserver cho ngoại lệ "java.lang.SecurityException: Permission từ chối: đọc com.android.providers.media.MediaProvider nội dung uri: // media/bên ngoài/images/phương tiện truyền thông từ pid = 31.855, uid = 10341 đòi hỏi android.permission. READ_EXTERNAL_STORAGE, hoặc grantUriPermission()", nếu Permission lưu trữ không được cấp tại MARSHMELLOW – shanraisshan
@shanrais Có, bạn nên kiểm tra và yêu cầu sự cho phép thời gian chạy tại Android M. Hãy suy http://developer.android.com/training/permissions/ request.html để biết thêm thông tin. – alijandro