Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 13 Support and bug fixes #68

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Detector_kotlinVersion=1.3.50
Detector_kotlinVersion=1.6.10
Detector_compileSdkVersion=28
Detector_buildToolsVersion=28.0.3
Detector_targetSdkVersion=28
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,82 +5,109 @@ import android.content.Context
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.os.Build
import android.provider.MediaStore
import android.content.pm.PackageManager
import android.Manifest.permission
import android.Manifest.permission.READ_EXTERNAL_STORAGE
import androidx.core.content.ContextCompat
import android.database.Cursor
import android.util.Log
import java.lang.Exception


class ScreenshotDetectionDelegate(val context: Context, val listener: ScreenshotDetectionListener) {
lateinit var contentObserver: ContentObserver

var isListening = false
var previousPath = ""

fun startScreenshotDetection() {
contentObserver = object : ContentObserver(Handler()) {
override fun onChange(selfChange: Boolean, uri: Uri?) {
super.onChange(selfChange, uri)
if (isReadExternalStoragePermissionGranted() && uri != null) {
val path = getFilePathFromContentResolver(context, uri)
if (path != null && isScreenshotPath(path)) {
previousPath = path
onScreenCaptured(path!!)
}
} else {
onScreenCapturedWithDeniedPermission()
}
}
lateinit var contentObserver: ContentObserver

var isListening = false
var previousPath = ""

fun startScreenshotDetection() {
val contentObserver: ContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
override fun onChange(selfChange: Boolean, uri: Uri?) {

super.onChange(selfChange, uri)
if (!isReadExternalStoragePermissionGranted()) {
onScreenCapturedWithDeniedPermission()
}

context.contentResolver.registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
contentObserver)
isListening = true
if (uri != null) {
val path = getFilePathFromContentResolver(context, uri)
if (path != null && isScreenshotPath(path)) {
previousPath = path.toLowerCase().substring(path.toLowerCase().lastIndexOf("screenshot"))
onScreenCaptured(path!!)
}
}
}
}

fun stopScreenshotDetection() {
context.getContentResolver().unregisterContentObserver(contentObserver)
isListening = false
}
context.contentResolver.registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
contentObserver)
isListening = true
}

private fun onScreenCaptured(path: String) {
listener.onScreenCaptured(path)
}
fun stopScreenshotDetection() {
val contentObserver: ContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
override fun onChange(selfChange: Boolean, uri: Uri?) {

super.onChange(selfChange, uri)
if (!isReadExternalStoragePermissionGranted()) {
onScreenCapturedWithDeniedPermission()
}

private fun onScreenCapturedWithDeniedPermission() {
listener.onScreenCapturedWithDeniedPermission()
if (uri != null) {
val path = getFilePathFromContentResolver(context, uri)
if (path != null && isScreenshotPath(path)) {
previousPath = path.toLowerCase().substring(path.toLowerCase().lastIndexOf("screenshot"))
onScreenCaptured(path!!)
}
}
}
}

private fun isScreenshotPath(path: String?): Boolean {
return path != null && path.toLowerCase().contains("screenshots") && previousPath != path
context.getContentResolver().unregisterContentObserver(contentObserver)
isListening = false
}

private fun onScreenCaptured(path: String) {
listener.onScreenCaptured(path)
}

private fun onScreenCapturedWithDeniedPermission() {
listener.onScreenCapturedWithDeniedPermission()
}

private fun isScreenshotPath(path: String?): Boolean {
return path != null && path.toLowerCase().contains("screenshots") && (previousPath == "" || !path.toLowerCase().contains(previousPath))
}

private fun getFilePathFromContentResolver(context: Context, uri: Uri): String? {
try {
private fun getFilePathFromContentResolver(context: Context, uri: Uri): String? {
try {

val cursor = context.contentResolver.query(uri, arrayOf(MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATA), null, null, null)
if (cursor != null && cursor.moveToFirst()) {
val path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
cursor.close()
return path
}
} catch (e: Exception) {
val cursor = context.contentResolver.query(uri, arrayOf(MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATA), null, null, null)
if (cursor != null && cursor.moveToFirst()) {
val path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
cursor.close()
return path
}
} catch (e: Exception) {

}
return null
}
return null
}

private fun isReadExternalStoragePermissionGranted(): Boolean {
val isAndroid13OrAbove = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU

private fun isReadExternalStoragePermissionGranted(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
if (isAndroid13OrAbove) {
psbdgr8 marked this conversation as resolved.
Show resolved Hide resolved
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED
}
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
}
}

interface ScreenshotDetectionListener {
fun onScreenCaptured(path: String)
fun onScreenCapturedWithDeniedPermission()
}
fun onScreenCaptured(path: String)
fun onScreenCapturedWithDeniedPermission()
}