Android:你如何检查是否启用了特定的AccessibilityService
我写了一个android应用程序,需要使用AccessibilityService。 我知道如何查看手机上的“辅助function”是否已启用或禁用,但我无法确定是否在辅助function菜单中专门启用了我的应用程序。
我想提示用户,如果AccessibilityService没有运行,但找不到这样做的好方法。 是否有任何我可能会错过的API方法,让我知道设备上启用了哪些辅助function服务?
我最后自己做了这个:
public boolean isAccessibilityEnabled(){ int accessibilityEnabled = 0; final String LIGHTFLOW_ACCESSIBILITY_SERVICE = "com.example.test/com.example.text.ccessibilityService"; boolean accessibilityFound = false; try { accessibilityEnabled = Settings.Secure.getInt(this.getContentResolver(),android.provider.Settings.Secure.ACCESSIBILITY_ENABLED); Log.d(LOGTAG, "ACCESSIBILITY: " + accessibilityEnabled); } catch (SettingNotFoundException e) { Log.d(LOGTAG, "Error finding setting, default accessibility to not found: " + e.getMessage()); } TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':'); if (accessibilityEnabled==1){ Log.d(LOGTAG, "***ACCESSIBILIY IS ENABLED***: "); String settingValue = Settings.Secure.getString(getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); Log.d(LOGTAG, "Setting: " + settingValue); if (settingValue != null) { TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; splitter.setString(settingValue); while (splitter.hasNext()) { String accessabilityService = splitter.next(); Log.d(LOGTAG, "Setting: " + accessabilityService); if (accessabilityService.equalsIgnoreCase(ACCESSIBILITY_SERVICE_NAME)){ Log.d(LOGTAG, "We've found the correct setting - accessibility is switched on!"); return true; } } } Log.d(LOGTAG, "***END***"); } else{ Log.d(LOGTAG, "***ACCESSIBILIY IS DISABLED***"); } return accessibilityFound; }
从API级别14开始,还可以通过AccessibilityManager获取正在运行的辅助function服务:
public static boolean isAccessibilityEnabled(Context context, String id) { AccessibilityManager am = (AccessibilityManager) context .getSystemService(Context.ACCESSIBILITY_SERVICE); List<AccessibilityServiceInfo> runningServices = am .getEnabledAccessibilityServiceList(AccessibilityEvent.TYPES_ALL_MASK); for (AccessibilityServiceInfo service : runningServices) { if (id.equals(service.getId())) { return true; } } return false; }
要找出您的和所有安装的辅助function服务的标识,您可以运行以下代码片段:
public static void logInstalledAccessiblityServices(Context context) { AccessibilityManager am = (AccessibilityManager) context .getSystemService(Context.ACCESSIBILITY_SERVICE); List<AccessibilityServiceInfo> runningServices = am .getInstalledAccessibilityServiceList(); for (AccessibilityServiceInfo service : runningServices) { Log.i(TAG, service.getId()); } }
在我的例子中,ID看起来像org.your.package / .YourAccessibilityService。
到目前为止,该方法工作可靠。
检查服务是否启用
/** * Based on {@link com.android.settingslib.accessibility.AccessibilityUtils#getEnabledServicesFromSettings(Context,int)} * @see <a href="https://github.com/android/platform_frameworks_base/blob/d48e0d44f6676de6fd54fd8a017332edd6a9f096/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java#L55">AccessibilityUtils</a> */ public static boolean isAccessibilityServiceEnabled(Context context, Class<?> accessibilityService) { ComponentName expectedComponentName = new ComponentName(context, accessibilityService); String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); if (enabledServicesSetting == null) return false; TextUtils.SimpleStringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(':'); colonSplitter.setString(enabledServicesSetting); while (colonSplitter.hasNext()) { String componentNameString = colonSplitter.next(); ComponentName enabledService = ComponentName.unflattenFromString(componentNameString); if (enabledService != null && enabledService.equals(expectedComponentName)) return true; } return false; }
用法:
boolean enabled = isAccessibilityServiceEnabled(context, MyAccessibilityService.class);
检测何时启用或禁用服务
进行callback:
ContentObserver observer = new ContentObserver() { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); boolean accessibilityServiceEnabled = isAccessibilityServiceEnabled(context, MyAccessibilityService.class); //Do something here } };
订阅:
Uri uri = Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); context.getContentResolver().registerContentObserver(uri, false, observer);
完成后取消订阅:
context.getContentResolver().unregisterContentObserver(observer);
请注意,这不适用于getEnabledAccessibilityServiceList()
方法,因为它的值与Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
值不同步。 这就是为什么我认为使用Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
是一个更好的“一刀切”的方法。
你能跟踪服务是否正在运行吗? 如果无障碍服务启用不应该也运行?
public class MyAccessibilityService extends AccessibilityService{ public static boolean isEnabled = false; @Override public void onServiceConnected() { isEnabled = true; } @Override public void onDestroy(){ isEnabled = false; }
当您的活动服务刚刚开始时获取ID。 在您的Activity服务OnSeriviceCeonnected后,所有的初始化调用。 用这个…
AccessibilityServiceInfo serviceInfo = this.getServiceInfo(); String accessibilityId = serviceInfo.getId();
需要Jelly Bean API
然后,您可以使用Martin的代码(isAccessibilityEnabled)来检查正在运行的服务。
这需要更多的时间
AccessibilityManager am = (AccessibilityManager) context .getSystemService(Context.ACCESSIBILITY_SERVICE);
AccessibilityManager accessibilityManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE); List<AccessibilityServiceInfo> runningservice = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK); accessibilityManager.addAccessibilityStateChangeListener(new AccessibilityManager.AccessibilityStateChangeListener() { @Override public void onAccessibilityStateChanged(boolean b) { Toast.makeText(MainActivity.this, "permission "+b, Toast.LENGTH_SHORT).show(); } });
Listner会在状态改变的时候被调用,你可以跟踪布尔值来检查权限,这是迄今为止最简单和最轻的解决scheme来检查权限