Programmatically enabling/disabling accessibility settings on Android device
Asked Answered
A

3

14

How can I programmatically enable/disable an android screen reader service such as TalkBack?

I am developing a kiosk type application that will be installed on an Android device that will be loaned to visitors while they visit a particular museum. (We are still in the process of determining what device we will use.) The plan is to only allow users to use our app and not have access to the android settings application. However, we'd like to allow users to configure some accessibility settings. When they are finished with the device, we need to restore all the settings to our defaults.

The discussion at the link below has many suggesting launching Android's Settings app. But we don't want users accessing many other settings.

How to Programmatically Enable/Disable Accessibility Service in Android

Andersonandert answered 13/7, 2016 at 19:30 Comment(5)
Does your app going to be signed a system application?Holofernes
It could be. Is that required to get this to work?Andersonandert
Check this other post out on StackOverflow, click hereSchizophrenia
Hi John, have u got any solution i am also looking same thing. if u got solution then pls let post your ansRumania
Anuj, My plan is to have a system signed app with the WRITE_SECURE_SETTINGS permission declared so that I can use Settings.Secure.putString to update the necessary settings.Andersonandert
D
11

Only system apps can enable/disable accessibility service programatically. System apps can directly write in settings secure db to start accessibility service.

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

Following permission is required to write in settings secure db:

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

For non system apps, only way to start accessibility service is direct them to accessibility settings screen via intent and let user manually start the service :

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
Duppy answered 26/7, 2016 at 14:52 Comment(4)
I am able to have my system signed app enable/disable talkback by setting Settings.Secure.ACCESSIBILITY_ENABLED to 1 or 0. However, when I disable talkback by setting it to 0, an error is displayed saying "Unfortunately, Pico TTS has stopped". Anyone have suggestions on how to prevent that error message from being displayed?Andersonandert
first remove talkback entry from Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES and then update ACCESSIBILITY_ENABLED to 0Duppy
I still get the same error. However, I noticed the same thing happens with the standard Android Settings app. So I think this error is related to the version of TalkBack that I installed. I'm hoping that once I get the actual devices I will be using that this won't be an issue.Andersonandert
I think problem is talkback accessibility service is not shutting down tts properlyDuppy
T
3

I think there might be a way to do that if you make your app an AccessibilityService (but you would have to enable it manually after install).

Then in your AccessibilityService class, inside onAccessibilityEventmethod you can explore views (recursively) and perform clicks - in the example below it will click on TalkBack item in settings - after that it should toggle the toggle button on next screen (the trick is that you can click on parent not the switch view itself) - I haven't tried this code :)

@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();
    }

so now if you open accessibility settings with Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); it will perform clicks for you - you would have to somehow cover it with full screen toast or service with view

I'm currently working on automatic airplane mode toggle and it works - so should do the job in your case

take a look on my 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"
/>
Trimmer answered 27/7, 2016 at 13:6 Comment(0)
M
0

From lollipop you can not change all settings that breaks the security policy. Some of them you may access but you have to take permission for that. So please don't waste time on that.

Martyrize answered 27/7, 2016 at 4:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.