1.在 Application onCreate 方法设置 activity 生命周期监听

package com.example.myscreenshot;import android.app.Activity;
import android.app.Application;
import android.os.Bundle;public class MyApp extends Application {private static MyApp sInstance;private Activity activeActivity;//应用中显示的 activitypublic static MyApp getInstance() {return sInstance;}@Overridepublic void onCreate() {super.onCreate();sInstance=this;initActivityLifecycleCallbacks(this);}//全局监听 activity 生命周期private void initActivityLifecycleCallbacks(Application application) {application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {activeActivity = activity;}@Overridepublic void onActivityStarted(Activity activity) {activeActivity = activity;}@Overridepublic void onActivityResumed(Activity activity) {activeActivity = activity;}@Overridepublic void onActivityPaused(Activity activity) { }@Overridepublic void onActivityStopped(Activity activity) { }@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) { }@Overridepublic void onActivityDestroyed(Activity activity) { }});}//获取当前显示的activitypublic Activity getActiveActivity() {return activeActivity;}
}

2.在 MainActivity 初始化 文件监听

package com.example.myscreenshot;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;public class MainActivity extends AppCompatActivity {private static final int REQUEST_PERMISSION_CODE = 100;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);Log.e("ScreenShotHelper", "onActivityResult=requestCode=" + requestCode);if (requestCode == REQUEST_PERMISSION_CODE) {ScreenShotHelper.getInstance().registerListener(this);}}@Overrideprotected void onDestroy() {super.onDestroy();ScreenShotHelper.getInstance().unregisterListener();}
}

3.监听截屏

package com.example.myscreenshot;import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;import androidx.core.app.ActivityCompat;public class ScreenShotHelper {private final String TAG=getClass().getName();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", "snap", "截屏"};/*** 读取媒体数据库时需要读取的列*/private static final String[] MEDIA_PROJECTIONS = {MediaStore.Images.ImageColumns.DATA,MediaStore.Images.ImageColumns.DATE_TAKEN,MediaStore.Images.ImageColumns.DATE_ADDED,};/*** 内部存储器内容观察者*/private ContentObserver mInternalObserver;/*** 外部存储器内容观察者*/private ContentObserver mExternalObserver;private ContentResolver mResolver;private String lastData;private Handler mHandler;private static class Instance {static ScreenShotHelper mInstance = new ScreenShotHelper();}public static ScreenShotHelper getInstance() {return Instance.mInstance;}/*** 注册监听* @param mainActivity*/public void registerListener(MainActivity mainActivity) {//上下文mHandler = new Handler(mainActivity.getMainLooper());// 初始化mInternalObserver = new MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, null);mExternalObserver = new MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null);mResolver = mainActivity.getContentResolver();// 添加监听mResolver.registerContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, true, mInternalObserver);mResolver.registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mExternalObserver);}//注销监听public void unregisterListener() {if (mResolver != null) {mResolver.unregisterContentObserver(mInternalObserver);mResolver.unregisterContentObserver(mExternalObserver);}}private void handleMediaContentChange(Uri contentUri) {Cursor cursor = null;try {// 数据改变时查询数据库中最后加入的一条数据cursor = mResolver.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);int dateAddIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_ADDED);// 获取行数据final String data = cursor.getString(dataIndex);long dateTaken = cursor.getLong(dateTakenIndex);long dateAdded = cursor.getLong(dateAddIndex);if (data.length() > 0) {if (TextUtils.equals(lastData, data)) {//更改资源文件名也会触发,并且传递过来的是之前的截屏文件,所以只对分钟以内的有效if (System.currentTimeMillis() - dateTaken < 3 * 3600) {mHandler.removeCallbacks(shotCallBack);mHandler.postDelayed(shotCallBack, 500);}} else if (dateTaken == 0 || dateTaken == dateAdded * 1000) {mHandler.removeCallbacks(shotCallBack);} else if (checkScreenShot(data)) {mHandler.removeCallbacks(shotCallBack);lastData = data;mHandler.postDelayed(shotCallBack, 500);}}} catch (Exception e) {Log.e(TAG, "ex==" + e.getMessage());} finally {if (cursor != null && !cursor.isClosed()) {cursor.close();}}}private Runnable shotCallBack = new Runnable() {@Overridepublic void run() {final String path = lastData;if (path != null && path.length() > 0) {Log.e(TAG, "run=path==" + path);//逻辑处理区Dialog dialog=new Dialog(MyApp.getInstance().getActiveActivity());ImageView imageView = new ImageView(MyApp.getInstance().getActiveActivity());imageView.setImageBitmap(BitmapFactory.decodeFile(path));dialog.setContentView(imageView);dialog.show();}}};/*** 根据包含关键字判断是否是截屏*/private boolean checkScreenShot(String data) {if (data == null || data.length() < 2) {return false;}data = data.toLowerCase();for (String keyWork : KEYWORDS) {if (data.contains(keyWork)) {return true;}}return false;}private class MediaContentObserver extends ContentObserver {private Uri mContentUri;private long mLastTime;MediaContentObserver(Uri contentUri, Handler handler) {super(handler);mContentUri = contentUri;}@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);try {//满足以下条件才去查询:1.应用是否可见 2.读写权限 是否已开启 3.是否回调多次(某些机型会出现)boolean isVisible = MyApp.getInstance().getActiveActivity() != null && MyApp.getInstance().getActiveActivity().getWindow().getDecorView().getVisibility() == View.VISIBLE;//应用是否可见boolean isGranted = isGrantedPermission(MyApp.getInstance().getActiveActivity());//读写权限 是否已开启boolean isFast = (System.currentTimeMillis() - mLastTime) > 3000;//是否回调多次(某些机型会出现)Log.e(TAG, "onChange==" + selfChange + ",activeActivity=" + MyApp.getInstance().getActiveActivity().getClass().getName() + ",isVisible=" + isVisible + ",isGranted=" + isGranted + ",isFast=" + isFast);if (isVisible && isGranted && isFast) {handleMediaContentChange(mContentUri);mLastTime = System.currentTimeMillis();}} catch (Exception e) {Log.e(TAG, "ex==" + e.getMessage());}}}private boolean isGrantedPermission(Activity activity){return ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;}
}

4. AndroidManifest.xml 文件 设置 读写权限

BitmapFactory.decodeFile(path) 高版本需要此项:android:requestLegacyExternalStorage="true"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myscreenshot"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><applicationandroid:requestLegacyExternalStorage="true"android:name=".MyApp"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

Demo 下载地址:https://download.csdn.net/download/qq_29364417/21641402

Android app内截屏监听相关推荐

  1. Android App内截屏监控及涂鸦功能实现

    Android App内截屏监控及涂鸦功能实现 Android截屏功能是一个常用的功能,可以方便的用来分享或者发送给好友,本文介绍了如何实现app内截屏监控功能,当发现用户在我们的app内进行了截屏操 ...

  2. Android 截屏监听(截图分享功能实现)

    具体来说就是,检测到了用户在应用内有截图,弹出一个分享界面, 在截图下方添加一个二维码,进行分享. ●●●  前言 Android系统没有直接对截屏事件监听的接口,也没有广播,只能自己动手来丰衣足食, ...

  3. Android App中监听系统截屏(截屏监听功能)

    功能需求: App内截屏监控功能,当发现用户在我们的app内进行了截屏操作时,进行对图片的二次操作,例如添加二维码,公司logo等一系列操作. 首先来app界面图及截屏监听图添加效果图 主要是利用内容 ...

  4. Android系统截屏监听工具

    Android系统截屏监听工具 做系统截屏通知的时候,找了很多资料,测试后发现要做挺多机型适配的,而且有时候会没有监听到,有时候又监听到多次,不能实现想要的效果.一下是最终的解决方案,已在足够多的手机 ...

  5. 2022-10-09 Android app禁止截屏方法 和 在禁止截屏的情况下录制屏幕

    一.APP有时候为了保护用户的隐私安全会禁止用户录屏和截屏,比如金融类的app等.可以在app的onCreate方法中添加这么一段代码 1.代码 //禁止app录屏和截屏getWindow().set ...

  6. 云闪付APP内嵌H5监听左上角X关闭事件

    最近在做云闪付蓝牙对接,遇到的一个问题. 需求 用户进入云闪付APP内嵌 H5页面调用接口连上蓝牙后,可能不想支付使用,或其他原因,随手关闭左上角X关闭浏览器,这时需要监听这个动作,断开蓝牙连接,不然 ...

  7. 详细讲解安卓截屏监听操作

    需求 项目中有时会遇到监听用户截屏操作的需求,应用场景也比较丰富. eg. 1: 某个隐私页面禁止截屏,当发现用户截屏后,删除该截屏文件: eg. 2: 当用户截屏时,可能是需要进行分享,意见反馈等操 ...

  8. iOS录屏和截屏监听(以及出现的bug)

    需求: 出于项目安全性方面的考虑增加保护,需要在APP内敏感页面输入框做防用户截屏录屏的功能 截屏 应用中只会收到已经截屏的通知并没办法干预不能截屏,所以截屏我们只能做到提示的作用 做法: 在需要防止 ...

  9. android App内监听截图加二维码

    Android截屏功能是一个常用的功能,可以方便的用来分享或者发送给好友,本文介绍了如何实现app内截屏监控功能,当发现用户在我们的app内进行了截屏操作时,进行对图片的二次操作,例如添加二维码,公司 ...

最新文章

  1. 谈谈Linux打补丁的原理以及如何判别打补丁的错误 --- 从补丁学内核
  2. 考研英语二大纲22年考研
  3. linux mkdir 系统调用,Linux Rootkit 系列四:对于系统调用挂钩方法的补充
  4. 2019 年上万篇论文发表,这 14 篇脱颖而出!
  5. Halcon和Visionpro的对比
  6. win11如何禁用后台应用权限 Windows11禁用后台应用权限的设置方法
  7. 在条码打印软件中怎样批量导入图片
  8. 分享一个自己写的QT小游戏-玛丽奥医生
  9. 五、鼎捷T100生产管理之报工
  10. 什么是ACL访问控制列表?它们的匹配机制是什么?
  11. Selenium操作cookie绕过验证码登陆实战
  12. 拒退10万保证金 哈啰杨磊被限制消费 公司回应正在申请解除
  13. 简单版捕鱼达人的制做
  14. 运行 c++ 程序出现“Failed to execute ”.exe“ Error 0:操作成功完成
  15. 前端调用微信扫一扫不触发事件,没有任何反应
  16. 这一次,Google 终于对 Web 自动化下手了!
  17. 盐城北大青鸟东台基地开展春季游学活动
  18. 2019牛客多校第六场 E Androgynos
  19. 国外变电站3d可视化技术发展_变电站3D可视化运维管理!
  20. Web APIs第01天笔记——Web API介绍

热门文章

  1. ORACLE错误代码对照表
  2. php实现aes ecb模式加密,PHP、Python、Java的AES ECB加密实现-Fun言
  3. (转)DDD CQRS和Event Sourcing的案例:足球比赛
  4. CISA 考试大纲及考点
  5. C++复习:对C的拓展
  6. Solidworks机构运动仿真
  7. linux 时钟分频,浅析AD9522时钟分频电路原理
  8. iPhone苹果手机语音备忘录M4A文件损坏显示时长无法播放修复方法
  9. 第一代网络计算机功能,在计算机网络的发展历程中,第一代计算机网路主要实现什么功能...
  10. 非乘a非b_给你28万 ,你买B+级车还是豪华入门车?