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
相关产品推荐
相关产品推荐

