Android实现自动点击 - 无障碍服务

ps: 不想看代码的滑到最下面有apk包百度网盘下载地址

1. 先看效果图 不然都是耍流氓

2.项目目录

 

3.一些配置

build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-android-extensions'
}

android {
    compileSdkVersion 31
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.znan.autoclick"
        minSdkVersion 24
        targetSdkVersion 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

    //协程
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3"

}

accessibility.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:canPerformGestures="true"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_desc" />

AndroidManifest.xml 注册权限和服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.znan.autoclick">

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AutoClick">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".AutoClickService"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility" />
        </service>
    </application>

</manifest>

4.代码

AutoClickService.kt 无障碍服务

class AutoClickService : AccessibilityService() {

    private val TAG = javaClass.canonicalName

    var mainScope: CoroutineScope? = null

    private val broadcastReceiver = BroadcastHandler(this)

    //点击间隔
    private var mInterval = -1L

    //点击坐标xy
    private var mPointX = -1f
    private var mPointY = -1f

    //悬浮窗视图
    private lateinit var mFloatingView: FloatingClickView

    companion object {

        //打开悬浮窗
        val ACTION_SHOW = "action_show"

        //自动点击事件 开启/关闭
        val ACTION_PLAY = "action_play"
        val ACTION_STOP = "action_stop"

        //关闭悬浮窗
        val ACTION_CLOSE = "action_close"
    }

    private inner class BroadcastHandler(val context: Context) : BroadcastReceiver() {

        fun register() {
            context.registerReceiver(
                this,
                IntentFilter().apply {
                    addAction(BroadcastConstants.BROADCAST_ACTION_AUTO_CLICK)
                    //息屏关闭自动点击事件
                    addAction(Intent.ACTION_SCREEN_OFF)
                }
            )
        }

        fun unregister() {
            context.unregisterReceiver(this)
        }

        override fun onReceive(p0: Context?, intent: Intent?) {
            intent?.apply {
                when(action) {
                    Intent.ACTION_SCREEN_OFF -> {
                        mFloatingView.remove()
                        mainScope?.cancel()
                    }
                    BroadcastConstants.BROADCAST_ACTION_AUTO_CLICK -> {
                        when (getStringExtra(BroadcastConstants.KEY_ACTION)) {
                            ACTION_SHOW -> {
                                mFloatingView.remove()
                                mainScope?.cancel()
                                mInterval = getLongExtra(BroadcastConstants.KEY_INTERVAL, 5000)
                                mFloatingView.show()
                            }
                            ACTION_PLAY -> {
                                mPointX = getFloatExtra(BroadcastConstants.KEY_POINT_X, 0f)
                                mPointY = getFloatExtra(BroadcastConstants.KEY_POINT_Y, 0f)
                                mainScope = MainScope()
                                autoClickView(mPointX, mPointY)
                            }
                            ACTION_STOP -> {
                                mainScope?.cancel()
                            }
                            ACTION_CLOSE -> {
                                mFloatingView.remove()
                                mainScope?.cancel()
                            }
                            else -> {
                                Log.e(TAG, "action error")
                            }
                        }
                    }
                }
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        startForegroundNotification()
        mFloatingView = FloatingClickView(this)
        broadcastReceiver.register()
    }

    private fun startForegroundNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationBuilder =
                NotificationCompat.Builder(this, NotificationConstants.CHANNEL_ID)
            val notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setCategory(Notification.CATEGORY_SERVICE)
                .build()
            startForeground(-1, notification)

        } else {
            startForeground(-1, Notification())
        }
    }

    @RequiresApi(Build.VERSION_CODES.N)
    private fun autoClickView(x: Float, y: Float) {
        mainScope?.launch {
            while (true) {
                delay(mInterval)
                Log.d(TAG, "auto click x:$x  y:$y")
                val path = Path()
                path.moveTo(x, y)
                val gestureDescription = GestureDescription.Builder()
                    .addStroke(GestureDescription.StrokeDescription(path, 100L, 100L))
                    .build()
                dispatchGesture(
                    gestureDescription,
                    object : AccessibilityService.GestureResultCallback() {
                        override fun onCompleted(gestureDescription: GestureDescription?) {
                            super.onCompleted(gestureDescription)
                            Log.d(TAG, "自动点击完成")
                        }

                        override fun onCancelled(gestureDescription: GestureDescription?) {
                            super.onCancelled(gestureDescription)
                            Log.d(TAG, "自动点击取消")
                        }
                    },
                    null
                )
            }
        }

    }


    override fun onInterrupt() {
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent?) {
    }

    override fun onDestroy() {
        super.onDestroy()
        broadcastReceiver.unregister()
        mainScope?.cancel()
    }

}

悬浮窗

SingletonHolder.kt

open class SingletonHolder<out T, in A>(creator: (A) -> T) {
    private var creator: ((A) -> T)? = creator
    @Volatile private var instance: T? = null

    fun getInstance(arg: A): T {
        val i = instance
        if (i != null) {
            return i
        }

        return synchronized(this) {
            val i2 = instance
            if (i2 != null) {
                i2
            } else {
                val created = creator!!(arg)
                instance = created
                creator = null
                created
            }
        }
    }
}

FloatingManager.kt

import android.content.Context
import android.view.View
import android.view.WindowManager

class FloatingManager private constructor(context: Context) {

    //获得WindowManager对象
    private var mWindowManager: WindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager

    companion object : SingletonHolder<FloatingManager, Context>(::FloatingManager)


    /**
     * 添加悬浮窗
     * @param view
     * @param params
     * @return
     */
    fun addView(view: View, params: WindowManager.LayoutParams): Boolean {
        try {
            mWindowManager.addView(view, params)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return false
    }

    /**
     * 移除悬浮窗
     *
     * @param view
     * @return
     */
    fun removeView(view: View): Boolean {
        try {
            mWindowManager.removeView(view)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return false
    }

    /**
     * 更新悬浮窗参数
     *
     * @param view
     * @param params
     * @return
     */
    fun updateView(view: View, params: WindowManager.LayoutParams): Boolean {
        try {
            mWindowManager.updateViewLayout(view, params)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return false
    }
}

FloatingClickView.kt

class FloatingClickView(private val mContext: Context) : FrameLayout(mContext) {

    private lateinit var mWindowManager: FloatingManager
    private var mParams: WindowManager.LayoutParams? = null

    private lateinit var mView: View

    //按下坐标
    private var mTouchStartX = -1f
    private var mTouchStartY = -1f

    val STATE_CLICKING = "state_clicking"
    val STATE_NORMAL = "state_normal"
    private var mCurrentState = STATE_NORMAL

    private var ivIcon: AppCompatImageView? = null

    init {
        initView()
    }


    private fun initView() {
        mView = LayoutInflater.from(context).inflate(R.layout.view_floating_click, null)
        ivIcon = mView.findViewById(R.id.iv_icon)
        mWindowManager = FloatingManager.getInstance(mContext)
        initListener()
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initListener() {
        mView.setOnTouchListener { v, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    mTouchStartX = event.rawX
                    mTouchStartY = event.rawY
                }

                MotionEvent.ACTION_MOVE -> {
                    mParams?.let {
                        it.x += (event.rawX - mTouchStartX).toInt()
                        it.y += (event.rawY - mTouchStartY).toInt()
                        mWindowManager.updateView(mView, it)
                    }
                    mTouchStartX = event.rawX
                    mTouchStartY = event.rawY
                }
            }
            false
        }

        mView.setOnClickListener {

            val location = IntArray(2)
            it.getLocationOnScreen(location)

            val intent = Intent().apply {
                action = BroadcastConstants.BROADCAST_ACTION_AUTO_CLICK
                when (mCurrentState) {
                    STATE_NORMAL -> {
                        mCurrentState = STATE_CLICKING
                        putExtra(BroadcastConstants.KEY_ACTION, AutoClickService.ACTION_PLAY)
                        putExtra(BroadcastConstants.KEY_POINT_X, (location[0] - 1).toFloat())
                        putExtra(BroadcastConstants.KEY_POINT_Y, (location[1] - 1).toFloat())
                        ivIcon?.setImageResource(R.drawable.ic_auto_click_icon_green_24)
                    }
                    STATE_CLICKING -> {
                        mCurrentState = STATE_NORMAL
                        putExtra(BroadcastConstants.KEY_ACTION, AutoClickService.ACTION_STOP)
                        ivIcon?.setImageResource(R.drawable.ic_auto_click_icon_gray_24)
                    }
                }
            }

            context.sendBroadcast(intent)
        }
    }

    fun show() {
        mParams = WindowManager.LayoutParams()
        mParams?.apply {
            gravity = Gravity.CENTER
            //总是出现在应用程序窗口之上
            type = if (Build.VERSION.SDK_INT >= 26) {
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
            }
            //设置图片格式,效果为背景透明
            format = PixelFormat.RGBA_8888

            flags =
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR or
                        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH

            width = LayoutParams.WRAP_CONTENT
            height = LayoutParams.WRAP_CONTENT
            if (mView.isAttachedToWindow) {
                mWindowManager.removeView(mView)
            }
            mWindowManager.addView(mView, this)
        }
    }

    fun remove() {
        mCurrentState = STATE_NORMAL
        ivIcon?.setImageResource(R.drawable.ic_auto_click_icon_gray_24)
        mWindowManager.removeView(mView)
    }

}

页面事件

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val TAG = javaClass::class.java.canonicalName

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initNotification()
        initListener()
        startAutoClickService()
    }

    private fun initListener() {
        btn_accessibility.setOnClickListener {
            checkAccessibility()
        }

        btn_floating_window.setOnClickListener {
            checkFloatingWindow()
        }

        btn_show_window.setOnClickListener {
            hideKeyboard()
            if (TextUtils.isEmpty(et_interval.text.toString())) {
                Snackbar.make(et_interval, "请输入间隔", Snackbar.LENGTH_SHORT).show()
                return@setOnClickListener
            }
            showFloatingWindow(et_interval.text.toString().toLong())
        }

        btn_close_window.setOnClickListener {
            closeFloatWindow()
        }

        btn_test.setOnClickListener {
            Log.d(TAG, "btn_test on click")
        }
    }

    /**
     * 跳转设置开启无障碍
     */
    private fun checkAccessibility() {
        val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
        startActivity(intent)
    }

    /**
     * 跳转设置顶层悬浮窗
     */
    private fun checkFloatingWindow() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "已开启", Toast.LENGTH_SHORT).show()
            } else {
                val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
                startActivity(intent)
            }
        }
    }

    private fun startAutoClickService() {
        val intent = Intent(this, AutoClickService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intent)
        } else {
            startService(intent)
        }
    }

    private fun showFloatingWindow(interval: Long) {
        sendBroadcast(Intent().apply {
            action = BroadcastConstants.BROADCAST_ACTION_AUTO_CLICK
            putExtra(BroadcastConstants.KEY_ACTION, AutoClickService.ACTION_SHOW)
            putExtra(BroadcastConstants.KEY_INTERVAL, interval)
        })
    }

    private fun closeFloatWindow() {
        sendBroadcast(Intent().apply {
            action = BroadcastConstants.BROADCAST_ACTION_AUTO_CLICK
            putExtra(BroadcastConstants.KEY_ACTION, AutoClickService.ACTION_CLOSE)
        })
    }


    private fun initNotification() {
        //注册渠道id
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = NotificationConstants.CHANNEl_NAME
            val descriptionText = NotificationConstants.CHANNEL_DES
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel =
                NotificationChannel(NotificationConstants.CHANNEL_ID, name, importance).apply {
                    description = descriptionText
                }
            channel.enableLights(true)
            channel.lightColor = Color.GREEN
            // Register the channel with the system
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    override fun onDestroy() {
        val intent = Intent(this, AutoClickService::class.java)
        stopService(intent)
        super.onDestroy()
    }

    //收起输入法
    fun hideKeyboard() {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        if (imm.isActive && currentFocus != null) {
            imm.hideSoftInputFromWindow(
                currentFocus!!.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }
}
object NotificationConstants {
    val CHANNEL_ID = "auto_channel_id"

    val CHANNEl_NAME = "Auto Click"

    val CHANNEL_DES = "Auto Click Service"
}

object BroadcastConstants {
    val BROADCAST_ACTION_AUTO_CLICK = "BROADCAST_ACTION_AUTO_CLICK"

    val KEY_ACTION = "KEY_ACTION"
    val KEY_INTERVAL = "KEY_INTERVAL"
    val KEY_POINT_X = "KEY_POINT_X"
    val KEY_POINT_Y = "KEY_POINT_Y"
}

5.布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tv_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="50dp"
        android:layout_marginTop="20dp"
        android:text="先打开无障碍权限 和 悬浮窗顶层权限\n点击位置在图标左上角xy偏移一个px\n程序将会在延迟一个间隔后开始执行"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_accessibility"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="50dp"
        android:layout_marginTop="20dp"
        android:text="无障碍选项"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_message" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_floating_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:text="悬浮窗选项"
        app:layout_constraintStart_toEndOf="@id/btn_accessibility"
        app:layout_constraintTop_toTopOf="@id/btn_accessibility" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tv_unit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50dp"
        android:text="ms"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="@id/et_interval"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/et_interval" />

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/et_interval"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginStart="50dp"
        android:layout_marginTop="50dp"
        android:layout_marginEnd="10dp"
        android:hint="点击的间隔(建议大于100)(毫秒)"
        android:inputType="number"
        android:textColor="#FF0000"
        android:textSize="14sp"
        app:layout_constraintEnd_toStartOf="@id/tv_unit"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/btn_accessibility" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_show_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="打开悬浮视图"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et_interval" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_close_window"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="关闭悬浮视图"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/btn_show_window" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="100dp"
        android:text="测试点击按钮"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_auto_click_icon_gray_24" />
</FrameLayout>

6.app-auto-click.zip

百度网盘

 提取码: 6p2u 

 告辞~

  • 19
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
AutoClick是好用的自动点击工具 当你在玩游戏或工作中需要频繁的点击鼠标时 它可以释放你的手指并节省您的时间 只有按下热键 AutoClick将帮助您完成点击 AutoClick的使用非常简单 默认的是热键是F3;启动AutoClick后 设置好参数 主要是点击左键还是右键 单击还是双击以及间隔时间等 然后将鼠标放在需要点击的地方 按下F3 则AutoClick开始工作 即开始自动点击 要退出自动点击模式 只需再次按下F3 当然快捷键也是可以更换的 AutoClick还可以录制一系列鼠标动作 录制步骤是 先按F4激活录制模式 这时会录制一个浮动条 将鼠标移动到浮动条上 单击下Record按钮 然后拖曳鼠标 不要放开 到需要点击的地方然后释放鼠标 只是释放鼠标就可以 鼠标实现的动作是在设置里设定的 这时变完成一个动作的录制 继续录制时 需要再次单击下浮动条上的Record按钮 再次拖曳鼠标 不要放开 到需要点击的地方 依次类推 完成所有动作的录制后 再次按下F4完成录制 要自动点击上述录制的一系列鼠标动作 需要先点击选中界面上的Smrat Click选项 再按F3开始自动点击 AutoClick为单文件软件 但是貌似不支持设置的保存 要是想更换快捷键之类的需要每次启动时重新设置 不过默认的快捷键已经是很方便了">AutoClick是好用的自动点击工具 当你在玩游戏或工作中需要频繁的点击鼠标时 它可以释放你的手指并节省您的时间 只有按下热键 AutoClick将帮助您完成点击 AutoClick的使用非常简单 默认的是热键是F3;启动AutoClick后 设 [更多]
Android无障碍点击是指在安卓设备中,为了帮助视障人士或有其他行动障碍的人使用设备而开发的一种功能。该功能使得用户可以通过触摸屏幕来模拟真实的点击操作。 无障碍点击功能可以通过在设备的设置中进行配置。一旦开启,用户可以使用不同的手势来模拟单击、长按、滑动、双击等操作。这些手势可以通过定义不同的触摸区域来触发不同的操作。例如,用户可以通过双击屏幕的左上角来实现返回操作,通过长按屏幕右下角来实现主屏幕操作等。 该功能对于视觉障碍的用户来说尤为重要,因为他们无法准确地通过触摸屏幕定位和点击需要的区域。而无障碍点击功能可以帮助他们通过简单的手势操作来实现他们想要的操作,从而提高他们使用设备的便利性和自主性。 除了视觉障碍的用户外,无障碍点击功能对于其他行动不便的人士也有帮助。例如,一些人可能因为手部受伤或其他身体状况而无法精确地点击屏幕。通过无障碍点击功能,他们可以通过一些简单的手势来代替真实的点击动作,从而更方便地使用设备。 总之,Android无障碍点击功能是为了帮助视障人士和其他行动有障碍的人更便捷地使用设备而设计的。这项功能可以通过简单的手势来模拟真实的点击操作,提高用户的独立性和自主性。它为广大用户创造了一个更包容和无障碍的手机环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值