这只是一个想法,可能无法完全转移。
以下是 AccessibilityService 可以做的事情:
无障碍服务在后台运行,并在触发 AccessibilityEvents 时接收系统的回调。此类事件表示用户界面中的某些状态转换,例如,焦点已更改、按钮已被单击等。
您将被告知里面的事件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:
在代码中,在 onServiceConnected() 内部。(API 4 以上)
在 xml 中,使用meta-data
服务中的标记。(API 14 以上)
在您的应用程序的情况下,您可能会设置AccessibilityServiceInfo.eventTypes
为:
accessibilitySeviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
但是,TYPES_ALL_MASK 将包括通知,例如:AccessibilityEvent.TYPE_ANNOUNCEMENT、AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED 等,我猜你不想拦截。因此,您需要选择 AccessibilityEvent.TYPE_X 的子集。
您应该注意的另一件事是通知超时:
在通知 AccessibilityService 之前给定类型的最新事件之后的超时。
事件通知超时对于避免过于频繁地将事件传播到客户端很有用,因为这是通过昂贵的进程间调用来完成的。可以将超时视为确定事件生成何时稳定的标准。
因此,请慷慨地设置超时值。
如果您决定使用 AccessibilityService 选项,您会发现此页面非常有用:开发可访问性服务。
从您对 Chloe 的回答的评论来看,该设备似乎在您的控制之下:这意味着,在某种程度上,您不必依赖用户来启用该服务:
无障碍服务的生命周期完全由系统管理,并遵循既定的服务生命周期。此外,启动或停止可访问性服务仅由显式用户操作通过在设备设置中启用或禁用来触发。
您可以在部署时启用 AccessibilityService,也可以使用AppLock 之类的应用程序限制对 Settings 菜单的访问。
另一种选择是检查您的 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 已被好奇/臭名昭著的用户禁用,您可以通过显示带有文本的全屏视图来锁定设备:Device has been locked. Contact a Sales Rep to unlock this device
.