模拟用户点击,“去除”USB弹框

前言

最近公司里要做一款简易的自助机。功能:取号。硬件:一台Android系统的触摸设备内置热敏打印机。打印机与Android设备通过usb进行连接。

遇到的问题

用过android设备的人都知道。当USB设备连接到Android系统的设备时,会出现一个弹出窗口,要求获得用户许可。当用户点击确认后弹框会消失,但是当Android设备重启之后,再次进行连接的时候仍然会弹出这个弹框。然后我的自助机碰到了同样的问题,即使“默认情况下用于该usb设备”勾选了也没用。既然是自助机,那怎么能让机器每次都弹出这个弹框呢!(盗用一张网上的图片)
在这里插入图片描述

解决思路

既然不知道该怎么解决,那就百度吧。你别说网上答案还挺多,可是一篇篇看下来真的是让人有点小失望。因为网上的解决方法基本上都是修改系统源码,有兴趣的可以去这里https://blog.csdn.net/angelsmiling/article/details/103678754 看看。方法是很简单,只需要注释一些代码就可以了。但是编译源码什么的是真的麻烦。最主要的是我不会,没办法只能找别的方法了。
既然无法做到去除弹框,那我为什么不能模拟用户点击默认点击“确定”呢。没错就这么干。

解决办法

如果不清楚什么是“模拟用户点击”确切来说是“无障碍服务”可以先去百度下“AccessibilityService”这个方法。
好了不说废话了直接上代码。
首先需要在res目录下的xml目录下建立配置文件:accessible_service_config.xml ,名字随意取。
在这里插入图片描述
accessible_service_config.xml的配置如下:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/desc"
    //usb所在的包名,这里的包名不能乱写,包名不正确你的程序没影响但是功能却实现不了
    android:packageNames="com.android.systemui"
    />

accessibilityEventTypes:设置响应事件的类型,这里设置typeAllMask,就是响应全部类型的事件。

accessibilityFeedbackType:设置回馈给用户的方式,有语音播出和振动,这里使用通用类型。

packageNames:目标包名(这个很重要)。至于包名如何获取大家可以看一下这篇文章https://www.jb51.net/article/133593.htm

之后就可以编写我们的service了

public class MyAccessibilityService extends AccessibilityService {
    private static final String TAG = "TAG";
    private Map<Integer, Boolean> handleMap = new HashMap<>();
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        AccessibilityNodeInfo nodeInfo = event.getSource();
        if (nodeInfo != null) {
            int eventType = event.getEventType();
            //当跳出弹框的时候,窗口会发生变化。根据这个进行判断
            if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED || eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                if (handleMap.get(event.getWindowId()) == null) {
                    boolean handled = iterateNodesAndHandle(nodeInfo);
                    if (handled) {
                        handleMap.put(event.getWindowId(), true);
                    }
                }
            }
        }
    }
    @Override
    public void onInterrupt() {
    }
    //遍历节点,模拟点击安装按钮
    private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            if ("android.widget.Button".equals(nodeInfo.getClassName())) {
            //这里通过文案找节点。当然你也可以通过id来找(可是我不会,确认来说怕麻烦)
                String nodeCotent = nodeInfo.getText().toString();
                Log.d(TAG, "content is: " + nodeCotent);
                if ("安装".equals(nodeCotent)
                 || "完成".equals(nodeCotent) 
                 || "确定".equals(nodeCotent)) {
                    Log.d("jaa", "content is: " + nodeCotent);
                    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    return true;
                }
            }
            //遇到ScrollView的时候模拟滑动一下
            else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                if (iterateNodesAndHandle(childNodeInfo)) {
                    return true;
                }
            }
        }
        return false;
    }
}

最后记得在manifest中进行注册,添加权限

<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
<service
            android:name=".MyAccessibilityService"
            android:label="智能安装App
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>

            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service_config" />
        </service>

使用

程序安装之后首先在手机的设置功能里面找到辅助功能(有的是无障碍功能)之后找到你自己服务
在这里插入图片描述
然后打开服务
在这里插入图片描述
最后打开你的程序。以上代码实测可行,问题解决。(录屏什么的太麻烦,所以就没搞)。这里说一个简单测试方法,比如说打开你的程序后跳出一个AlertDialog,AlertDialog上有两个按钮“取消”和“确定”。(记得更改accessible_service_config.xml 中 android:packageNames=“你的应用包名”)

后记

我测试的环境都是在root的android设置上进行了。至于没有root的设置行不行我没试,有兴趣的朋友们可以试一下。
最后说一点,博主的文笔很烂大家将就着的看吧。(抱歉,抱拳)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值