IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 通过AccessibilityService(无障碍服务)自动在设置界面打开App所需要的对应权限 -> 正文阅读

[移动开发]通过AccessibilityService(无障碍服务)自动在设置界面打开App所需要的对应权限

最近看到一个项目比如说需要允许访问应用权限、以及录屏等权限的时候 在手机运行的时候点击跳转至无障碍界面点击打开无障碍服务,然后调转至设置界面,然后手机就自动的一步一步的打开App所需的权限,看起来特别牛逼和智能的亚子。了解了一下发现通过AccessibilityService这个类可以完成上述需求。但是由于每款手机的设置界面是不相同的,所以需要做不同的机型判断适配机型。我的是在华为 Honor 9i(Android 9.0系统)中完成自动设置权限的功能的。

关于AccessibilityService类我就不做过多的解释了,直接撸代码

1.在清单文件的application中添加:

    <service
        android:name="com.hxf.childapp.AutoDebugService"
        android:enabled="true"
        android:exported="true"
        android:label="你的包名"
        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/autodebug"/>
    </service>

2.配置需要监听的包名和行为,也就是@xml/autodebug文件:在xml文件夹中创建autodebug文件。

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask|typeWindowStateChanged|typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagReportViewIds"
    android:canPerformGestures="true"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:packageNames="com.android.settings" />

这里说一下 android:packageNames中的值就是需要监听的应用。

3.创建AutoDebugService类继承自AccessibilityService类:

public class AutoDebugService extends AccessibilityService {
	
}

4.重写方法:

@Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    
    }

需要重写的核心方法 所有事件都是从这个方法监听的,比如界面改变,点击,长按等事件。

5.通过事件判断是否监听:

if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType() || AccessibilityEvent.TYPE_VIEW_CLICKED == event.getEventType()) {

}

此处我是通过界面改变和点击事件进行过滤,逻辑都是写在此回调方法中,

以下就是全部代码,只供参考思路,不同的手机是需要适配的。

public class AutoDebugService extends AccessibilityService {
    int index = 0;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType() || AccessibilityEvent.TYPE_VIEW_CLICKED == event.getEventType()) {
            if (step == 0) {
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType()) {
                    event("com.android.settings:id/dashboard_container", "帐户");
                    Log.e("lee", step + "*******");
                }
            } else if (step == 1) {
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType()) {
                    Log.e("lee", step + "*******");
                    back();
                }
            } else if (step == 2) {
                if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType()) {
                    back();
                }
            } else if (step == 3) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType()) {
                    event("com.android.settings:id/dashboard_container", "安全和隐私");
                }
            } else if (step == 4) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 5) {
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 6) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/dashboard_container", "桌面和壁纸");
            } else if (step == 7) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/list", "桌面风格");
            } else if (step == 8) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/normal_l_ui_sector", "标准风格");
            } else if (step == 9) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 10) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 11) {
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 12) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/dashboard_container", "应用");
            } else if (step == 13) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/list", "应用分身");
            } else if (step == 14) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                check("com.android.settings:id/clone_app_switche");
            } else if (step == 15) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 16) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 17) {
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 18) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/dashboard_container", "应用");
            } else if (step == 19) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/list", "应用启动管理");
            } else if (step == 20) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                check("com.huawei.systemmanager:id/app_control_switch");
            } else if (step == 21) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 22) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 23) {
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 24) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/dashboard_container", "系统");
            } else if (step == 25) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/list", "开发人员选项");
            } else if (step == 26) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                event("com.android.settings:id/list", "USB 调试");
            } else if (step == 27) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 28) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            } else if (step == 29) {
                Log.e("lee", step + "*******");
                try {
                    Thread.sleep(700);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                back();
            }
        }
    }

    /**
     * 通过Id获取AccessibilityNodeInfo
     *
     * @param id
     * @return
     */
    private List<AccessibilityNodeInfo> findNodesById(String id) {
        AccessibilityNodeInfo root = getRootInActiveWindow();
        if (root != null) {
            return root.findAccessibilityNodeInfosByViewId(id);
        }
        return null;
    }

    /**
     * 通过Text获取AccessibilityNodeInfo
     *
     * @param text
     * @return
     */
    private List<AccessibilityNodeInfo> findNodesByText(String text) {
        AccessibilityNodeInfo root = getRootInActiveWindow();
        if (root != null) {
            return root.findAccessibilityNodeInfosByText(text);
        }
        return null;
    }

    /**
     * 处理事件
     *
     * @param id
     * @param text
     */
    private void event(String id, String text) {
        List<AccessibilityNodeInfo> byIdList = findNodesById(id);
        List<AccessibilityNodeInfo> byTextList = findNodesByText(text);
        if (byTextList != null && byTextList.size() > 0) {
            AccessibilityNodeInfo info = byTextList.get(0);
            if (!info.isChecked()) {
                info.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
                step++;
            } else {
                byTextList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                step++;
            }
        } else {
            if (byIdList != null && byIdList.size() > 0) {
                byIdList.get(0).performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
        }
    }

    private void check(String id) {
        List<AccessibilityNodeInfo> byIdList = findNodesById(id);
        if (byIdList != null && byIdList.size() > 0) {
            for (int i = 0; i < byIdList.size(); i++) {
                if (!byIdList.get(i).isChecked()) {
                    byIdList.get(i).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }
        step++;
    }


    /**
     * 返回上一层级
     */
    private void back() {
        performGlobalAction(GLOBAL_ACTION_BACK);
        step++;
    }
}

调用的方法,先判断是否打开了无障碍服务:
如果打开了就跳转到设置界面进行一步一步的设置

if (isAccessibilitySettingsOn(AutoDebugService.class.getName())) {//打开了无障碍权限
                Intent intent = new Intent(Settings.ACTION_SETTINGS);
                startActivity(intent);
            }

未打开的话就去打开:

 Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(intent, REQUEST_ACCESSIBLE_PERMISSION);

以上就完成了自动设置权限的功能。 如果不知道视图的id 可以使用sdk自带的DDMS工具查看视图。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-10 10:58:28  更:2021-09-10 11:00:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:41:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码