TimeShining / Android-Dev-Tools

Documentation and Attached Library of Dev Tools App
https://play.google.com/store/apps/details?id=cn.trinea.android.developertools
Apache License 2.0
231 stars 43 forks source link

关于开启无障碍 #23

Closed ZIDOUZI closed 2 days ago

ZIDOUZI commented 2 years ago

可以通过adb命令使应用获得secure setting权限直接开启无障碍

因为我连无障碍都懒得开了😅

希望能加入这个功能?

Trinea commented 2 years ago

一直有计划,只是比较忙😂

Trinea commented 6 months ago

两年多过去了😂,感谢反馈,确实对于模拟器很方便。因为不管是授权 WRITE_SECURE_SETTINGS,还是直接写 settings 都需要权限,正式机器上看起来没法操作。在模拟器上可以通过

adb root

adb shell settings put secure enabled_accessibility_services cn.trinea.android.developertools/b.c.a

直接开启开发助手的无障碍权限

ZIDOUZI commented 6 months ago

嗯🤔其实我是指调用写入安全设置权限直接开启无障碍. 我贴一点代码吧, 之前提了issue就忘了.

import android.Manifest.permission.WRITE_SECURE_SETTINGS
// other import

if (!accessibility) {
    if (secureSettingsEnabled) ctx.tryWriteSetting() else when (shizuku) { // 调用shizuku写入设置
        true -> { // shizuku可用
            queryShizuku()
            ctx.tryWriteSetting()
        }

        false -> { //shizuku不可用
            accessibilityDialog.show() // 引导用户选择开启方式(手动开启/adb开启/安装shizuku授权). adb方式: adb shell pm grant {packageName}  $WRITE_SECURE_SETTINGS
            return null
        }

        null -> { //shizuku未授权
            Shizuku.requestPermission(0x0)
            return null
        }
    }
}

fun queryShizuku(grant: Boolean = true) { // 通过shizuku授予或撤销WRITE_SECURE_SETTINGS权限
    val action = if (grant) "grant" else "revoke"
    Shizuku.getBinder()!!.let {
        IShizukuService.Stub.asInterface(it).newProcess(
            arrayOf("pm", action, pn, WRITE_SECURE_SETTINGS),
            null, null
        ).apply {
            waitFor()
            Timber.i("Shizuku process exit with value: ${exitValue()}")
        }
    }
}

fun Context.tryWriteSetting(): Boolean {
    if (secureSettings) {
        Settings.Secure.putString(
            contentResolver,
            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
            "${pn}/${AccessibilityService::class.java.canonicalName}"
        )
        return true
    }
    return false
}

// 检查shizuku可用性
val shizuku: Boolean?
    get() {
        if (Shizuku.isPreV11() || !Shizuku.pingBinder()) return false
        if (Shizuku.checkSelfPermission() != PackageManager.PERMISSION_GRANTED) {
            if (Shizuku.shouldShowRequestPermissionRationale()) return false
            return null
        }
        return true
    }

这里面用了两种方法授予WRITE_SECURE_SETTINGS权限, 一种是通过adb, 在对话框那里通过提示用户运行, 另一种是使用shizuku. 当然, shizuku需要引入库, 可能对维护增加复杂度.

如果采纳shizuku方案的话, 需要引入两个库, 我采用了测试版Android Studio的库管理功能, 您可以将下述信息改为合适方式引入.

[versions]
shizuku = "13.1.4"

[libraries]
shizuku = { group = "dev.rikka.shizuku", name = "api", version.ref = "shizuku" }
shizuku-provider = { group = "dev.rikka.shizuku", name = "provider", version.ref = "shizuku" }

可能还有些遗漏的信息, 如有遗漏我尽量补上.

Trinea commented 6 months ago

感谢👍🏻,我回头试试

ZIDOUZI commented 6 months ago

补充一点说明,授予WRITE_SECURE_SETTING后应用就可以调用该权限启动无障碍服务也就是Context.tryWriteSetting,所以只需要授权一次该权限就行了 上面的pnpackageName

Trinea commented 1 week ago

最新 8.0.0 版已支持 root 手机上一键开启无障碍服务,可从国内各大市场下载使用