Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable Google Assist API (Now on Tap)

Google have recently released Android Marshmallow with Now on Tap which can scan the app contents and provide an additional information to the user.

Unfortunately, for our app the info doesn't look very relevant and Google is ignoring the data we set inside onProvideContentAssist() and onProvideAssistData().

These specs look rather high level and also contain the words like "can suggest" and "additional information" so seems like Google officially allows itself to ignore the data app developers provide.

So we decided to disable Now on Tap, but seems it is not very trivial. According to the doc provided above, we should use FLAG_SECURE in this case. But then users couldn't capture screenshots and Google Now on Tap starts to blame our app with the following user facing message:

Results not available
This app has blocked Now on Tap

enter image description here

But it seems that Opera somehow gently blocks Now on Tap for their private tabs. It shows much more app friendly message for them:

Nothing on tap

enter image description here

How does Opera block Now on Tap?

Does anybody know how to block Google Assist API (Now on Tap) without getting a blame regarding our app from their side?

like image 923
goRGon Avatar asked Oct 09 '15 17:10

goRGon


1 Answers

The View class has a method setAssistBlocked:

Controls whether assist data collection from this view and its children is enabled (that is, whether {@link #onProvideStructure} and {@link #onProvideVirtualStructure} will be called). The default value is false, allowing normal assist collection. Setting this to false will disable assist collection.

@param enabled Set to true to disable assist data collection, or false (the default) to allow it.

Unfortunately this method is annotated with @hide, so we can't see it or directly use it.

But we can use it with a small reflection call:

private void setAssistBlocked(View view, boolean blocked) {
        try {
            Method setAssistBlockedMethod = View.class.getMethod("setAssistBlocked", boolean.class);
            setAssistBlockedMethod.invoke(view, blocked);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

To block all contents in the activity you can use:

final View rootContent = findViewById(android.R.id.content);
setAssistBlocked(rootContent, true);
like image 161
Mattia Maestrini Avatar answered Sep 29 '22 16:09

Mattia Maestrini