在Android设备上编程实现启用/禁用辅助功能设置

14

我如何以编程的方式启用/禁用 Android 屏幕阅读器服务,例如 TalkBack?

我正在开发一种类似信息亭的应用程序,该应用程序将安装在 Android 设备上,并借给游客们参观特定的博物馆(目前仍在确定使用哪种设备)。计划是只允许用户使用我们的应用程序,而不允许访问 Android 设置应用程序。但是,我们希望允许用户配置一些辅助功能设置。当他们完成使用设备后,我们需要将所有设置恢复为默认值。

下面链接中的讨论有许多人建议启动 Android 的设置应用程序。但我们不希望用户访问其他许多设置。

如何以编程方式启用/禁用 Android 辅助功能服务


你的应用程序将被签名为系统应用吗? - Nir Duan
可能是。这是必须的才能让它工作吗? - John Weidner
请查看StackOverflow上的另一篇帖子,点击这里 - Ethan
嗨John,你有任何解决方案吗?我也在寻找同样的东西。如果你有解决方案,请发布你的答案。 - Anuj Zunjarrao
Anuj,我的计划是拥有一个已签名的系统应用程序,并声明WRITE_SECURE_SETTINGS权限,以便我可以使用Settings.Secure.putString来更新必要的设置。 - John Weidner
3个回答

11

只有系统应用程序才能以编程方式启用/禁用辅助功能服务。 系统应用程序可以直接写入安全设置数据库以启动辅助功能服务。

Settings.Secure.putString(getContentResolver(),Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "com.packagename/com.packagename.componentname");

需要以下权限才能在设置安全数据库中写入:

<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

对于非系统应用程序,启动辅助功能服务的唯一方法是通过意图将它们直接指向辅助功能设置屏幕,并让用户手动启动服务:

对于非系统应用,开启辅助功能服务的唯一方式是通过 Intent 直接引导用户进入辅助功能设置屏幕,并让用户手动启动服务:

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);

我可以通过将Settings.Secure.ACCESSIBILITY_ENABLED设置为1或0来启用/禁用TalkBack,但是当我将其设置为0以禁用TalkBack时,会显示一个错误:“很抱歉,Pico TTS已停止”。有没有人有关于如何防止该错误消息被显示的建议? - John Weidner
先从Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES中删除TalkBack条目,然后将ACCESSIBILITY_ENABLED更新为0。 - abhishesh
我仍然遇到相同的错误。不过,我注意到标准的Android设置应用程序也会出现同样的情况。因此,我认为这个错误与我安装的TalkBack版本有关。我希望一旦我获得实际使用的设备,这个问题就不会再出现了。 - John Weidner
我认为问题在于Talkback辅助服务没有正确关闭TTS。 - abhishesh

3
我认为如果您将应用程序设置为AccessibilityService,则可以实现这一点(但您需要在安装后手动启用)。
然后,在AccessibilityService类中的onAccessibilityEvent方法中,您可以递归地探索视图并执行点击操作。在下面的示例中,它将点击设置中的TalkBack项目 - 然后它应该切换到下一个屏幕上的切换按钮(诀窍是您可以点击父项而不是开关视图本身)- 我还没有尝试过这段代码 :)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    AccessibilityNodeInfo source = event.getSource();        
    if(event.getEventType()==AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) 
        explore(source);

}

private void explore(AccessibilityNodeInfo view){
    int count = view.getChildCount();
    for(int i=0; i<count; i++){
        AccessibilityNodeInfo child = view.getChild(i);
        if(!MODE_TALK_BACK_SCREEN){
            if(child.getText()!=null && child.getText().toString().toLowerCase().contains("TalkBack")){
                child.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
                MODE_TALK_BACK_SCREEN=true;
                return;
            }
        }else{
            if("ToggleButton".equals(child.getClassName().toString())){ //there ony one toggle button on the screen
                child.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
                performGlobalAction(GLOBAL_ACTION_BACK);
                performGlobalAction(GLOBAL_ACTION_BACK);//need to go back two time - i don't know if that will work :)
                return;
            }
        }
        explore(child);
        child.recycle();
    }

现在,如果您使用Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);打开可访问性设置,则它会为您执行点击操作 - 您需要用全屏幕提示或带视图的服务进行一些覆盖处理。

我目前正在开发自动飞行模式切换功能,并且它可以正常工作 - 因此在您的情况下也应该能够胜任。

请查看我的serviceconfig.xml文件。

<accessibility-service     xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description"
android:packageNames="com.android.settings"
android:accessibilityEventTypes="typeWindowStateChanged"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>

0
从棒棒糖开始,您无法更改所有设置,因为这会违反安全策略。其中一些您可能可以访问,但必须获得许可。所以请不要浪费时间在这上面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接