Android - 不活动/Activity ,无论顶级应用程序如何

标签 android

我需要找出最后一次用户交互的时间,无论哪个应用程序位于顶部。我不关心事件发生在哪里或发生了什么,我只需要知道事件发生的时间。或者,碰巧我收到一个事件。

我尝试了多种方法:

  1. 使用窗口创建服务并添加触摸监听器。这吃掉了触摸事件并且没有将其传递下去
  2. 寻找 shell 命令。 getevent 可以工作(每次收到触摸时都会出现新行),但是您需要 root,因此这对我来说不是合适的解决方案。
  3. 寻找“锁定前的时间”,但一无所获。

另请注意:这不存在安全问题,因为我不需要任何识别信息,例如触摸位置。只是一个类型标记(或现场 Activity )。

我也愿意使用反射来解决这个问题。


@user2558882 有一个非常好的解决方案。到目前为止,这是我遇到的最好的方法。

虽然这很棒,但它仍然需要用户在辅助功能控件中手动启用我们的应用程序。我们拥有拥有数千台设备的客户,并且我们有一种自动更新和更改设置的方法。我们尝试将手动配置保持在最低限度,但有些事情仍然需要用户输入,例如启用设备管理模式。因此,这个解决方案是可以接受的,但我仍然愿意接受一种不需要任何用户输入即可启用的方式。


我最终实现了@user2558882使用无障碍服务的想法。但欢迎其他想法。

最佳答案

这只是一个想法,可能无法完全移植。

这是 AccessibilityService 可以执行的操作:

An accessibility service runs in the background and receives callbacks by the system when AccessibilityEvents are fired. Such events denote some state transition in the user interface, for example, the focus has changed, a button has been clicked, etc.

您将被告知onAccessibilityEvent(AccessibilityEvent)内的事件:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    // Some event

    timeSinceLastInteraction = System.currentTimeMillis();

}

您可以定期记录更新:

Log.i("LOG_TIME_ELAPSED", "Last user interaction was " + 
             ((System.currentTimeMillis() - timeSinceLastInteraction) / 1000) + 
                      " seconds ago.");

您可以通过两种方式配置 AccessibilityService:

  1. 在代码中,在 onServiceConnected() 内。 (API 4 及以上)

  2. 在 xml 中,在服务中使用 meta-data 标记。 (API 14 及以上)

就您的应用程序而言,您可以将 AccessibilityServiceInfo.eventTypes 设置为:

accessibilitySeviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;

但是,TYPES_ALL_MASK 将包含以下通知:AccessibilityEvent.TYPE_ANNOUNCMENT、AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED 等,我猜您不介意拦截这些通知。因此,您需要选择 AccessibilityEvent.TYPE_X 的子集。

您应该注意的另一件事是通知超时:

The timeout after the most recent event of a given type before an AccessibilityService is notified.

The event notification timeout is useful to avoid propagating events to the client too frequently since this is accomplished via an expensive interprocess call. One can think of the timeout as a criteria to determine when event generation has settled down.

因此,请慷慨地设置超时值。

如果您决定使用 AccessibilityService 选项,您会发现此页面非常有用:Developing an Accessibility Service .

从您对 Chloe 的回答的评论来看,设备似乎在您的控制之下:这意味着,在某种程度上,您不必依赖用户来启用该服务:

The lifecycle of an accessibility service is managed exclusively by the system and follows the established service life cycle. Additionally, starting or stopping an accessibility service is triggered exclusively by an explicit user action through enabling or disabling it in the device settings.

您可以在部署时启用 AccessibilityService,并可能使用 AppLock 等应用程序限制对“设置”菜单的访问。

另一个选项是检查您的 AccessibilityService 是否不时启用:

AccessibilityManager am = (AccessibilityManager)
                               getSystemService(ACCESSIBILITY_SERVICE);

List<AccessibilityServiceInfo> listOfServices = 
                             am.getEnabledAccessibilityServiceList(
                               AccessibilityServiceInfo.FEEDBACK_ALL_MASK);

for (AccessibilityServiceInfo asi : listOfServices) {

    // Check if your AccessibilityService is running

}

如果 AccessibilityService 已被好奇/臭名昭著的用户禁用,您可以通过显示带有文本的全屏 View 来锁定设备:设备已被锁定。请联系销售代表解锁此设备

关于Android - 不活动/Activity ,无论顶级应用程序如何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18882331/

相关文章:

android - TabLayout 多行时文本大小发生变化

java - 在 Android 的 Couchbase lite 中获取嵌套的 JSON

javascript - 如何确定音频文件扩展名可能是什么(Chrome,Android)?

android - Bluez 架构 : Explain this Architecture

android - 无法使用 gradle 将 xstream 1.4.8 依赖项添加到 Android

Android:无法从 View 转换到图库

android - XML 解析器无连接错误

javascript - cordova 应用程序中全屏模式下的纵向 HTML5 视频在 Android 设备上被拉伸(stretch)

android - 亚马逊 S3 和安卓

android - 在android中使用GPS确定车辆的速度