当前位置:   article > 正文

android 广播监听截屏,Android 应用监听截屏操作

images.imagecolumns.date_taken

最近要求做一个app内监听截屏,然后调用自己的分享功能。

结合我的业务实际,以下是完整代码。

0.局部变量

private String data;//截图图片路径

private Handler mUiHandler;

private MediaContentObserver mInternalObserver;

private MediaContentObserver mExternalObserver;

private static final String[] MEDIA_PROJECTIONS = {

// MediaStore.Images.ImageColumns.WIDTH,

// MediaStore.Images.ImageColumns.HEIGHT,

MediaStore.Images.ImageColumns.DATA,

MediaStore.Images.ImageColumns.DATE_TAKEN

};

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 class MediaContentObserver extends ContentObserver {

private Uri mediaContentUri; // 需要观察的Uri

public MediaContentObserver(Uri contentUri, Handler handler) {

super(handler);

mediaContentUri = contentUri;

}

@Override

public void onChange(boolean selfChange) {

super.onChange(selfChange);

// 处理媒体数据库反馈的数据变化

handleMediaContentChange(mediaContentUri);

}

}

2.注册监听

private void initMediaContentObserver() {

// 运行在 UI 线程的 Handler, 用于运行监听器回调

mUiHandler = new Handler(Looper.getMainLooper());

// 创建内容观察者,包括内部存储和外部存储

mInternalObserver = new MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, mUiHandler);

mExternalObserver = new MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mUiHandler);

// 注册内容观察者

getContentResolver().registerContentObserver(

MediaStore.Images.Media.INTERNAL_CONTENT_URI, false, mInternalObserver);

getContentResolver().registerContentObserver(

MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, mExternalObserver);

}

3.处理数据

private void handleMediaContentChange(Uri contentUri) {

Cursor cursor = null;

try {

// 数据改变时查询数据库中最后加入的一条数据

cursor = getContentResolver().query(contentUri,

MEDIA_PROJECTIONS,

null, null, MediaStore.Images.ImageColumns.DATE_ADDED + " desc limit 1");

if (cursor == null) return;

if (!cursor.moveToFirst()) return;

// cursor.getColumnIndex获取数据库列索引

int dateTakenIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN);

long dateTaken = cursor.getLong(dateTakenIndex); // 图片生成时间

//因为该监听也会监听到删除截图的操作,所以判断最后一张图的时间和现在时间,如果相差8s内,则认为是刚截图

//国内部分机器刚截的图并不是马上就写进去,而是放在内存了,8s是一个经验值

if (System.currentTimeMillis() - dateTaken > 8000) return;

int dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);

data = cursor.getString(dataIndex); // 图片存储地址

// int width = 0;

// int height = 0;

// int widthIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.WIDTH);

// int heightIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.HEIGHT);

// width = cursor.getInt(widthIndex); // 获取图片高度

// height = cursor.getInt(heightIndex); // 获取图片宽度

// 处理获取到的第一行数据

handleMediaRowData(data);

} catch (AndroidRuntimeException e) {

//1.Android7.0以下机器要求用FLAG_ACTIVITY_NEW_TASK启动

//2.部分机器写入截图实在是太慢,给个800ms延迟

mUiHandler.postDelayed(() ->

startActivity(ShareCapturePicActivity.newIntent(this, data,

Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)), 800);

e.printStackTrace();

} finally {

if (cursor != null && !cursor.isClosed()) {

cursor.close();

}

}

}

//处理监听到的资源

private void handleMediaRowData(String data) {

if (checkScreenShot(data)) {

startActivity(ShareCapturePicActivity.newIntent(this, data, Intent.FLAG_ACTIVITY_SINGLE_TOP));

}

}

//判断是否是截屏

private boolean checkScreenShot(String data) {

data = data.toLowerCase();

// 判断图片路径是否含有指定的关键字之一, 如果有, 则认为当前截屏了

for (String keyWork : KEYWORDS) {

if (data.contains(keyWork)) {

return true;

}

}

return false;

}

顺带提一下

onNewIntent的周期

第一次singleTop启动,正常onCreate--start--resume

后续就是 onNewIntent---start--resume

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/418783
推荐阅读
相关标签
  

闽ICP备14008679号