Saturday, 17 July 2021

isGestureDetectionAvailable returns false on Android 10

isGestureDetectionAvailable() always returns false. I looked this issue up here on SO, and all those who faced the same problem in the past few years haven't received an answer or got it solved. Here and Here And everywhere else. There will be a 50 points reward for the correct answer as a token of appreciation.

AndroidManifest.xml

<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />


  <service
        android:enabled="true"
        android:name="helpers.FingerprintSVC"
        android:label="@string/app_name"
        android:accessibilityFlags="flagDefault|flagRequestFingerprintGestures"
        android:canRequestFingerprintGestures="true"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibility_service_config" />
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
  </service>

FingerprintSVC

public class FingerprintSVC extends AccessibilityService {

private static final String TAG = "++++";

@Override
public int onStartCommand(Intent aIntent, int aFlags, int aStartId){
    super.onStartCommand(aIntent, aFlags, aStartId);

    Log.d(TAG, "onStartCommand");

    if(!isAccessibilityServiceEnabled(this, this.getClass())){
        Toast toast= Toast.makeText(this, "Enable A.SVC", Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP|Gravity.FILL_HORIZONTAL, 0, 0);
        toast.show();

        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

    return START_STICKY;
}

@Override
public void onCreate(){
    super.onCreate();
    Log.d(TAG, "onCreate");
}

@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
    Log.d(TAG, "onAccessibilityEvent");
}

@Override
public void onInterrupt() {
    Log.d(TAG, "onInterrupt");
}

@Override
protected boolean onGesture(int gestureId) {
    Log.d(TAG, "onGesture " + gestureId);
    return super.onGesture(gestureId);
}

@Override
protected boolean onKeyEvent(KeyEvent event) {
    Log.d(TAG, "onKeyEvent " + event.getKeyCode());
    return super.onKeyEvent(event);
}

@Override
public void onDestroy() {
    Toast.makeText(getApplicationContext(), "onDestroy" , Toast.LENGTH_SHORT).show();
    super.onDestroy();
}



@Override
protected void onServiceConnected() {
    super.onServiceConnected();
    Log.d(TAG, "onServiceConnected");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        FingerprintGestureController gestureController = getFingerprintGestureController();

        Toast.makeText(getApplicationContext(), "Is available: " + gestureController.isGestureDetectionAvailable(), Toast.LENGTH_LONG).show();
        Log.e(TAG, "Is available: " + gestureController.isGestureDetectionAvailable() );

        FingerprintGestureController.FingerprintGestureCallback callback = new
                FingerprintGestureController.FingerprintGestureCallback() {
                    @Override
                    public void onGestureDetectionAvailabilityChanged(boolean available) {
                        super.onGestureDetectionAvailabilityChanged(available);
                        Toast.makeText(getApplicationContext(), "Gesture available change to: " + available, Toast.LENGTH_SHORT).show();
                        Log.d(TAG, "onGestureDetectionAvailabilityChanged " + available);
                    }

                    @Override
                    public void onGestureDetected(int gesture) {
                        super.onGestureDetected(gesture);
                        Toast.makeText(getApplicationContext(), "Gesture: " + gesture, Toast.LENGTH_SHORT).show();
                        Log.d(TAG, "onGestureDetected " + gesture);
                    }
                };

        gestureController.registerFingerprintGestureCallback(callback, new Handler());
    }
}

@Override
public boolean onUnbind(Intent intent) {
    Log.d(TAG, "onUnbind " );
    return super.onUnbind(intent);
}


public 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;
}

}

build.gradle

android {
compileSdkVersion 30
buildToolsVersion '29.0.3'
defaultConfig {
    applicationId "com.xxxx.xxxx"
    minSdkVersion 26
    targetSdkVersion 30
}

I'm testing on Samsung M11 powered by Android 10. I don't have other devices to test on.



from isGestureDetectionAvailable returns false on Android 10

No comments:

Post a Comment