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

Android Kotlin实现剪贴板变化监听并发送通知(无需常驻通知)

Android Kotlin 实现剪贴板监听并发送通知(无需常驻通知)

可以实现这个功能,但需要结合Android版本的权限限制选择方案,**无障碍服务(AccessibilityService)**是适配Android 10+的最优解,且不需要应用自身显示常驻通知。

核心实现思路

Android 10(API 29)及以后系统限制了后台应用直接访问剪贴板,传统的ContentObserver无法在后台正常监听。而无障碍服务属于系统托管的服务,只要用户手动开启对应权限,就能在后台监听剪贴板变化,且不需要应用维持前台状态(也就无需常驻通知)。

具体实现步骤

1. 创建无障碍服务类

继承AccessibilityService,在事件回调中处理剪贴板内容变化,并发送通知:

import android.accessibilityservice.AccessibilityService
import android.content.ClipboardManager
import android.content.pm.PackageManager
import android.os.Build
import android.view.accessibility.AccessibilityEvent
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat

class ClipboardMonitorService : AccessibilityService() {
    private var lastCopiedText: String? = null
    private val CHANNEL_ID = "clipboard_notify_channel"
    private val NOTIFICATION_ID = 1001

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // 只处理剪贴板内容变化事件
        if (event.eventType != AccessibilityEvent.TYPE_CLIPBOARD_CONTENT_CHANGED) return

        val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
        val clipData = clipboard.primaryClip ?: return

        if (clipData.itemCount > 0) {
            val currentText = clipData.getItemAt(0).text?.toString() ?: return
            // 避免重复通知同一段内容
            if (currentText != lastCopiedText) {
                lastCopiedText = currentText
                sendCopyNotification(currentText)
            }
        }
    }

    private fun sendCopyNotification(content: String) {
        // Android 8.0+ 需要创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = android.app.NotificationChannel(
                CHANNEL_ID,
                "剪贴板通知",
                android.app.NotificationManager.IMPORTANCE_DEFAULT
            )
            val notificationManager = getSystemService(NOTIFICATION_SERVICE) as android.app.NotificationManager
            notificationManager.createNotificationChannel(channel)
        }

        // 点击通知打开应用主界面
        val launchIntent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
            flags = android.content.Intent.FLAG_ACTIVITY_NEW_TASK or android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent = android.app.PendingIntent.getActivity(
            this,
            0,
            launchIntent,
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) android.app.PendingIntent.FLAG_IMMUTABLE else 0
        )

        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification) // 替换为你的通知图标
            .setContentTitle("检测到新的复制内容")
            .setContentText(if (content.length > 50) "${content.substring(0, 50)}..." else content)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()

        NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification)
    }

    override fun onInterrupt() {
        // 服务被中断时的清理逻辑(可选)
    }
}

2. 配置无障碍服务参数

在res/xml目录下创建accessibility_service_config.xml,定义服务的监听规则:

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

在res/values/strings.xml中添加服务描述(用户开启权限时会看到):

<string name="accessibility_service_desc">监听剪贴板变化,当您复制内容时自动发送通知</string>

3. 注册服务到Manifest

在AndroidManifest.xml中注册无障碍服务,添加必要权限:

<service
    android:name=".ClipboardMonitorService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:exported="false">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>

4. 引导用户开启权限

首次启动时,需要引导用户跳转到系统的无障碍设置页面开启权限,示例代码:

fun openAccessibilitySettings(context: Context) {
    val intent = android.content.Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS)
    intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
    context.startActivity(intent)
}

关键注意事项

  • 权限要求:必须由用户手动开启无障碍权限,应用无法自动获取,因此需要在界面上明确告知用户开启步骤。
  • 版本兼容性:TYPE_CLIPBOARD_CONTENT_CHANGED是API 30(Android 11)新增的事件类型,若要兼容Android 10,可以监听TYPE_VIEW_TEXT_SELECTION_CHANGED作为补充,但准确性稍差。
  • 避免重复通知:通过记录上次复制的内容,过滤重复的剪贴板操作。
  • 通知渠道:Android 8.0及以上必须创建通知渠道,否则通知无法正常显示。

内容的提问来源于stack exchange,提问作者Ron Petrosian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:15:02