1.前言

今世移动使用广告的过度侵扰问题现已引起了广阔用户的重视和不满。而芒果TV平台运营中心的副总经理陈超推出了一项名为”摇一摇开屏广告”的新策略↓

Android使用无障碍模式跳过应用广告的实现(仿李跳跳功能)

引发了更多关于用户体会的忧虑下↓

Android使用无障碍模式跳过应用广告的实现(仿李跳跳功能)

在这种策略下,用户在不经意间被强制翻开广告,这对用户来说无疑是一种糟糕的体会。当人处于运动的状态下,翻开某些APP

而“李跳跳”APP经过使用Android的无妨碍形式,”李跳跳”成功协助用户自动越过这些令人困扰的开屏广告,然后有效地减轻了用户的不方便。随之而来的不正当竞争指控引发了关于这类使用的法令和道德讨论。

我决定仿“李跳跳”写一个广告越过帮手,以呼吁关于这种过度侵扰性广告的重视,一起也为广阔Android开发者们分享运用的技能原理。

2.效果图

Android使用无障碍模式跳过应用广告的实现(仿李跳跳功能)

3.无妨碍形式

当咱们深入探讨”李跳跳”及其仿制使用的功用完成时,了解Android的无妨碍形式和AccessibilityService以及onAccessibilityEvent函数的详细内容至关重要。这些技能是这些使用背面的核心,让咱们更深入地了解它们:

3.1Android的无妨碍形式

无妨碍形式是Android操作体系的一个功用,旨在进步设备的可用性和可拜访性,特别是为了协助那些有视觉、听觉或运动妨碍的用户。经过无妨碍形式,使用能够获取有关用户界面和用户操作的信息,以便在需求时供给更好的支持。

3.2 onServiceConnected函数

这是AccessibilityService的回调函数之一,当服务被绑定到体系时会被调用。在这个函数中,能够进行初始化操作,如设置服务的配置、注册事情监听等。

@Override
public void onServiceConnected() {
    // 在这里进行服务的初始化操作
    // 注册需求监听的事情类型
}

3.3 onAccessibilityEvent函数

这是AccessibilityService的核心函数,用于处理发生的可拜访性事情。在这个函数中,能够检查事情类型、获取事情源信息以及采纳相应的操作。 本次功用主要用到的就是这个函数

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    // 处理可拜访性事情 
    // 获取事情类型、源信息,履行相应操作 
}

3.4 onInterrupt函数

这个函数在服务被中止时会被调用,例如,用户关闭了无妨碍服务或体系资源不足。能够在这里进行一些整理工作或记录日志以盯梢服务的中止状况。

@Override
public void onInterrupt() {
    // 服务中止时履行整理或记录日志操作
}

3.5 onUnbind函数

当服务被解绑时,这个函数会被调用。能够在这里进行资源的开释和整理工作。

@Override
public boolean onUnbind(Intent intent) {
    // 解绑时履行资源开释和整理操作
    return super.onUnbind(intent);
}

3.6 onKeyEvent函数(未用到)

这个函数用于处理键盘事情。经过监听键盘事情,能够完成自定义的按键处理逻辑。例如,能够捕获特定按键的按下和开释事情,并履行相应操作。

@Override
public boolean onKeyEvent(KeyEvent event) {
    // 处理键盘事情,履行自定义逻辑
    return super.onKeyEvent(event);
}

3.7 onGesture函数(未用到)

onGesture()函数答应处理手势事情。这些事情能够包括触摸屏幕上的手势,例如滑动、缩放、旋转等。经过监听手势事情,能够完成各种手势相关的使用功用。

@Override
public boolean onGesture(int gestureId) {
    // 处理手势事情,履行自定义逻辑
    return super.onGesture(gestureId);
}

4.功用完成

4.1无妨碍服务的启用和注册

  • 创建AccessibilityService的类。
public class AdSkipService extends AccessibilityService {
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }
    @Override
    public void onInterrupt() {
    }
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
}
  • 在AndroidManifest.xml文件中声明AccessibilityService。
<service android:name=".service.AdSkipService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>

4.2 onAccessibilityEvent函数的完成

  • 在onAccessibilityEvent函数中获取当时界面的控件,并在异步遍历一切子控件
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    // 获取当时界面的控件
    AccessibilityNodeInfo nodeInfo = event.getSource();
    taskExecutorService.execute(new Runnable() {
        @Override
        public void run() {
            //遍历节点函数,查找一切控件
            iterateNodesToSkipAd(nodeInfo);
        }
    });
}
  • 判别控件的文本是否带有“越过”二字
/**
 * 判别节点内容是否是关键字(默认为”越过“二字 )
 * @param node 节点
 * @param keyWords 关键字
 * @return 是否包括
 * */
public static boolean isKeywords(AccessibilityNodeInfo node, String keyWords){
    CharSequence text = node.getText();
    if (TextUtils.isEmpty(text)) {
        return false;
    }
    //查询是否包括"越过"二字
    return text.toString().contains(keyWords);
}
  • 触发控件的点击事情
/**
 * 点击越过按钮
 * @param node 节点
 * @return 是否点击成功
 * */
private boolean clickSkipNode(AccessibilityNodeInfo node){
    //尝试点击
    boolean clicked = node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    //打印点击按钮的成果
    LogUtil.e("clicked result = " + clicked);
    return clicked;
}

注:本篇章为了读者方便了解,对代码进行了简化,删去了繁琐的逻辑判别。具体完成详见源码

5.结语

咱们经过AccessibilityService和无妨碍形式,供给了一种改善用户体会的办法,协助用户摆脱令人不快的广告干扰。经过了解怎么开发这样的使用,咱们能够更好地了解无妨碍技能的潜力,并在维护用户权益的前提下改善使用环境。

假如对你有所协助,请记得帮我点一个赞和star,有什么意见和主张能够在谈论区给我留言

源码地址:github.com/Giftedcat/A…