【问题标题】:Can I have Talkback and my custom Accessibility Service enabled simultaneously?我可以同时启用 Talkback 和我的自定义辅助功能服务吗?
【发布时间】:2020-07-14 16:04:22
【问题描述】:

我正在使用 Java 的 Android Studio 开发辅助功能应用。

我以编程方式启用 Talkback 作为无障碍服务:

public class TalkBackToggler {

//In the terminal run the command line:

//    adb shell pm grant com.MyApp android.permission.WRITE_SECURE_SETTINGS

private static final String VALUE_DISABLED = "0";
private static final String VALUE_ENABLED = "1";

private final ContentResolver contentResolver;
private final Callback callback;
private Context context;

TalkBackToggler(ContentResolver contentResolver, Callback callback, Context context) {
    this.contentResolver = contentResolver;
    this.callback = callback;
    this.context = context;
}


public void enableTalkBack()
{
    try {
        AccessibilityManager am = (AccessibilityManager)(context.getSystemService(Context.ACCESSIBILITY_SERVICE));
        List<AccessibilityServiceInfo> services = am.getInstalledAccessibilityServiceList();

        if (services.isEmpty()) {
            return;
        }

        AccessibilityServiceInfo service = services.get(0);

        boolean enableTouchExploration = (service.flags
            & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;

        ServiceInfo serviceInfo;
        ComponentName componentName;
        String enabledServiceString = "";

        if (!enableTouchExploration) {
            final int serviceCount = services.size();
            for (int i = 1; i < serviceCount; i++) {
                AccessibilityServiceInfo candidate = services.get(i);
                serviceInfo = candidate.getResolveInfo().serviceInfo;
                componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
                enabledServiceString = componentName.flattenToString();

                if (enabledServiceString.contains("talkback")) {
                    if ((candidate.flags & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) == 0) {
                        candidate.flags = candidate.flags | AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
                }
                    enableTouchExploration = true;

                    break;
                }
            }
        }

        ContentResolver resolver = context.getContentResolver();

        Settings.Secure.putString(resolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServiceString);

        if (enableTouchExploration) {
            Settings.Secure.putString(resolver, Settings.Secure.TOUCH_EXPLORATION_ENABLED, VALUE_ENABLED);
        }

            Settings.Secure.putString(resolver, Settings.Secure.ACCESSIBILITY_ENABLED, VALUE_ENABLED);
        }
        catch(Exception e) {
             Log.e("Device", "Failed to enable accessibility: " + e);
        }
    }
}

我有一个自定义的 AccessibiltyService,我也以编程方式启用它:

public class MyAccessibiltyService extends AccessibilityService {

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.v(TAG, "onServiceConnected");
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        info.flags = AccessibilityServiceInfo.DEFAULT;
        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
        setServiceInfo(info);
    }
 

在 AndroidManifest.xml 我已经注册了这两个服务:

<service
    android:name=".activities.MyAccessibiltyService"
    android:enabled="true"
    android:exported="true"
    android:label="Keynoa"
    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/my_accessibility_service_config" />
</service>

<service
    android:name=".activities.TalkBackToggleService"
    android:enabled="true"
    android:exported="true"
    android:label="Keynoa"
    android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
    <action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>

 <meta-data
     android:name="android.service.quicksettings.ACTIVE_TILE"
     android:value="true" />
</service>

问题:我无法以编程方式同时启用对讲服务和辅助功能服务;当我启用一项服务时,另一项服务被禁用。

但是!当我从设备设置中手动启用 Talkback 时,我的 Accessibility Service 会与 Talkback 同时保持启用状态!

我有办法以编程方式启用这两种服务并让它们同时保持启用状态吗?

谢谢。

【问题讨论】:

    标签: java android android-studio accessibilityservice talkback


    【解决方案1】:

    您正在覆盖启用服务的设置,因此启用的服务列表仅包含 TalkBack。如果您查看设置代码,则在切换服务时会出现读取-修改-写入。

    您已经远离公共 API 的道路,从仅系统的权限授予开始,因此您应该期待脆弱性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-26
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多