如何检测android用户使用的自动点击器应用程序? [英] How to detect auto clicker app used by android user?

查看:58
本文介绍了如何检测android用户使用的自动点击器应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些 Android 用户使用 Play-store 上提供的自动点击器应用程序进行多次点击.

Some android user using auto-clicker apps available on play-store to click multiple time.

所以我想检测/阻止尝试使用自动点击器的用户.android 有没有办法检测这些用户?如果是,那么我们如何检测这些用户?

So I want to detect/block user who tries to use auto-clicker.Is there any way in android to detect such users?If yes, then how we can detect those users?

推荐答案

没有检测自动点击器是否正在运行的 API.所有自动点击器都使用无障碍服务来模拟点击,并且有一个 API 可以让您检测是否有任何无障碍服务正在运行.问题是,这些服务还包括屏幕阅读器和其他对残疾人有用的工具.您绝对不应该仅仅因为您的用户使用无障碍服务而屏蔽他们.

There is no API to detect if an autoclicker is running. All autoclickers use accessibility services to emulate clicks, and there is an API that allows you to detect if any accessibility service is running. The problem is, those services also include screen readers and other useful tools for disabled people. You definitely shouldn't block your users just because they're using accessibility services.

但是,您也可以检测不自然"点击和手势.没有人可以执行多个手势,从屏幕上完全相同的点开始,在完全相同的点完成,并在每个手势上花费完全相同的时间.

However, you can also detect "unnatural" clicks and gestures. No human can perform several gestures starting at exactly the same point on the screen, finishing at exactly the same point and spending exactly the same amount of time on each gesture.

当你检测到那个用户是
a) 使用无障碍服务
b) 执行不自然的点击
您可以合理地假设他正在使用自动点击器.然后你可以阻止他的触碰或做任何你想做的事情.

And when you detect that user is
a) using an accessibility service
b) performing unnatural clicks
you can reasonably assume that he is using an autoclicker. You can then block his touches or do whatever you want to do.

为了检测不自然的触摸,您必须分析所有传入的触摸事件.获得所有这些接触的最简单方法是覆盖根容器的 onInterceptTouchEvent 方法.

In order to detect unnatural touches you'll have to analyze all incoming touch events. Easiest way to get all those touches is to override onInterceptTouchEvent method of your root container.

例如,创建此类并将其用作布局的根目录:

E.g., create this class and use it as root for your layout:

class AutoclickerFrameLayout @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        AutoclickerDetector.recordEvent(event)
        // If you return true in this method touches will be blocked
        return false
    }

}

在分析 MotionEvents 时请记住,即使是自动点击器,报告的坐标和时间也可能会略有不同.例如,您可以使用此实现:

When analyzing MotionEvents keep in mind that even for autoclicker, reported coordinates and time can vary very slightly. For example, you can use this implementation:

object AutoclickerDetector {

    fun isAccessibilityServiceEnabled(context: Context): Boolean {
        val am = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
        val enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK)
        return enabledServices.isNotEmpty()
    }

    var isDetectingSimilarGestures = false
        private set

    private data class Touch(
            val x: Float,
            val y: Float,
            val time: Long
    ) {

        fun isSimilar(other: Touch): Boolean {
            return abs(this.x - other.x) < 1.0f
                    && abs(this.y - other.y) < 1.0f
        }

    }

    private data class Gesture(
            val start: Touch,
            val end: Touch
    ) {

        val duration: Long = end.time - start.time

        fun isSimilar(other: Gesture): Boolean {
            return this.start.isSimilar(other.start)
                    && this.end.isSimilar(other.end)
                    && abs(this.duration - other.duration) < 50
        }

    }

    private var gestureStart: Touch? = null
    private val recentGestures = ArrayList<Gesture>()

    fun recordEvent(event: MotionEvent) {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                gestureStart = Touch(event.rawX, event.rawY, System.currentTimeMillis())
            }
            MotionEvent.ACTION_UP -> {
                gestureStart?.let { gestureStart ->
                    val gestureEnd = Touch(event.rawX, event.rawY, System.currentTimeMillis())
                    recentGestures.add(Gesture(gestureStart, gestureEnd))
                    trimGestureHistory()
                    checkSimilarGestures()
                }
                gestureStart = null
            }
        }
    }

    private const val HISTORY_SIZE = 20

    private fun trimGestureHistory() {
        while (recentGestures.size > HISTORY_SIZE) {
            recentGestures.removeAt(0)
        }
    }

    private fun checkSimilarGestures() {
        recentGestures.forEachIndexed { i, searchGesture ->
            var similarCount = 0
            recentGestures.forEachIndexed { j, compareGesture ->
                if (i != j && searchGesture.isSimilar(compareGesture)) {
                    similarCount++
                }
            }
            if (similarCount > 2) {
                // There is no way user can physically perform almost exactly the same gesture
                // 3 times amongst 20 last gestures
                isDetectingSimilarGestures = true
                return
            }
        }
        isDetectingSimilarGestures = false
    }

}

然后在您的主代码中,您可以检查自动点击器当前是否正在工作:

Then in your main code you can check if autoclicker is currently working:

AutoclickerDetector.isAccessibilityServiceEnabled(context) 
    && AutoclickerDetector.isDetectingSimilarGestures

这篇关于如何检测android用户使用的自动点击器应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆