web-dev-qa-db-ja.com

Android:特定のAccessibilityServiceが有効になっているかどうかを確認する方法

Android AccessibilityService の使用を必要とするアプリを作成しました。アクセシビリティが有効か無効かを確認する方法を知っています電話ですが、ユーザー補助機能メニューでアプリが特に有効になっているかどうかを判断する方法を見つけることができません。

AccessibilityServiceが実行されていない場合にユーザーにプロンプ​​トを表示したいのですが、これを行うための適切な方法が見つかりません。デバイスで有効になっているアクセシビリティサービスを通知するAPIメソッドが不足している可能性がありますか?

39
Andrew

私はこれを最後に自分で解決しました:

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;
}
65
Andrew

APIレベル14 なので、 AccessibilityManager を使用して有効なアクセシビリティサービスを取得することもできます。

public static boolean isAccessibilityServiceEnabled(Context context, Class<? extends AccessibilityService> service) {
    AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
    List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);

    for (AccessibilityServiceInfo enabledService : enabledServices) {
        ServiceInfo enabledServiceInfo = enabledService.getResolveInfo().serviceInfo;
        if (enabledServiceInfo.packageName.equals(context.getPackageName()) && enabledServiceInfo.name.equals(service.getName()))
            return true;
    }

    return false;
}

使用法:

boolean enabled = isAccessibilityServiceEnabled(context, MyAccessibilityService.class);
51
Martin

ifサービスが有効かどうかを確認しています

_/**
 * 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);
_

サービスの有効化または無効化の検出

コールバックを行います。

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

これは the getEnabledAccessibilityServiceList()アプローチでは機能しないことに注意してください。 _Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES_ 値と同期します。そのため、 _Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES_ を使用する方が、1つのサイズですべてに対応できるアプローチであると思います。

20
Sam

サービスがこのように実行されているかどうかを追跡できますか?アクセシビリティサービスが有効になっている場合、それも実行されるべきではないのですか?

public class MyAccessibilityService extends AccessibilityService{
public static boolean isEnabled = false; 

 @Override
    public void onServiceConnected() {
      isEnabled = true; 
    }
 @Override 
    public void onDestroy(){ 
      isEnabled = false; 
    }
5
user3157940

アクティビティサービスが開始されたときにIDを取得します。すべての初期化呼び出しの後、アクティビティサービスOnSeriviceCeonnectedで。これを使って...

AccessibilityServiceInfo serviceInfo = this.getServiceInfo();
    String accessibilityId = serviceInfo.getId();

Jelly Bean APIが必要

次に、Martinのコード(isAccessibilityEnabled)を使用して、実行中のサービスを確認できます。

2
DarthJaiz

手遅れかもしれませんが、アクセシビリティサービスのステータスを確認する方法は次のとおりです。

$ adb Shell dumpsys accessibility

結果:

ACCESSIBILITY MANAGER (dumpsys accessibility)
User state[attributes:{id=0, currentUser=true, accessibilityEnabled=false, touchExplorationEnabled=false, displayMagnificationEnabled=false}
           services:{}]
0
Banana droid