这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战
如何跳过掘金app的开屏广告(二)
上篇文章分析了,想要获取跳过开屏广告的核心就是手机帮助我们点击
跳过
按钮,最终也选定了无障碍服务作为我们的技术,这篇文章将实现跳过广告功能代码。
一、效果
程序点击跳过
要比手动点击快得多。
二、代码实现
2.1 关键回调
创建的服务继承AccessibilityService
类之后,又一个关键的回调,是onAccessibilityEvent
回调,我们的逻辑都在这个方法中。
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
复制代码
2.1 定位包名
我们只想在某个app或者某些app下进行跳过广告。
两种方法
- 在xml的config文件的
android:packageNames
属性添加应用包名 - 在service中获取包名,进行判断。
String packageStr = event.getPackageName().toString();
if (TextUtils.equals(packageStr, "com.xx.xxx")) {
}
复制代码
比如获取到的掘金app的包名是 com.daimajia.gold
ps: 随手网上搜索了一下代码家
,github上显示这个人是掘金的CTO了。
2.2 定位目标组件
想给一个组件添加点击方法,首先要定位到这个组件,获取这个组件,然后才能添加点击动作。
怎么定位组件呢?
笔者这里常用的有三种方法。
- uiautomator, Android sdk中自带,可以很方便的使用
- autoJs,这是一款app,也是用无障碍服务,基于无障碍服务添加了图形化界面,在手机端方便查看。
- 自己使用代码遍历查看。
具体分析:
掘金app的右上角有“跳过”文字,分析视图结构,大概是这样。
伪代码
<FragmentLayout id:fl_skip > // 实际点击事件在这个
<ProgressBar > // 这个是跳过效果的进度
<TextView text="跳过"> // 跳过的文字载体
</FragmentLayout>
复制代码
2.3 获取目标组件
首先获取到当前页面的所有组件 -> 然后获取到目标组件
使用getRootInActiveWindow()
获取所有的组件
使用findAccessibilityNodeInfosByViewId(“”)
获取所有符合该ID的NodeList 使用findAccessibilityNodeInfosByText()
获取所有符合该文字的NodeList
AccessibilityNodeInfo sourceNodeInfo = getRootInActiveWindow();
if (sourceNodeInfo == null)
return;
List<AccessibilityNodeInfo> textNodeInfoList = sourceNodeInfo.findAccessibilityNodeInfosByViewId("com.daimajia.gold:id/fl_skip");
if (textNodeInfoList.size() > 0) {
textNodeInfoList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
复制代码
2.4 设置点击操作
找到目标的定位的AccessibilityNodeInfo
之后,我们开始进行操作。
常用的有
ACTION_CLICK:在节点信息上点击的操作。 ACTION_LONG_CLICK:在节点上点击长按的操作。 ACTION_COPY:将当前选择拷贝到剪贴板的操作。 ACTION_CUT:剪贴当前选项并放置到剪贴板的操作。 ACTION_FOCUS:给节点添加输入焦点的操作。
我们执行 AccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
就可以达到效果了。
2.5 代码部分
想要实现其它app的功能,可以在代码上进行拓展。
完整代码。
package com.demo.accessibilitydemo;
import android.accessibilityservice.AccessibilityService;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import java.util.List;
public class MyService extends AccessibilityService {
private final String TAG = "MyService";
public MyService() {
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, "package:" + event.getPackageName());
String packageStr = event.getPackageName().toString();
if (TextUtils.equals(packageStr, "com.daimajia.gold")) {
AccessibilityNodeInfo sourceNodeInfo = getRootInActiveWindow();
if (sourceNodeInfo == null)
return;
List<AccessibilityNodeInfo> textNodeInfoList = sourceNodeInfo.findAccessibilityNodeInfosByViewId("com.daimajia.gold:id/fl_skip");
if (textNodeInfoList.size() > 0) {
textNodeInfoList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
@Override
public void onInterrupt() {
}
}
复制代码