You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现从应用外EditText字段全选并执行复制/剪切操作?

Hey there! Let's break down how to solve your two related problems step by step—first accessing and copying text from external EditTexts, then triggering that action with a phone shake.

1. 核心:跨应用EditText全选与复制的实现

First off, let's get one thing straight: on Android, you can't directly access UI elements from other apps due to the system's sandbox security. The only legitimate way to do this is using an Accessibility Service—this is the official tool for interacting with other apps' UI in a controlled manner.

Step 1: Create an Accessibility Service Subclass

This service will handle finding focused EditTexts and performing select/copy/cut actions. Here's a Kotlin implementation:

class ShakeCopyAccessibilityService : AccessibilityService() {
    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // We'll handle shake-triggered actions separately, but this can listen to focus events too
    }

    override fun onInterrupt() {
        // Cleanup logic if the service is interrupted
    }

    // Method to trigger select-all + copy/cut on focused EditText
    fun performTextAction(action: Int) {
        val rootNode = rootInActiveWindow ?: return
        val focusedEditText = findFocusedEditText(rootNode)
        focusedEditText?.let {
            // First select all text in the EditText
            it.performAction(AccessibilityNodeInfo.ACTION_SELECT_ALL)
            // Then execute copy or cut action
            it.performAction(action)
            // Recycle the node to avoid memory leaks
            it.recycle()
        }
    }

    // Recursively search the UI tree for the focused EditText
    private fun findFocusedEditText(node: AccessibilityNodeInfo): AccessibilityNodeInfo? {
        if (node.isFocused && node.className == EditText::class.java.name) {
            return node
        }
        for (i in 0 until node.childCount) {
            val childNode = node.getChild(i) ?: continue
            val result = findFocusedEditText(childNode)
            if (result != null) {
                return result
            }
            childNode.recycle()
        }
        return null
    }
}

Step 2: Register the Service in AndroidManifest

Add this to your AndroidManifest.xml—note the required system permission and configuration reference:

<service
    android:name=".ShakeCopyAccessibilityService"
    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_config" />
</service>

Step 3: Create the Accessibility Service Config

Make a new file res/xml/accessibility_service_config.xml to define the service's capabilities:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeViewFocused"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canPerformGestures="true"
    android:description="@string/accessibility_service_desc" />

Add the service description to your strings.xml (users will see this in accessibility settings):

<string name="accessibility_service_desc">Allows this app to select and copy/cut text from other apps\' input fields when you shake your phone.</string>
2. 晃动手机触发操作的实现

To detect a shake, we'll use the device's accelerometer via SensorManager, then trigger the accessibility service's text action when a shake is detected.

Step 1: Listen for Shake Events in Your Activity

Add this to your main activity (use a foreground service if you want the feature to work in the background):

class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null
    private var lastAccel = 0f
    private val shakeThreshold = 18f // Adjust this based on testing (lower = more sensitive)

    // Reference to our accessibility service
    private var accessibilityService: ShakeCopyAccessibilityService? = null

    // Bind to the service to call its methods
    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            val binder = service as ShakeCopyAccessibilityService.LocalBinder
            accessibilityService = binder.getService()
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            accessibilityService = null
        }
    }

    private val sensorListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]

            val currentAccel = sqrt((x*x + y*y + z*z).toDouble()).toFloat()
            val deltaAccel = currentAccel - lastAccel
            lastAccel = currentAccel

            // Trigger action when a shake is detected
            if (deltaAccel > shakeThreshold) {
                accessibilityService?.let {
                    // Use AccessibilityNodeInfo.ACTION_CUT for cut instead of copy
                    it.performTextAction(AccessibilityNodeInfo.ACTION_COPY)
                }
            }
        }

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
    }

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

        // Initialize sensor manager
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

        // Bind to the accessibility service
        Intent(this, ShakeCopyAccessibilityService::class.java).also { intent ->
            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
        }

        // Prompt user to enable accessibility service if it's not active
        if (!isAccessibilityServiceEnabled()) {
            startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
        }
    }

    // Helper to check if our service is enabled in accessibility settings
    private fun isAccessibilityServiceEnabled(): Boolean {
        val enabledServices = Settings.Secure.getString(
            contentResolver,
            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
        )
        val packageName = packageName
        return enabledServices?.contains("$packageName/.ShakeCopyAccessibilityService") == true
    }

    override fun onResume() {
        super.onResume()
        accelerometer?.let {
            sensorManager.registerListener(sensorListener, it, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(sensorListener)
    }

    override fun onDestroy() {
        super.onDestroy()
        unbindService(serviceConnection)
    }
}

Step 2: Add Local Binder to Accessibility Service

To let the activity call the service's methods, add a binder inside ShakeCopyAccessibilityService:

inner class LocalBinder : Binder() {
    fun getService(): ShakeCopyAccessibilityService = this@ShakeCopyAccessibilityService
}

override fun onBind(intent: Intent): IBinder {
    return LocalBinder()
}
Key Notes to Keep in Mind
  • User Consent is Mandatory: Android requires users to manually enable accessibility services in Settings. Always guide them to do this on first launch.
  • Tune the Shake Threshold: Adjust shakeThreshold to avoid false triggers—normal phone movement shouldn't activate the feature.
  • Memory Management: Always call recycle() on AccessibilityNodeInfo objects to prevent memory leaks.
  • Compatibility Limits: Some apps (like banking or secure apps) block accessibility access for security reasons—your feature won't work in these cases.

内容的提问来源于stack exchange,提问作者Loktakpat Tonda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:01:14