### Kotlin: Start Screen Recording and Handle Permissions Source: https://context7.com/nain57/smart-autoclicker/llms.txt Initiates screen recording using Android's MediaProjection API and handles the user's permission response. It then starts the detection process once the recording is active. ```kotlin import android.content.Context import android.content.Intent import android.app.Activity import android.util.Log import androidx.lifecycle.lifecycleScope import com.example.smartautoclicker.DetectorEngine import com.example.smartautoclicker.DetectorState import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import javax.inject.Inject // Assume getSystemService, startActivityForResult, and lifecycleScope are available in the Activity/Fragment context // Assume REQUEST_MEDIA_PROJECTION is a defined request code // Initialize detector engine (injected via Hilt) @Inject lateinit var detectorEngine: DetectorEngine // 1. Start screen recording with MediaProjection permission // In a real Android component (Activity/Fragment): // val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager // val captureIntent = mediaProjectionManager.createScreenCaptureIntent() // startActivityForResult(captureIntent, REQUEST_MEDIA_PROJECTION) // Placeholder for starting the capture intent: fun requestMediaProjectionPermission(mediaProjectionManager: Any) { // val captureIntent = mediaProjectionManager.createScreenCaptureIntent() // startActivityForResult(captureIntent, REQUEST_MEDIA_PROJECTION) Log.i("Detector", "Requesting MediaProjection permission...") } // 2. Handle permission result and start recording // This function would be called from an Activity's onActivityResult or ActivityResultLauncher callback fun handleMediaProjectionResult(requestCode: Int, resultCode: Int, data: Intent?, detectorEngine: DetectorEngine, onRecordingStopped: () -> Unit) { val REQUEST_MEDIA_PROJECTION = 100 // Example request code if (requestCode == REQUEST_MEDIA_PROJECTION && resultCode == Activity.RESULT_OK) { detectorEngine.startScreenRecord( resultCode = resultCode, data = data!!, onRecordingStopped = onRecordingStopped ) // Wait for state to become RECORDING // This requires a CoroutineScope, e.g., from lifecycleScope // lifecycleScope.launch { // detectorEngine.state.collect { state -> // when (state) { // DetectorState.RECORDING -> { // // Recording started successfully, can now start detection // Log.i("Detector", "Recording started. Ready for detection.") // // startDetection() // Call your detection start function here // } // DetectorState.ERROR_NATIVE_DETECTOR_LIB_NOT_FOUND -> { // Log.e("Detector", "Native detection library not found.") // // showError("Native detection library not found") // Call your error handling function // } // else -> { /* Ignore other states for this example */ } // } // } // } } else { Log.e("Detector", "MediaProjection permission denied or failed. Result code: $resultCode") // Handle permission denial } } // Dummy classes and interfaces for compilation object DetectorState { const val RECORDING = 1; const val ERROR_NATIVE_DETECTOR_LIB_NOT_FOUND = 2; } class DetectorEngine { val state: kotlinx.coroutines.flow.StateFlow = kotlinx.coroutines.flow.MutableStateFlow(0).also { emit -> // Simulate state changes for demonstration Thread { Thread.sleep(1000) (emit as kotlinx.coroutines.flow.MutableStateFlow).value = DetectorState.RECORDING Thread.sleep(2000) (emit as kotlinx.coroutines.flow.MutableStateFlow).value = DetectorState.ERROR_NATIVE_DETECTOR_LIB_NOT_FOUND }.start() } fun startScreenRecord(resultCode: Int, data: Intent, onRecordingStopped: () -> Unit) { Log.d("DetectorEngine", "Starting screen record...") } fun stopScreenRecord() { Log.d("DetectorEngine", "Stopping screen record...") } fun startDetection(context: Context, scenario: Any, imageEvents: List, triggerEvents: List, progressListener: Any) { Log.d("DetectorEngine", "Starting detection...") } fun stopDetection() { Log.d("DetectorEngine", "Stopping detection...") } } class Context class Intent // Example usage simulation: // val detectorEngine = DetectorEngine() // requestMediaProjectionPermission(Any()) // handleMediaProjectionResult(100, Activity.RESULT_OK, Intent(), detectorEngine, { Log.w("Detector", "Recording stopped externally") }) ``` -------------------------------- ### Kotlin: Define and Start Image Detection Scenario Source: https://context7.com/nain57/smart-autoclicker/llms.txt Configures a detection scenario with image conditions and actions, then initiates the detection process. It requires scenario details, image event definitions, and a listener for progress updates. ```kotlin import android.content.Context import android.graphics.Rect import android.util.Log import com.example.smartautoclicker.* // Assume DetectorEngine, Scenario, ImageEvent, etc. are defined elsewhere // Dummy definitions for compilation class Identifier(val databaseId: Long) class Scenario(val id: Identifier, val name: String, val detectionQuality: Int, val randomize: Boolean, val keepScreenOn: Boolean) class ImageEvent(val id: Identifier, val scenarioId: Identifier, val name: String, val conditionOperator: Any, val priority: Int, val keepDetecting: Boolean, val conditions: List, val actions: List) class ImageCondition(val id: Identifier, val eventId: Identifier, val name: String, val priority: Int, val path: String, val area: Rect, val threshold: Int, val detectionType: Any, val shouldBeDetected: Boolean) class Click(val id: Identifier, val eventId: Identifier, val name: String, val priority: Int, val pressDuration: Long, val positionType: PositionType, val clickOnConditionId: Identifier) { enum class PositionType { ON_DETECTED_CONDITION } } object AND object WHOLE_SCREEN class ConditionsResult(val fulfilled: Boolean) class ScenarioProcessingListener { open fun onSessionStarted(context: Context, scenario: Scenario, imageEvents: List, triggerEvents: List) { Log.i("ScenarioListener", "Session Started") } open fun onImageEventProcessingCompleted(event: ImageEvent, results: ConditionsResult) { Log.d("ScenarioListener", "Event ${event.name} processed") } open fun onSessionEnded() { Log.i("ScenarioListener", "Session Ended") } } class TriggerEvent // Function to start detection fun startDetection(detectorEngine: DetectorEngine, applicationContext: Context) { val scenario = Scenario( id = Identifier(databaseId = 1), name = "Game Automation", detectionQuality = 600, // 400-1200, higher = slower but more accurate randomize = true, // Randomize action coordinates to avoid bot detection keepScreenOn = true ) val imageEvents = listOf( ImageEvent( id = Identifier(databaseId = 10), scenarioId = scenario.id, name = "Click Start Button", conditionOperator = AND, priority = 0, keepDetecting = false, // Stop after first match in this frame conditions = listOf( ImageCondition( id = Identifier(databaseId = 100), eventId = Identifier(databaseId = 10), name = "Start button visible", priority = 0, path = "/data/user/0/com.buzbuz.smartautoclicker/files/conditions/start_btn.png", area = Rect(100, 200, 300, 400), // Captured button area threshold = 5, // 0-100%, lower = stricter match detectionType = WHOLE_SCREEN, shouldBeDetected = true ) ), actions = listOf( Click( id = Identifier(databaseId = 1000), eventId = Identifier(databaseId = 10), name = "Click on detected button", priority = 0, pressDuration = 50L, positionType = Click.PositionType.ON_DETECTED_CONDITION, clickOnConditionId = Identifier(databaseId = 100) ) ) ) ) val progressListener = object : ScenarioProcessingListener() { override fun onSessionStarted(context: Context, scenario: Scenario, imageEvents: List, triggerEvents: List) { Log.i("Detection", "Session started with ${imageEvents.size} image events") } override fun onImageEventProcessingCompleted(event: ImageEvent, results: ConditionsResult) { Log.d("Detection", "Event ${event.name}: fulfilled=${results.fulfilled}") } override fun onSessionEnded() { Log.i("Detection", "Session ended") } } detectorEngine.startDetection( context = applicationContext, scenario = scenario, imageEvents = imageEvents, triggerEvents = emptyList(), progressListener = progressListener ) } // Dummy DetectorEngine for compilation class DetectorEngine { fun startScreenRecord(resultCode: Int, data: Intent, onRecordingStopped: () -> Unit) { Log.d("DetectorEngine", "Starting screen record...") } fun stopScreenRecord() { Log.d("DetectorEngine", "Stopping screen record...") } fun startDetection(context: Context, scenario: Scenario, imageEvents: List, triggerEvents: List, progressListener: ScenarioProcessingListener) { Log.d("DetectorEngine", "Starting detection...") } fun stopDetection() { Log.d("DetectorEngine", "Stopping detection...") } } // Example usage simulation: // val detectorEngine = DetectorEngine() // val appContext = Context() // startDetection(detectorEngine, appContext) ``` -------------------------------- ### Kotlin: ScenarioProcessor Initialization and Event Setup Source: https://context7.com/nain57/smart-autoclicker/llms.txt Initializes the ScenarioProcessor with various event configurations, including image detection conditions and trigger events with associated actions. It demonstrates how to define image paths, areas, thresholds, and timer-based conditions for automated task execution. Dependencies include image detection instances, scaling managers, and Android execution contexts. ```kotlin // Internal usage - typically created by DetectorEngine val scenarioProcessor = ScenarioProcessor( processingTag = "com.buzbuz.smartautoclicker", imageDetector = nativeDetectorInstance, scalingManager = scalingManager, randomize = true, // Add slight randomness to action coordinates imageEvents = listOf( ImageEvent( id = Identifier(databaseId = 1), scenarioId = Identifier(databaseId = 1), name = "Collect coins", conditionOperator = OR, // Match any condition priority = 0, keepDetecting = true, // Continue checking other events after match conditions = listOf( ImageCondition( id = Identifier(databaseId = 10), eventId = Identifier(databaseId = 1), name = "Gold coin visible", priority = 0, path = "/storage/conditions/gold_coin.png", area = Rect(50, 50, 150, 150), threshold = 8, detectionType = WHOLE_SCREEN, shouldBeDetected = true ), ImageCondition( id = Identifier(databaseId = 11), eventId = Identifier(databaseId = 1), name = "Silver coin visible", priority = 1, path = "/storage/conditions/silver_coin.png", area = Rect(45, 45, 145, 145), threshold = 8, detectionType = WHOLE_SCREEN, shouldBeDetected = true ) ), actions = listOf( Click( id = Identifier(databaseId = 100), eventId = Identifier(databaseId = 1), name = "Click coin", priority = 0, pressDuration = 50L, positionType = Click.PositionType.ON_DETECTED_CONDITION, clickOnConditionId = null // Will click on whichever condition matched ) ) ) ), triggerEvents = listOf( TriggerEvent( id = Identifier(databaseId = 2), scenarioId = Identifier(databaseId = 1), name = "Stop after 5 minutes", conditionOperator = AND, conditions = listOf( TimerReachedCondition( id = Identifier(databaseId = 20), eventId = Identifier(databaseId = 2), name = "5 minutes elapsed", timerValueMs = 300000L ) ), actions = listOf( ToggleEvent( id = Identifier(databaseId = 200), eventId = Identifier(databaseId = 2), name = "Disable coin collection", priority = 0, toggleType = ToggleType.DISABLE, toggleEventId = Identifier(databaseId = 1) ) ) ) ), bitmapSupplier = { path, width, height -> bitmapRepository.getImageConditionBitmap(path, width, height) }, androidExecutor = androidActionExecutor, unblockWorkaroundEnabled = false, onStopRequested = { Log.i("Processor", "Stop requested - all events disabled") stopScenario() }, progressListener = scenarioProgressListener ) // Start processing scenarioProcessor.onScenarioStart(applicationContext) // Process each screen frame lifecycleScope.launch { screenFrameFlow.collect { screenBitmap -> scenarioProcessor.process(screenBitmap) } } // Stop processing scenarioProcessor.onScenarioEnd() ``` -------------------------------- ### Define Automation Scenarios with Scenario Data Model Source: https://context7.com/nain57/smart-autoclicker/llms.txt The Scenario data model represents a complete automation setup, including configuration for detection quality, randomization, screen state, and event count. It can be persisted using Room database DAOs. The model includes properties for identification, naming, and behavior customization. ```kotlin // Create a new Smart Scenario val smartScenario = Scenario( id = Identifier(databaseId = 42), name = "Farming Bot v2", detectionQuality = 800, // 400-1200 range, affects detection speed/accuracy tradeoff randomize = true, // Randomizes click positions slightly to avoid detection keepScreenOn = true, // Prevents screen timeout during automation eventCount = 15 // Number of events in this scenario ) // Access scenario properties println("Running: ${smartScenario.name}") println("Quality: ${smartScenario.detectionQuality}") println("Contains ${smartScenario.eventCount} events") // Scenarios are persisted in Room database @Dao interface ScenarioDao { @Query("SELECT * FROM scenario_table WHERE id = :scenarioId") suspend fun getScenario(scenarioId: Long): ScenarioEntity @Insert suspend fun insertScenario(scenario: ScenarioEntity): Long @Update suspend fun updateScenario(scenario: ScenarioEntity) @Delete suspend fun deleteScenario(scenario: ScenarioEntity) } ``` -------------------------------- ### Kotlin: Native Image Detection with OpenCV Source: https://context7.com/nain57/smart-autoclicker/llms.txt Demonstrates using the NativeDetector for image pattern detection on screen captures. It covers initialization, setting screen bitmaps, defining detection parameters (image, dimensions, area, threshold), performing the detection, and handling results. Ensures proper resource management by releasing bitmaps and closing the detector. ```kotlin val detector = NativeDetector.newInstance() ?: run { Log.e("Detection", "Failed to load native detector library") return } try { detector.init() val screenBitmap: Bitmap = captureScreen() detector.setScreenBitmap(screenBitmap, metadata = "frame_001") val conditionBitmap = BitmapFactory.decodeFile("/path/to/button_image.png") val conditionWidth = 200 val conditionHeight = 100 val detectionArea = Rect(0, 0, 1080, 1920) val threshold = 10 val result: DetectionResult = detector.detectCondition( conditionBitmap = conditionBitmap, conditionWidth = conditionWidth, conditionHeight = conditionHeight, detectionArea = detectionArea, threshold = threshold ) when { result.isDetected -> { Log.i("Detection", "Found at (${result.position.x}, ${result.position.y})") Log.i("Detection", "Confidence: ${result.confidenceRate}%") } else -> { Log.d("Detection", "Not detected") } } detector.releaseScreenBitmap(screenBitmap) } finally { detector.close() } val minQuality = DETECTION_QUALITY_MIN // 400L ``` -------------------------------- ### Configure Image Detection Event with AND Logic (Kotlin) Source: https://context7.com/nain57/smart-autoclicker/llms.txt Sets up an ImageEvent where all specified ImageConditions must be met for the associated actions to trigger. This is useful for complex scenarios requiring multiple visual cues to be present or absent. Dependencies include image matching libraries and specific event/condition/action data classes. ```kotlin val clickButtonEvent = ImageEvent( id = Identifier(databaseId = 101), scenarioId = Identifier(databaseId = 42), name = "Click Play Button", conditionOperator = AND, // All conditions must match priority = 0, // Lower numbers execute first keepDetecting = false, // Stop processing other events after this matches enabledOnStart = true, // Event is active when scenario starts conditions = listOf( ImageCondition( id = Identifier(databaseId = 1001), eventId = Identifier(databaseId = 101), name = "Play button present", priority = 0, path = "/data/app/conditions/play_button.png", area = Rect(100, 200, 200, 300), // Captured button region threshold = 5, // 5% tolerance for image matching detectionType = IN_AREA, shouldBeDetected = true, detectionArea = Rect(0, 0, 1080, 400) // Only search top portion of screen ), ImageCondition( id = Identifier(databaseId = 1002), eventId = Identifier(databaseId = 101), name = "Loading spinner not present", priority = 1, path = "/data/app/conditions/loading.png", area = Rect(50, 50, 150, 150), threshold = 8, detectionType = WHOLE_SCREEN, shouldBeDetected = false // Must NOT be detected ) ), actions = listOf( Click( id = Identifier(databaseId = 10001), eventId = Identifier(databaseId = 101), name = "Click play button", priority = 0, pressDuration = 75L, positionType = Click.PositionType.ON_DETECTED_CONDITION, clickOnConditionId = Identifier(databaseId = 1001), // Click on first condition clickOffset = Point(5, 5) // Offset from condition center ), Pause( id = Identifier(databaseId = 10002), eventId = Identifier(databaseId = 101), name = "Wait for animation", priority = 1, pauseDuration = 1000L // Wait 1 second after click ) ) ) ``` -------------------------------- ### Scenario Persistence with Room Database in Kotlin Source: https://context7.com/nain57/smart-autoclicker/llms.txt Demonstrates how to interact with the ClickDatabase using Room for storing and managing scenarios, events, conditions, and actions. It covers querying, inserting, updating, and deleting data, leveraging Kotlin coroutines for asynchronous operations. Automatic database migrations are handled by Room. ```kotlin @Inject lateinit var database: ClickDatabase // Query scenarios lifecycleScope.launch { val allScenarios: List = database.scenarioDao() .getAllScenarios() val specificScenario: ScenarioWithEvents = database.scenarioDao() .getScenarioWithEvents(scenarioId = 42L) println("Scenario: ${specificScenario.scenario.name}") println("Events: ${specificScenario.events.size}") } // Insert new scenario val newScenario = ScenarioEntity( id = 0, // Auto-generated name = "New Bot", detectionQuality = 600, randomize = true, keepScreenOn = false ) val scenarioId = database.scenarioDao().insertScenario(newScenario) // Insert event for scenario val newEvent = EventEntity( id = 0, scenarioId = scenarioId, name = "Click Event", priority = 0, conditionOperator = AND, enabledOnStart = true ) val eventId = database.eventDao().insertEvent(newEvent) // Insert condition for event val newCondition = ConditionEntity( id = 0, eventId = eventId, name = "Button visible", path = "/conditions/button.png", areaLeft = 100, areaTop = 200, areaRight = 300, areaBottom = 400, threshold = 5, detectionType = WHOLE_SCREEN, shouldBeDetected = true ) database.conditionDao().insertCondition(newCondition) // Insert action for event val newAction = ActionEntity( id = 0, eventId = eventId, name = "Click button", priority = 0, type = ActionType.CLICK, clickPositionType = ClickPositionType.ON_DETECTED_CONDITION, pressDuration = 50L ) database.actionDao().insertAction(newAction) // Update scenario newScenario.copy(name = "Updated Bot").let { database.scenarioDao().updateScenario(it) } // Delete scenario (cascade deletes events, conditions, actions) database.scenarioDao().deleteScenario(newScenario) // Database version and migrations handled automatically // Current version: CLICK_DATABASE_VERSION = 18 ``` -------------------------------- ### Kotlin: Create and Execute DumbScenario for Simple Automation Source: https://context7.com/nain57/smart-autoclicker/llms.txt Demonstrates the creation of a `DumbScenario` for timer-based automation without image detection. It includes defining a series of `DumbClick`, `DumbPause`, and `DumbSwipe` actions and then executing this scenario using the `DumbEngine`. The engine's state can be observed via coroutine collectors. ```kotlin // Create a simple repeating click scenario val dumbScenario = DumbScenario( id = Identifier(databaseId = 1), name = "Auto-clicker 10 CPS", repeatCount = 100, // Execute 100 times isRepeatInfinite = false, maxDurationMin = 5, // Run for maximum 5 minutes isDurationInfinite = false, randomize = false, // No coordinate randomization dumbActions = listOf( DumbClick( id = Identifier(databaseId = 10), name = "Click every 100ms", priority = 0, position = Point(500, 1000), pressDuration = 50L, repeatCount = 10, isRepeatInfinite = false, repeatDelay = 100L // 100ms between clicks ), DumbPause( id = Identifier(databaseId = 11), name = "Pause 1 second", priority = 1, pauseDuration = 1000L, repeatCount = 1, isRepeatInfinite = false, repeatDelay = 0L ), DumbSwipe( id = Identifier(databaseId = 12), name = "Swipe left", priority = 2, from = Point(800, 1000), to = Point(200, 1000), swipeDuration = 200L, repeatCount = 1, isRepeatInfinite = false, repeatDelay = 0L ) ) ) // Execute dumb scenario @Inject lateinit var dumbEngine: DumbEngine lifecycleScope.launch { dumbEngine.init(accessibilityService) dumbEngine.executeScenario(dumbScenario) dumbEngine.state.collect { state -> when (state) { DumbEngineState.IDLE -> Log.i("Dumb", "Ready") DumbEngineState.EXECUTING -> Log.i("Dumb", "Running") DumbEngineState.COMPLETED -> Log.i("Dumb", "Finished") } } } ``` -------------------------------- ### Configure Image Detection Event with OR Logic (Kotlin) Source: https://context7.com/nain57/smart-autoclicker/llms.txt Sets up an ImageEvent where at least one of the specified ImageConditions must be met for the associated actions to trigger. This is useful for scenarios where multiple visual variations can lead to the same outcome. Dependencies include image matching libraries and specific event/condition/action data classes. ```kotlin // OR operator example val collectRewardsEvent = ImageEvent( id = Identifier(databaseId = 102), scenarioId = Identifier(databaseId = 42), name = "Collect any reward", conditionOperator = OR, // Match ANY condition priority = 1, keepDetecting = true, // Continue checking other events conditions = listOf( ImageCondition(/* gold reward icon */), ImageCondition(/* silver reward icon */), ImageCondition(/* bronze reward icon */) ), actions = listOf( Click( id = Identifier(databaseId = 10003), eventId = Identifier(databaseId = 102), name = "Click reward", priority = 0, pressDuration = 50L, positionType = Click.PositionType.ON_DETECTED_CONDITION, clickOnConditionId = null // Will click on whichever condition matched ) ) ) ``` -------------------------------- ### Integrate OpenCV for Release Build | CMake Source: https://github.com/nain57/smart-autoclicker/blob/master/core/smart/detection/src/CMakeLists.txt This CMake code block integrates OpenCV for release builds. It adds the OpenCV source directory as a subdirectory for building and sets the include directories for core and imgproc modules. It also ensures the correct output directory for 'opencv_core' and includes necessary headers for OpenCV modules. ```cmake ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/release/opencv") set(SOURCE_OPENCV_PATH "${CMAKE_CURRENT_SOURCE_DIR}/release/opencv") # Adds the CMakeLists.txt file located in the specified directory # as a build dependency. add_subdirectory(${SOURCE_OPENCV_PATH}) # For a reason I'm missing, we have to set the correct output for opencv_core set_target_properties( opencv_core PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ) target_include_directories(smartautoclicker PUBLIC ${SOURCE_OPENCV_PATH}/modules/core/include ${SOURCE_OPENCV_PATH}/modules/imgproc/include ) # Required to get opencv2/open_modules.hpp generated at build time include_directories (${CMAKE_BINARY_DIR}) ENDIF() ``` -------------------------------- ### Link Libraries to Target | CMake Source: https://github.com/nain57/smart-autoclicker/blob/master/core/smart/detection/src/CMakeLists.txt This snippet links the 'smartautoclicker' library to OpenCV core and imgproc libraries, the 'jnigraphics' system library, and the found 'log-lib'. This is the final step to ensure all dependencies are correctly linked for the application to run. ```cmake # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries(smartautoclicker opencv_core opencv_imgproc -ljnigraphics ${log-lib} ) ``` -------------------------------- ### Find and Link System Log Library | CMake Source: https://github.com/nain57/smart-autoclicker/blob/master/core/smart/detection/src/CMakeLists.txt This snippet demonstrates how to find a prebuilt NDK library, specifically the 'log' library, and store its path in a variable named 'log-lib'. This is essential for accessing logging functionalities in Android NDK projects. ```cmake # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( log-lib log ) ``` -------------------------------- ### Declare and Build Shared Library | CMake Source: https://github.com/nain57/smart-autoclicker/blob/master/core/smart/detection/src/CMakeLists.txt This snippet declares a shared library named 'smartautoclicker' and specifies all its source and header files. CMake will compile these files into a single shared library. ```cmake cmake_minimum_required(VERSION 3.22.1) IF(WITH_BUILD_ID MATCHES OFF) add_link_options("LINKER:--build-id=none") ENDIF() project("smartautoclicker") add_library( smartautoclicker SHARED main/cpp/smartautoclicker.cpp main/cpp/detector/detector.cpp main/cpp/detector/detector.hpp main/cpp/detector/images/condition_image.cpp main/cpp/detector/images/condition_image.hpp main/cpp/detector/images/detection_image.cpp main/cpp/detector/images/detection_image.hpp main/cpp/detector/images/screen_image.cpp main/cpp/detector/images/screen_image.hpp main/cpp/detector/matching/template_matcher.cpp main/cpp/detector/matching/template_matcher.hpp main/cpp/detector/matching/template_matching_result.cpp main/cpp/detector/matching/template_matching_result.hpp main/cpp/jni/jni.hpp main/cpp/jni/jni_bitmap.cpp main/cpp/jni/jni_detector.cpp main/cpp/jni/jni_detection_result.cpp main/cpp/logs/log.cpp main/cpp/logs/log.h main/cpp/utils/correction.hpp main/cpp/utils/roi.h) ``` -------------------------------- ### Kotlin: Stop Detection and Screen Recording Source: https://context7.com/nain57/smart-autoclicker/llms.txt Provides methods to halt the ongoing image detection process and optionally stop the screen recording. This is crucial for cleanup and resource management when the application is no longer active. ```kotlin import android.util.Log import com.example.smartautoclicker.DetectorEngine // Assume DetectorEngine class is defined and available // Method to stop only detection fun stopDetection(detectorEngine: DetectorEngine) { detectorEngine.stopDetection() // Stops detection but keeps recording Log.i("Detector Lifecycle", "Detection stopped.") } // Method to stop both detection and recording fun stopRecording(detectorEngine: DetectorEngine) { detectorEngine.stopScreenRecord() // Stops both detection and recording Log.i("Detector Lifecycle", "Screen recording stopped.") } // Dummy DetectorEngine for compilation class DetectorEngine { fun startScreenRecord(resultCode: Int, data: Intent, onRecordingStopped: () -> Unit) { Log.d("DetectorEngine", "Starting screen record...") } fun stopScreenRecord() { Log.d("DetectorEngine", "Stopping screen record...") } fun startDetection(context: Context, scenario: Scenario, imageEvents: List, triggerEvents: List, progressListener: ScenarioProcessingListener) { Log.d("DetectorEngine", "Starting detection...") } fun stopDetection() { Log.d("DetectorEngine", "Stopping detection...") } } // Example usage simulation: // val detectorEngine = DetectorEngine() // stopDetection(detectorEngine) // stopRecording(detectorEngine) ``` -------------------------------- ### Execute Android Gestures and System Actions with AndroidActionExecutor Source: https://context7.com/nain57/smart-autoclicker/llms.txt The AndroidActionExecutor class dispatches various automation actions using Android's AccessibilityService. It supports gesture execution (clicks, swipes), global system actions (back, home), text input, activity launching, broadcasting, and posting notifications. It requires initialization with an AccessibilityService instance and offers a resetState method to cancel ongoing actions. Note the API limitation on maximum gesture duration. ```kotlin import android.accessibilityservice.AccessibilityService import android.accessibilityservice.GestureDescription import android.content.Intent import android.graphics.Path import android.net.Uri import android.util.Log import androidx.core.app.NotificationCompat import androidx.lifecycle.lifecycleScope import com.example.smart_autoclicker.core.actions.ActionNotificationRequest import com.example.smart_autoclicker.core.actions.AndroidActionExecutor import kotlinx.coroutines.launch @Inject lateinit var actionExecutor: AndroidActionExecutor // Must be initialized with AccessibilityService instance class AutoClickerService : AccessibilityService() { override fun onCreate() { super.onCreate() actionExecutor.init(this) } override fun onDestroy() { actionExecutor.clear() super.onDestroy() } } // Execute a click gesture lifecycleScope.launch { val clickGesture = GestureDescription.Builder().apply { val path = Path().apply { moveTo(500f, 1000f) // Click at (500, 1000) } addStroke(GestureDescription.StrokeDescription(path, 0L, 50L)) // 50ms press }.build() actionExecutor.dispatchGesture(clickGesture) Log.i("Action", "Click executed") } // Execute a swipe gesture lifecycleScope.launch { val swipeGesture = GestureDescription.Builder().apply { val path = Path().apply { moveTo(200f, 1000f) lineTo(800f, 1000f) // Swipe right } addStroke(GestureDescription.StrokeDescription(path, 0L, 300L)) // 300ms swipe }.build() actionExecutor.dispatchGesture(swipeGesture) } // Perform global system actions actionExecutor.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK) actionExecutor.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME) actionExecutor.performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS) // Write text to focused input field actionExecutor.writeTextOnFocusedItem( text = "Hello World", validate = true // Press enter after input ) // Launch an activity via Intent val launchIntent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://example.com") addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } actionExecutor.startActivity(launchIntent) // Send a broadcast val broadcastIntent = Intent("com.example.CUSTOM_ACTION").apply { putExtra("key", "value") } actionExecutor.sendBroadcast(broadcastIntent) // Post a notification (queued to avoid spam detection) actionExecutor.postNotification( ActionNotificationRequest( id = 1, title = "Automation Alert", message = "Task completed successfully", priority = NotificationCompat.PRIORITY_DEFAULT ) ) // Reset state (cancels ongoing actions) actionExecutor.resetState() // Maximum gesture duration from API limitations val maxDuration = 59_999L // GESTURE_DURATION_MAX_VALUE ``` -------------------------------- ### Configure Broadcast-Based TriggerEvent in Kotlin Source: https://context7.com/nain57/smart-autoclicker/llms.txt Creates a TriggerEvent that reacts to system broadcasts, such as a low battery warning. It uses a BroadcastReceivedCondition to monitor specific intent actions and triggers a notification. This enables responsive automations to system events. ```kotlin val broadcastTriggerEvent = TriggerEvent( id = Identifier(databaseId = 203), scenarioId = Identifier(databaseId = 42), name = "React to system broadcast", conditionOperator = AND, conditions = listOf( BroadcastReceivedCondition( id = Identifier(databaseId = 2003), eventId = Identifier(databaseId = 203), name = "Battery low broadcast", intentAction = Intent.ACTION_BATTERY_LOW ) ), actions = listOf( Notification( id = Identifier(databaseId = 20004), eventId = Identifier(databaseId = 203), name = "Battery warning", priority = 0, title = "Pausing Automation", message = "Battery level low" ) ) ) ``` -------------------------------- ### Kotlin: Define Automation Action Types for Smart Autoclicker Source: https://context7.com/nain57/smart-autoclicker/llms.txt Defines various action types that can be executed when event conditions are met in the Smart Autoclicker project. These include click, swipe, pause, counter changes, event toggling, launching intents, displaying notifications, and system actions. Each action is represented as a data class with specific parameters for its operation. ```kotlin val clickAction = Click( id = Identifier(databaseId = 1), eventId = Identifier(databaseId = 100), name = "Click center of screen", priority = 0, pressDuration = 50L, // Milliseconds positionType = Click.PositionType.USER_SELECTED, position = Point(540, 960), // Center of 1080x1920 screen clickOnConditionId = null, clickOffset = null ) // Swipe action - drag gesture between two points val swipeAction = Swipe( id = Identifier(databaseId = 2), eventId = Identifier(databaseId = 100), name = "Swipe up to scroll", priority = 1, swipeDuration = 300L, // 300ms swipe from = Point(540, 1500), to = Point(540, 500) ) // Pause action - wait before next action val pauseAction = Pause( id = Identifier(databaseId = 3), eventId = Identifier(databaseId = 100), name = "Wait for animation", priority = 2, pauseDuration = 2000L // 2 seconds ) // Change counter action - modify scenario state counter val incrementCounterAction = ChangeCounter( id = Identifier(databaseId = 4), eventId = Identifier(databaseId = 100), name = "Increment click count", priority = 3, counterName = "total_clicks", operation = ADD, operationValue = 1 ) // Toggle event action - enable/disable other events val toggleAction = ToggleEvent( id = Identifier(databaseId = 5), eventId = Identifier(databaseId = 100), name = "Disable farming event", priority = 4, toggleType = ToggleType.DISABLE, toggleEventId = Identifier(databaseId = 50) ) // Intent action - launch app or send broadcast val intentAction = Intent( id = Identifier(databaseId = 6), eventId = Identifier(databaseId = 100), name = "Open browser", priority = 5, intentAction = Intent.ACTION_VIEW, componentName = null, flags = Intent.FLAG_ACTIVITY_NEW_TASK, extras = listOf( IntentExtra( id = Identifier(databaseId = 60), actionId = Identifier(databaseId = 6), key = "url", value = "https://example.com" ) ), isBroadcast = false ) // Notification action - display system notification val notificationAction = Notification( id = Identifier(databaseId = 7), eventId = Identifier(databaseId = 100), name = "Show progress", priority = 6, title = "Automation Status", message = "Task completed successfully" ) // System action - perform global device action val systemAction = SystemAction( id = Identifier(databaseId = 8), eventId = Identifier(databaseId = 100), name = "Go home", priority = 7, globalAction = AccessibilityService.GLOBAL_ACTION_HOME ) ``` -------------------------------- ### Integrate OpenCV for Debug Build | CMake Source: https://github.com/nain57/smart-autoclicker/blob/master/core/smart/detection/src/CMakeLists.txt This CMake code block handles the integration of OpenCV for debug builds. It defines prebuilt shared libraries for 'opencv_core' and 'opencv_imgproc' by specifying their locations based on the ANDROID_ABI. It also sets the public include directories for the 'smartautoclicker' target. ```cmake # In debug, we want to use the prebuilts of OpenCV in order to speed up the dev process/CI IF(CMAKE_BUILD_TYPE MATCHES Debug) set(PREBUILT_OPENCV_PATH "${CMAKE_CURRENT_SOURCE_DIR}/debug/opencv") add_library( opencv_core SHARED IMPORTED ) set_target_properties( opencv_core PROPERTIES IMPORTED_LOCATION "${PREBUILT_OPENCV_PATH}/libs/${ANDROID_ABI}/libopencv_core.so" ) add_library( opencv_imgproc SHARED IMPORTED ) set_target_properties( opencv_imgproc PROPERTIES IMPORTED_LOCATION "${PREBUILT_OPENCV_PATH}/libs/${ANDROID_ABI}/libopencv_imgproc.so" ) target_include_directories( smartautoclicker PUBLIC ${PREBUILT_OPENCV_PATH}/include ) ``` -------------------------------- ### Configure Counter-Based TriggerEvent in Kotlin Source: https://context7.com/nain57/smart-autoclicker/llms.txt Sets up a TriggerEvent to stop a scenario after a specific number of iterations (e.g., 100). It utilizes a CounterReachedCondition and includes actions for notification and stopping the scenario. This is ideal for limiting repetitive tasks. ```kotlin val repeatLimitEvent = TriggerEvent( id = Identifier(databaseId = 202), scenarioId = Identifier(databaseId = 42), name = "Stop after 100 iterations", conditionOperator = AND, conditions = listOf( CounterReachedCondition( id = Identifier(databaseId = 2002), eventId = Identifier(databaseId = 202), name = "Loop counter = 100", counterName = "loop_count", comparisonOperation = EQUALS, counterValue = 100 ) ), actions = listOf( Notification( id = Identifier(databaseId = 20002), eventId = Identifier(databaseId = 202), name = "Notify completion", priority = 0, title = "Automation Complete", message = "100 iterations finished" ), ToggleEvent( id = Identifier(databaseId = 20003), eventId = Identifier(databaseId = 202), name = "Stop scenario", priority = 1, toggleType = ToggleType.DISABLE_ALL, toggleEventId = null ) ) ) ``` -------------------------------- ### Configure Timer-Based TriggerEvent in Kotlin Source: https://context7.com/nain57/smart-autoclicker/llms.txt Configures a TriggerEvent to automatically stop a scenario after a specified duration (e.g., 30 minutes). It uses a TimerReachedCondition and a ToggleEvent to disable all other events. This is useful for time-bound automations. ```kotlin val stopAfterTimeEvent = TriggerEvent( id = Identifier(databaseId = 201), scenarioId = Identifier(databaseId = 42), name = "Auto-stop after 30 minutes", conditionOperator = AND, enabledOnStart = true, conditions = listOf( TimerReachedCondition( id = Identifier(databaseId = 2001), eventId = Identifier(databaseId = 201), name = "30 minutes elapsed", timerValueMs = 1800000L // 30 * 60 * 1000 ) ), actions = listOf( ToggleEvent( id = Identifier(databaseId = 20001), eventId = Identifier(databaseId = 201), name = "Disable all events", priority = 0, toggleType = ToggleType.DISABLE_ALL, toggleEventId = null ) ) ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.