Я разрабатываю приложение специальных возможностей в Android Studio, Java.
Я реализовал AccessibilityService для включения / отключения Talkback, и он отлично работает:
public class TalkBackToggler {
//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);
}
}
public void disableTalkBack()
{
try {
ContentResolver resolver = context.getContentResolver();
Settings.Secure.putString(resolver,
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, VALUE_DISABLED);
Settings.Secure.putString(resolver,
Settings.Secure.TOUCH_EXPLORATION_ENABLED, VALUE_DISABLED);
Settings.Secure.putString(resolver,
Settings.Secure.ACCESSIBILITY_ENABLED, VALUE_DISABLED);
}
catch(Exception e) {
Log.e("Device", "Failed to enable accessibility: " + e);
}
}
interface Callback {
void onSecurityExceptionThrown();
}
}
I есть еще одна служба AccessibiltyService, которая обнаруживает прикосновение к EditText, которая также отлично работает:
public class MyAccessibiltyService extends AccessibilityService {
private void getEventType(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) return;
if (source.getClassName().equals(EditText.class.getName())) {
AccessibilityManager accessibilityManager = (AccessibilityManager) getBaseContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
if (accessibilityManager.isTouchExplorationEnabled()) {
TalkBackToggleService TalkBackToggleService = new TalkBackToggleService(getBaseContext());
}
}
}
@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);
}
}
в AndroidManifet. 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>
Я даю разрешение запустив на терминале команду строки:
adb shell pm grant com.myapplication android.permission.WRITE_SECURE_SETTINGS
ПРОБЛЕМА: я хочу определить, когда происходит касание поля EditText, когда Talkback включен, но когда я включаю Talkback, вторая служба AccessibilityService, обнаруживающая поля EditText, отключена !
Что делать? Спасибо.