diff --git a/android/gradle.properties b/android/gradle.properties index 2a55193..84eebc7 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -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 diff --git a/android/src/main/java/com/reactnativedetector/ScreenshotDetectionDelegate.kt b/android/src/main/java/com/reactnativedetector/ScreenshotDetectionDelegate.kt index b8964d3..a7fee51 100644 --- a/android/src/main/java/com/reactnativedetector/ScreenshotDetectionDelegate.kt +++ b/android/src/main/java/com/reactnativedetector/ScreenshotDetectionDelegate.kt @@ -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) { + 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() -} \ No newline at end of file + fun onScreenCaptured(path: String) + fun onScreenCapturedWithDeniedPermission() +}