Android 14应用最小化时无法接收Accessibility Event求助
问题:Android 14下应用最小化后无法接收Accessibility Event
我的应用在Android 10系统中可正常接收Accessibility Event,但升级至Android 14后,应用被最小化时完全无法接收任何Accessibility Event,希望恢复到Android 10下的正常工作状态。相关配置与代码如下:
Manifest配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <queries> <intent> <action android:name="android.intent.action.MAIN" /> </intent> </queries> <application android:name="MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="CrashActivity" /> <service android:name="ScreenshotService" android:foregroundServiceType="mediaProjection" android:permission="android.permission.FOREGROUND_SERVICE" /> <service android:name="MyAccessibilityService" android:exported="true" 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> </application> </manifest>
Accessibility Service实现
package aman.astau; import android.accessibilityservice.AccessibilityService; import android.app.NotificationManager; import android.content.Context; import android.app.NotificationChannel; import android.app.Notification; import android.os.Build; import android.view.accessibility.AccessibilityEvent; import android.widget.Toast; import androidx.core.app.NotificationCompat; public class MyAccessibilityService extends AccessibilityService { private static final String CHANNEL_ID = "accessibility_service_channel"; private static final int NOTIFICATION_ID = 1; @Override public void onCreate() { super.onCreate(); // Create the notification channel createNotificationChannel(); // Create a persistent notification Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Accessibility Service") .setContentText("The service is running in the background") .setSmallIcon(android.R.drawable.ic_dialog_info) .build(); // Start the service in the foreground startForeground(NOTIFICATION_ID, notification); } @Override public void onAccessibilityEvent(AccessibilityEvent event) { Toast.makeText(getApplicationContext(), "something happened", Toast.LENGTH_SHORT).show(); } @Override public void onInterrupt() { // Handle interruptions (e.g., if the service is turned off) Toast.makeText(getApplicationContext() , "interrupted" , 0).show(); } private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = "Accessibility Service Channel"; String description = "Channel for accessibility service"; int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); // Register the channel with the system NotificationManager notificationManager = getSystemService(NotificationManager.class); if (notificationManager != null) { notificationManager.createNotificationChannel(channel); } } } }
配置文件
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackGeneric" android:notificationTimeout="1000" android:canRetrieveWindowContent="true" android:canRequestFilterKeyEvents="true" android:accessibilityFlags="flagDefault|flagReportViewIds|flagIncludeNotImportantViews" android:description="@string/accessibility_service_description" />
另外注意到Mt Manager、Current Activity等应用仍能正常获取应用完整类名。
解决方案
Android 14对后台服务和辅助功能的运行规则做了严格限制,以下是针对性修复步骤:
1. 为Accessibility Service指定前台服务类型
在Manifest的MyAccessibilityService声明中添加android:foregroundServiceType="specialUse",这是Android 14要求的,辅助功能类服务需明确此类型:
<service android:name="MyAccessibilityService" android:exported="true" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:foregroundServiceType="specialUse"> <!-- 新增此行 --> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> </service>
2. 更新Accessibility配置文件,补充关键标志
在accessibility_service_config.xml中添加提升服务优先级的标志,确保系统不会限制事件传递:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackGeneric" android:notificationTimeout="1000" android:canRetrieveWindowContent="true" android:canRequestFilterKeyEvents="true" android:accessibilityFlags="flagDefault|flagReportViewIds|flagIncludeNotImportantViews|flagRequestAccessibilityButton" android:description="@string/accessibility_service_description" android:canRequestEnhancedWebAccessibility="true" android:canPerformGestures="true" />
flagRequestAccessibilityButton能让服务绑定系统辅助按钮,提升后台运行优先级。
3. 提升前台通知的重要性
Android 14对前台通知的可见性要求更高,将通知通道的重要性改为IMPORTANCE_HIGH,确保服务在后台时不会被系统回收:
private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = "Accessibility Service Channel"; String description = "Channel for accessibility service"; int importance = NotificationManager.IMPORTANCE_HIGH; // 从DEFAULT改为HIGH NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); channel.setShowBadge(true); // 显示通知角标,增强可见性 NotificationManager notificationManager = getSystemService(NotificationManager.class); if (notificationManager != null) { notificationManager.createNotificationChannel(channel); } } }
4. 清理过时权限与API
- 移除
GET_TASKS权限,该权限在Android 10后已废弃,改用UsageStatsManager获取任务信息 - 确保用户已手动开启
PACKAGE_USAGE_STATS权限(引导用户前往「设置-应用-权限-使用情况访问权限」开启)
5. 优化事件调试方式
后台环境中Toast可能无法显示,改用Log输出事件信息,方便调试:
@Override public void onAccessibilityEvent(AccessibilityEvent event) { Log.d("AccessibilityService", "收到事件:类型=" + event.getEventType() + ",包名=" + event.getPackageName()); }
参考合规应用的实现逻辑
Mt Manager、Current Activity等应用能正常工作,核心是严格遵循Android 14的辅助功能规范:
- 正确声明前台服务类型
- 保持前台通知的高可见性
- 使用合规API获取窗口与任务信息,不依赖废弃接口
内容的提问来源于stack exchange,提问作者shweta Kumari
相关产品推荐
相关产品推荐

