当使用辅助服务检测到活动更改时,我正在实现将剪贴板文本粘贴到另一个应用程序的 EditText 视图。
在我的辅助功能服务上,辅助功能事件检测效果很好。但是当调用 onAccessibilityEvent 时,代码 event.getSource() 返回 null 对象。
public class ClipBoardPasteService extends AccessibilityService {
ClipboardManager clipboard;
@Override
public void onCreate() {
super.onCreate();
Log.i("MyTag", "clipboard service created");
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.i("MyTag", "ClipBoardPastedService : onAccessibilityEvent");
clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
AccessibilityNodeInfo source = event.getSource();
Log.i("MyTag", "source name : " + source.getViewIdResourceName());
source.performAction(AccessibilityNodeInfo.ACTION_PASTE);
}
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.i("MyTag", "ClipBoardPastedService : onServiceConnected");
String[] packages = {"com.google.android.talk"};
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.flags = AccessibilityServiceInfo.DEFAULT;
info.packageNames = packages;
//AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
info.eventTypes = AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED;
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
setServiceInfo(info);
}
}
这是我的 AndroidManifest.xml 的一部分
<service
android:name=".ClipBoardPasteService"
android:enabled="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
<category android:name="android.accessibilityservice.category.FEEDBACK_SPOKEN" />
</intent-filter>
<!-- from ICS -->
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
这是accessibility_service_config.xml
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/service_description"
android:packageNames="@null"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>
我搜索并发现了另一个stackoverflow的类似问题,但答案“Manifest中缺少元数据”没有意义。我的代码有什么问题吗?
并非所有事件类型都有来源。您应该检查该事件是否属于具有源的类型,然后以不同的方式处理这些事件。
例如 TYPE_WINDOWS_CHANGED 没有源,但 TYPE_VIEW_SCROLLED 有。为此,您应该仔细阅读 Android 文档。尽管有一定的逻辑,但还是有点混乱。如果因糟糕的文档和 API 设计而陷入混乱。
另请注意,在您的配置中,您的代码将覆盖您的 XML。删除 xml 中的 packagenames 行。并删除了您连接的服务中的所有代码。您只需覆盖您在服务配置 XML 文件中所做的配置即可。
最后,如果您需要使用代码覆盖某些配置,对于某些动态更改,您应该始终(阅读“几乎总是”)这样做:
AccessibilityServiceInfo info = getServiceInfo();
//modify info to your liking
setServiceInfo(info);
这可确保您创建正确构造的服务信息,并使用 XML 中的参数进行修改。这几乎总是设置全新配置的目的。
来源: http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html
我遇到了同样的问题,并且能够通过将此权限添加到 AndroidManifest.xml 来解决它
<application
...
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<service
...
</service>
...
</application>
我通过将 android:notificationTimeout 设置为 100 来解决这个问题。
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
android:packageNames="com.android.phone"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault|flagReportViewIds|flagIncludeNotImportantViews|flagRetrieveInteractiveWindows"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_service_description"
android:notificationTimeout="100"/>