我正在尝试通过AccessibilityService
发送系统返回新闻事件,这样可以正常工作,但前提是我不在我自己的应用中。
我总是从true
获得performGlobalAction
,无论我是否在自己的应用程序中,但我只看到如果我不在我自己的应用程序中,事件就会被执行应用程序,但在任何其他一个(从上面的活动显示或类似的意义上)
为什么会这样?我的应用是一个侧边栏应用,在WindowManager
顶部显示了叠加层,一切正常(AccessibilityService
正在运行,正在处理我的自定义事件,服务总是返回我的事件的成功消息,但我的自己的应用程序不会对后退按钮事件做出反应。)
我的服务如下:
public class MyAccessibilityService extends AccessibilityService {
public static void sendBackIntent(Context context) {
Intent intent = new Intent(context, MyAccessibilityService.class);
intent.putExtra("action", GLOBAL_ACTION_BACK);
context.startService(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle extras = intent.getExtras();
Integer action = null;
if (extras != null) {
action = extras.getInt("action");
}
if (action != null) {
switch (action) {
case GLOBAL_ACTION_BACK:
boolean result = performGlobalAction(action);
L.d("Action %d executed: %b", action, result);
break;
default:
L.e("Unhandled action %d", action);
break;
}
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
}
修改
说清楚:
MyAccessibilityService.sendBackIntent(context)
启动此服务,我发送的意图如下:if (isAccessibilityserviceRunning) MyAccessibilityService.sendBackIntent(context)
AccessibilityService
中的accessibilityservice.xml
设置了所有内容,并使用它来定义我的服务设置,这也完美无缺,我想要接收的所有事件都可靠且正确地接收编辑2
在我的情况下似乎我的叠加层仍在窃取焦点,使其可以集中注意力,并且没有时间问题,有时会产生问题。尽管如此,我可以使用BroadcastReceiver
与服务进行通信来改进我的解决方案,因为startService
调用不安全,如接受的答案所述
答案 0 :(得分:2)
让我觉得你在做一些非常奇怪的事情。您似乎将AccessibilityService
视为正常Service
。这部分表明这是您对方法的以下实现:
public static void sendBackIntent(Context context);
@Override
public int onStartCommand(Intent intent, int flags, int startId);
仅仅通过这两种方法的签名和你的
的召唤context.startService(intent);
在你的静态方法中,我可以说你不理解AccessibilityServices
以及他们应该如何执行他们的工作。您无法以您尝试的方式启动辅助功能服务,也无法与其进行交互。当然,您可以使用辅助功能服务来执行全局操作,但除非您从“辅助功能服务”菜单(您知道TalkBack显示的菜单)中正确启动它们,否则它们不会准确全局地执行此操作。
您的代码本质上并不是在您认为正在运行的上下文中运行。因此,它运行并执行某些操作。但是,AccessibilityServices
及其各自的力量在于它们能够全局连接到操作系统。当您尝试使用以下命令启动服务时,Android API将无法正确绑定AccessibilityService。
context.startService(intent);
您必须从“辅助功能服务设置”菜单启动辅助功能服务。
即使您的服务已经启动,这样的通话也是不安全的!在打开您的活动之前,无法保证您的用户将启动该服务。调用context.startService
并尝试以这种方式启动AccessibilityService后,它将阻止辅助功能设置菜单启动您的服务并正确绑定到操作系统。实际上,在这种情况下,用户必须:在“辅助功能设置”菜单中关闭服务开关,强制停止(甚至卸载)您的应用程序,重新启动设备,启动服务然后开始您的活动,为了实现正确的行为。
如果您不这样做,它将无法正确绑定到操作系统,并且其行为未定义。现在,你实际上已经在操作系统中创建了一个hack,并且正在遇到所谓的未定义行为,这种行为在版本,制造商等方面可能会有很大差异,因为它的行为不在AOSP集成测试中。
事实上,您明确无法使用context.startService()
调用启动辅助功能服务。这是Android的一个非常重要的安全功能,因为Accessibility Services可以访问屏幕内容,用户需要对允许此访问的提供商和应用程序进行细粒度控制。所以,虽然你可能会得到一些行为,但这是不明确和危险的行为。你想要的是如下:
使用以下服务配置XML:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeWindowContentChanged"
android:accessibilityFlags="flagRequestTouchExplorationMode"
android:canRetrieveWindowContent="true"
android:canRequestTouchExplorationMode="true"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="100"
android:settingsActivity="com.service.SettingsActivity"
/>
以及以下辅助功能服务。
class MyA11yService extends AccessibilityService {
@Override public boolean onGesture(int gestureId) {
switch (gestureId) {
case GESTURE_SWIPE_UP_AND_DOWN:
CLog.d("Performing gesture.");
performGlobalAction(GLOBAL_ACTION_BACK);
return true;
default:
return false;
}
}
}
performGlobalAction
调用在任何Context
中都可以正常使用。现在,您不想在SWIPE_UP_DOWN手势上执行此操作,而是要设置某种进程间通信,并希望能够触发“全局后退按钮”操作。但是,这些信息是针对另一个问题的,但是如果你理解了这篇文章中的信息,我确定你需要继续进行的是明确的。