首页 > 编程知识 正文

安卓实时监听,Android 监听

时间:2023-05-03 15:52:49 阅读:265435 作者:2710

一、源代码 package com.study.capturescreenlistenerimport android.annotation.SuppressLintimport android.content.ContentResolverimport android.content.Contextimport android.net.Uriimport android.os.Handlerimport android.os.HandlerThreadimport android.os.Looperimport android.provider.MediaStoreimport android.util.Logimport android.widget.Toastimport com.study.capturescreenlistener.contentobserver.UriObserver/** * 判断是否被截屏或者录屏。 * 因为Android并没有提供监听截屏或者录屏的api,但是可以知道的是不管截屏或者录屏生成的文件都会被保存到手机中, * 一般保存的文件夹命名如下KEYWORDS所示,所以可以通过监听相关的URI的的内容,从而达到监听截屏或者录屏的问题。 * 添加一个内容观察者就好了,录制屏或者截图都会调用这个。 * 如果添加两个内容观察者的话change方法将会被调用两次 */@SuppressLint("StaticFieldLeak")object CaptureScreenUtils : UriObserver.UriChangeListener { private var contentResolver: ContentResolver? = null// private var videoObserver: UriObserver private var imageObserver: UriObserver private var mainHandler:Handler private var context: Context? = null private val KEYWORDS = arrayOf( "screenshot", "screen_shot", "screen-shot", "screen shot", "screencapture", "screen_capture", "screen-capture", "screen capture", "screencap", "screen_cap", "screen-cap", "screen cap" ) private val screenPicture = mutableSetOf<String>() init { val handlerThread = HandlerThread("uriobserver") handlerThread.start() val handler = Handler(handlerThread.looper) mainHandler = Handler(Looper.getMainLooper())// videoObserver = UriObserver(handler)// videoObserver.setOnUriChangeListener(this) imageObserver = UriObserver(handler) imageObserver.setOnUriChangeListener(this) } override fun change(selfChange: Boolean, uri: Uri) { contentResolver?.let { it -> it.query( uri, null, null, null, MediaStore.Images.ImageColumns.DATE_ADDED + " desc limit 1" )?.takeIf { cursor -> cursor.moveToFirst() }?.use { cursor -> var path = "" var dateAdd = "" var relativePath = "" var type = "" val uriPath = uri.path?.toLowerCase() ?: "" Log.e(javaClass.simpleName, "uriPath=====$uriPath, uri=====$uri") when { uriPath.contains("video") -> { //录屏 type = "video" val dataIndex = cursor.getColumnIndex(MediaStore.Video.VideoColumns.DATA) path = cursor.getString(dataIndex).toLowerCase() val relativePathIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.RELATIVE_PATH) relativePath = cursor.getString(relativePathIndex) val dateAddIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_ADDED) dateAdd = cursor.getString(dateAddIndex) } uriPath.contains("images") -> {//截屏 type = "images" val dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA) path = cursor.getString(dataIndex).toLowerCase() val relativePathIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.RELATIVE_PATH) relativePath = cursor.getString(relativePathIndex) val dateAddIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_ADDED) dateAdd = cursor.getString(dateAddIndex) } else -> type = "未知" } Log.e(javaClass.simpleName, "type=====$type, data=====$path, uri=====$uri") Log.e( javaClass.simpleName, "type=====$type, relativePath=====$relativePath, uri=====$uri" ) Log.e(javaClass.simpleName, "type=====$type, dateAdd=====$dateAdd, uri=====$uri") for (keyword in KEYWORDS) { if (path.contains(keyword)) { //还在子线程中,在这里处理发现被录屏或者截屏的逻辑 mainHandler.post { Toast.makeText(context,"当前被截屏了",Toast.LENGTH_SHORT).show() } break } } } ?: Toast.makeText(this.context, "数据为空", Toast.LENGTH_SHORT).show() } } fun register(context: Context) { this.context = context val contentResolver = context.contentResolver contentResolver?.let { contentResolver -> this.contentResolver = contentResolver// contentResolver.registerContentObserver(// MediaStore.Video.Media.EXTERNAL_CONTENT_URI,// false,// videoObserver// ) contentResolver.registerContentObserver( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, imageObserver ) } } fun unregister() { contentResolver?.let {// it.unregisterContentObserver(videoObserver) it.unregisterContentObserver(imageObserver) } contentResolver = null context = null }} 源码地址

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。