用户展开通知时未调用AccessibilityEvent(状态栏)

时间:2017-04-24 15:26:45

标签: android events notifications accessibility accessibilityservice

我的代码从AccessibilityService检测当前正在运行的应用程序,但是当用户展开状态栏时,不会调用任何事件。我试图添加TYPE_NOTIFICATION_STATE_CHANGED和TYPES_ALL_MASK但没有任何改变。任何人都可以帮助我吗?

from __future__ import print_function
import urllib2 
from multiprocessing.dummy import Pool as ThreadPool 

import hashlib
import datetime
import json

print('Loading function')

def lambda_handler(event, context):

  f = urllib2.urlopen("https://example.com/geturls/?action=something");
  data = json.loads(f.read());

  urls = [];
  for d in data:
      urls.append("https://"+d+".example.com/path/to/action");

  # Make the Pool of workers
  pool = ThreadPool(4);

  # Open the urls in their own threads
  # and return the results
  try:
     results = pool.map(urllib2.urlopen, urls);
  except URLError:
     try:                              # try once more before logging error
        urllib2.urlopen(URLError.url); # TODO: figure out which URL errored
     except URLError:                  # log error
        urllib2.urlopen("https://example.com/error/?url="+URLError.url);

  #close the pool and wait for the work to finish 
  pool.close();
  return true; # always return true so we never duplicate successful calls

1 个答案:

答案 0 :(得分:1)

两件事。首先,当您设置辅助功能服务信息时,我建议这样做:

AccessibilityServiceInfo info = getServiceInfo();
//Set things in here
setServiceInfo(info);

现在,这不会解决这个问题。但是,这是一个很好的做法。您不想从服务配置XML中获取所有设置。此外,还有一些初始化选项和难以正确使用的东西,而不让Android系统为您初始化info对象。只需抓住当前的一个,根据自己的喜好进行调整,然后重置。事实上,我发现您所做的任何更改都无法在service_config xml文件中进行编辑。使用服务XML配置,它是一个更好的整体实践!

现在,您遇到的问题是您的配置完全错误。注意eventTypes有点掩盖。这意味着在以下行中:

asi.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;

你说的只是听WINDOW_STATE_CHANGED个事件。这太傻了。我喜欢做的是设置为TYPE_ALL_MASK,直到我确切知道为我想要的事件触发了哪些通知。然后过滤掉那些。您还可以使用TYPE_ALL_MASK并使用switch语句进行过滤,如果您正在收听各种不同的事件,这最终是必要的,因为不同的事件会填充不同的信息(EX:并非所有事件都有源节点信息)。

现在,为什么您使用的事件类型无效:

TYPE_NOTIFICATION_STATE_CHANGED:添加新通知时会触发此事件,而不是在向下滚动通知窗口时触发。

TYPE_WINDOW_STATE_CHANGED:当一个视图占用整个屏幕并且在允许访问背景内容之前需要进行交互时会激活此窗口。像模态对话,菜单等的东西。这个的定义非常粗略,而且不一致。我相信在后端,最终触发这一点的是绘制任何需要" SYSTEM_ALERT_VIEW"许可,而不是我给出的定义。但是,这个定义是意图...... YEAH Android可访问性文档很糟糕。

所以,现在我们知道了这个问题。我建议A:不使用代码配置服务信息,B:使用TYPE_ALL_MASK观察所有事件,并确定哪些事件最一致。如果您观看所有事件,则可能会在向下滚动通知栏时看到许多辅助功能事件。选择一个最可靠的/在碰撞时刻发生的事情(EX:有些人可能会在所有内容被渲染之前解雇......),然后对此进行过滤。

这是我开始的地方。

AndroidManifest.xml服务配置:

<service
        android:name=".A11yService"
        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/service_config" />

    </service>

service_config xml文件:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds"
    android:canRetrieveWindowContent="true"
    android:canRequestTouchExplorationMode="true"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:settingsActivity="com.deque.accessibilityanalyzer.SettingsActivity"
    />