当前位置: 首页 > 知识库问答 >
问题:

如何向AccessibilityService发送自定义事件?

邵子平
2023-03-14

我的程序目的:触发服务中的BACK按钮

我尝试了很多方法,没有人能达到这个目的,最后我发现了AccessibilityService,它可能是实现这个功能的最可能的方法。

我创建了这个AccessibilityService,并测试它是否正常工作

package com.accessibilityservice;

public class MyAccessibilityService extends AccessibilityService {
    public MyAccessibilityService() {
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

        performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);

    }

    @Override
    public void onInterrupt() {

    }
}

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="desc"
    android:notificationTimeout="100"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity" />

然后我尝试将performGlobalAction移动到服务,但它不执行操作。

public class MyService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        MyAccessibilityService mas=new MyAccessibilityService();
        mas.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
    }
}

我也尝试以不同的方式发送自定义事件,但没有人可以发送到MyAccessibilityService

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    //method1
    AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_CLICKED);
    event.setContentDescription("this is description");
    View view = new View(this);
    ViewParent parent = view.getParent();
    if (parent != null) {
        parent.requestSendAccessibilityEvent(view, event);
    }

    //method2
    AccessibilityManager manager = (AccessibilityManager) getApplicationContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
    AccessibilityEvent event = AccessibilityEvent.obtain();
    event.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
    event.setPackageName("p");
    event.setClassName("c");
    manager.sendAccessibilityEvent(event);
}

如何向MyAccessibilityService发送自定义事件或消息,以便识别执行操作的事件和消息?

共有3个答案

穆宾白
2023-03-14

我不确定这是否是正确的方法,但它会让你的工作完成。在可访问性服务方法onServiceConnection()中注册广播接收器,如下所示。

@Override
protected void onServiceConnected() {
    super.onServiceConnected();
    registerReceiver(listener, new IntentFilter("my_custom_event_listener));
}

@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(listener);
}

还有你的广播接收器在你的无障碍服务中

private class MyCustomListener extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
       Bundle extras = intent.getExtras();
        if(extras != null){
            String action = extras.getString("action");
            if(action.equals("back")
                performGlobalAction(GLOBAL_ACTION_BACK);
        }
}

与其创建事件,不如发送如下所示的广播来执行回退操作:

Intent back = new Intent("my_custom_event_listener");
Bundle data = new Bundle();
data.putString("action", "back");
back.putExtras(data);
sendBroadcast(back);
嵇丰
2023-03-14

您无法以尝试的方式运行辅助功能服务。辅助功能服务只能作为辅助功能服务运行。如果您了解可访问性服务的功能,这里的原因是显而易见的。他们可以做的事情:

    < li >跟踪键盘事件 < li >调查文本字段的内容 < li >任意发送动作事件

这些很容易被用于恶意目的。允许一个应用程序,甚至是一个标准服务,启动一个可以做这些事情的进程,这将是可怕的安全性。因此,只有系统才能启动具有所有相关权限的可访问性服务。它执行此操作的唯一位置是“辅助功能设置”菜单。通过这种方式,用户至少知道可访问性服务正在运行的时间,并且可以对他们运行的这些服务的类型更加谨慎。

这也导致了整体的答案:不能。至少不运行实际的可访问性服务,然后直接向其发送意图。但是用户必须自己单独启动你的服务。

闻人献
2023-03-14

1.创建服务的静态字段

公共静态 MyAccessibilityService 实例;

2然后在onServiceConnected()中初始化它

    @Override
    protected void onServiceConnected() {
    super.onServiceConnected();
    instance = this;
}

3不要忘记在onUnbind()中清除它

    @Override
    public boolean onUnbind(Intent intent) {
    instance = null;
    return super.onUnbind(intent);
}

当用户在设备设置中向您的应用程序授予权限时,系统将调用onServiceConnection()

onUnbind()是用户撤销该权限的时候

4随时随地使用您的实例

if(MyAccessibilityService.instance != null)
    MyAccessibilityService.instance.performGlobalAction(....)
 类似资料:
  • 问题内容: 我试图在PyQt中发出自定义事件。一个小部件将发出,另一个小部件将监听事件,但是两个小部件不需要关联。 在JavaScript中,我会这样做 编辑:我知道信号和插槽,但只知道如何在父级和子级之间使用它们。我如何在任意不相关的小部件之间使用这种机制(或其他机制)? 问题答案: 在PyQt中,以下说明: 等价的 以类似的方式: 等价的 但是最大的区别是“文档”对象的范围,因为连接是在全局元

  • 我试图使用Spring Boot/Spring数据,遵循DDD体系结构准则来实现一个应用程序。我有一个聚合根,它使用方法AbstractAggregateRoot::RegisterEvent()发布域事件。此外,为了日志/跟踪的目的,我需要截获这些事件,所以我决定做一个实验: 首先,实现自定义ApplicationEvent发布服务器 然后注册为bean 一旦我用注入的ApplicationEv

  • 我正在创建一个应用程序,我需要从自定义gmail域发送电子邮件。这是我的代码。 它给我的错误如下: 线程"main"中的异常java.lang.运行时异常:javax.mail.身份验证失败异常:534-5.7.14请通过534-5.7.14您的Web浏览器登录,然后重试。534-5.7.14在534 5.7.14https://support.google.com/mail/answer/787

  • /** 自定义消息发送接口(目前只支持文本消息发送) @param chatController 聊窗实体(必须是小能SDK创建的聊窗实体NtalkerChatController类型) @param type 消息类型: 11:文本消息 12:图片消息 13:语音消息 14:视频消息 @param message 消息内容 */ NSString *str = @“自定义文本消息test”;

  • 我正试图发送一个授权令牌,但我的服务器不知何故没有接收它。 //service.ts } //endpoint //标记过滤器

  • 问题内容: 我正在通过制作一个简单的Twitter客户端来练习PyQt和(Q)线程。我有两个Qthread。 主/ GUI线程。 Twitter提取线程-每隔X分钟从Twitter提取数据。 因此,每隔X分钟,我的Twitter线程就会下载一组新的状态更新(Python列表)。我想将此列表移交给Main / GUI线程,以便它可以使用这些状态更新窗口。 我假设我应该使用信号/插槽系统将“状态” P