Android .不一样的辅助服务,打开一个全新视角
1.先简单看看服务服务怎么用:
1.新建一个类继承AccessibilityService,并在AndroidManifest文件里注册它:
- <application>
- <service android:name=".MyAccessibilityService"
- android:label="@string/accessibility_service_label">
- <intent-filter>
- <action android:name="android.accessibilityservice.AccessibilityService" />
- </intent-filter>
- </service>
- <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
- </application>
- <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/accessibility_service_description"
- android:packageNames="com.example.android.apis"
- android:accessibilityEventTypes="typeAllMask"
- android:accessibilityFlags="flagDefault"
- android:accessibilityFeedbackType="feedbackSpoken"
- android:notificationTimeout="100"
- android:canRetrieveWindowContent="true"
- android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
- />
2.谈谈辅助服务的事件变化触发的方法:
onServiceConnected() - 可选。系统会在成功连接上你的服务的时候调用这个方法,在这个方法里你可以做一下初始化工作,例如设备的声 音震动管理,也可以调用setServiceInfo()进行配置工作。 onAccessibilityEvent() - 必须。通过这个函数可以接收系统发送来的AccessibilityEvent,接收来的AccessibilityEvent是经过过滤的,过滤是在配置 工作时设置的。 onInterrupt() - 必须。这个在系统想要中断AccessibilityService返给的响应时会调用。在整个生命周期里会被调用多次。 onUnbind() - 可选。在系统将要关闭这个AccessibilityService会被调用。在这个方法中进行一些释放资源的工作。
我们最主要的方法还是看,processAccessibilityEnvent(AccessibilityEvent event) ,那么从这个方法当中,每一次手机界面上的变化它都会传递时间给你常用的如下:
// TYPE_WINDOW_STATE_CHANGED Activity跳转,或者dialog弹出触发 // TYPE_NOTIFICATION_STATE_CHANGED 通知栏变化 // TYPE_WINDOW_CONTENT_CHANGED 内容变化 // TYPE_VIEW_CLICKED 点击触发
标题说要是一个全新视角,那么接下来就开始描述了。服务服务的每一次时间触发都会在processAccessibilityEnvent里传递你一个事件,你可以去取元素来做点击,滑动,长按,等等的行为。这个时候我我要是业务需求复杂一点,那么你在这个方法里就得写很多判断,就是很多if else了。代码看起来长,简直不能忍,于是啊我就脑洞大开,能不能把这种事件型的传递方式改为面向过程试的方式那?当然当然是可以,下面谈谈主要设计:
服务服务是可以拿到当前界面的名称,也就是我们写Activity的名称,包名等等的信息,那么这个就是我们用来写逻辑的利器了。
假设有AB连个界面,如果我们从A界面点击到B界面,那么辅助服务会触发一个TYPE_WINDOW_STATE_CHANGED 的事件,还会触发内容变化的一个事件,大家想想,到B界面的时候我们是能够拿到B界面的Activity名称的。假设A界面到B界面中间有一个dialog,一直有网络延迟。那么对于面向过程就是一个艰苦的过程了。那么到底该怎么去面向过程那:
设想一下,我们是不是可以在每次辅助服务事件触发的时候去缓存一个当前最新的一个界面信息,然后我们从缓存方法中去实现点击,滑动等等的时间。经过测试,这个方案是可行,那么然后如何让A界面到B界面能够尽快触发那:接下来看代码:
先声明一个 private static AccessibilityNodeInfo nodes = null;
那么这样就缓存了一个静态的当前最新的信息,那么都是静态的了,想在哪里调用都可以啊,辅助服务4。4以上的api是可以去点击控件id和文本的,那么我们封装两个点击的 方法,
![]()
点击的方法现在举了个例子,那么还有一个问题没解决,A界面到B界面来怎么控制:我们是否可以提供一个方法,然后设置一个Activity名字进去,刚才讲过,在辅助服务里边触发事件中可以拿到当前的Activity名字,如果我们提供一个方法,在全局设置一个Actiivty名字,然后把自己的这个方法写个死循环阻塞起来,服务服务收到的名字我们设置的名字一样的时候,然后就释放阻塞,这样就解决问题了。接下里看代码:那么这样的话就可以保证效率最快的去做自己想要做的事情了,还是按A到B界面来写行为就简单多了,
那么到了B界面马上就会去执行两个点击的行为,这样的话逻辑就好理解了,不用去写很多if else 。目前在网上没有看到类似的思路,希望今天的文章能让你需要用这个功能的时候给你一个方向。当然要看懂本文也是需要对辅助服务有一点了解的,不然应该不明白我在讲什么。希望这个思路能给大家带来帮助。。