Programmatically enabling/disabling accessibility settings on Android device

吃可爱长大的小学妹 提交于 2019-11-30 07:04:42

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);

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"
/>

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!