9

Недавно Google выпустил Android Marshmallow с помощью «Сейчас на связи», который может сканировать содержимое приложения и предоставлять дополнительную информацию пользователю.Как отключить Google Assist API (теперь на связи)

К сожалению, для нашего приложения информация не выглядит очень актуальной, и Google игнорирует данные, которые мы установили внутри onProvideContentAssist() и onProvideAssistData().

These specs выглядит довольно высокий уровень, а также содержат такие слова, как «может предложить» и «дополнительной информации», так кажется, что Google официально позволяет себе игнорировать приложение данных разработчиков предоставляют.

Итак, мы решили отключить Now on Tap, но, похоже, это не очень тривиально. В соответствии с документом, представленным выше, в этом случае мы должны использовать FLAG_SECURE. Но пользователи не могли захватить скриншоты и Google Now Разливного начинает обвинять наше приложение со следующим пользовательским сообщением лица:

Результатов не доступны
Это приложение заблокировало Теперь на Tap

enter image description here

Но кажется, что Opera так или иначе аккуратно блокирует Now on Tap для своих частных вкладок. Он показывает гораздо больше приложений дружественное послание для них:

Ничего на кране

enter image description here

Как Opera блок Сейчас на Tap?

Кто-нибудь знает, как заблокировать Google Assist API (теперь на связи), не получая вину за наше приложение со своей стороны?

+0

«так кажется, что Google официально позволяет себе игнорировать приложение данных разработчики предоставляют.» Скорее всего, вы просто делаете эту часть совершенно неправильно. – BooleanCheese

+0

@Saeed У Google есть пример кода внутри документов, о которых я упоминал: http://developer.android.com/training/articles/assistant.html#source_app, данные которых полностью игнорируются onTap (aka Google Assist) внутри нашего приложения. – goRGon

ответ

7

The View класс имеет метод setAssistBlocked:

Управляет помощь по сбору данных с этой точки зрения и его детей включена (то есть, является ли {@link #onProvideStructure} и { @link #onProvideVirtualStructure } будет вызываться). Значение по умолчанию является ложным, что позволяет использовать обычную помощь. Установка этого значения на false отключит вспомогательную коллекцию.

@param enabled Значение true для отключено помощь в сборе данных, или false (по умолчанию), чтобы разрешить это.

К сожалению, этот метод аннотируется @hide, поэтому мы не можем его увидеть или использовать непосредственно.

Но мы можем использовать его с небольшим отражением вызова:

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(); 
     } 
    } 

Чтобы блокировать все содержимое в деятельности вы можете использовать:

final View rootContent = findViewById(android.R.id.content); 
setAssistBlocked(rootContent, true); 
+1

Привет! Мы глубоко недовольны рекомендациями использования частных API платформы. Они скрыты по какой-то причине. Скрытые API-интерфейсы не поддерживаются, а это значит, что вы не знаете, что с ними может произойти - возможно, в будущем они исчезнут (к счастью, вы просто затихнете), возможно, изменения в версии, так что вызов, который вы сейчас делаете развязывает зомби-апокалипсис в мире. Вы не знаете будущего, поэтому, пожалуйста, не делайте этого. – hackbod

+1

Кроме того, в этом случае для этого не существует * причины *, поскольку вы можете использовать это: https://developer.android.com/reference/android/view/View.html # dispatchProvideStructure (android.view.ViewStructure) – hackbod

+6

Итак, если нет причин для этого, зачем хром делать ** точно ** [то же самое] (https: // codereview .chromium.org/1262453004)? Пожалуйста, объясните это, потому что мне действительно интересно ... –

-2

Opera делает это, вероятно, потому, что они не обновляются их браузеру сообщать вспомогательные данные (для этого требуется специальное сотрудничество с приложениями, которые не используют обычную иерархию представлений, например, браузеры).

Однако, если ваша проблема заключается в том, что теперь по выходу не возвращаются соответствующие данные, решение равно , а не, чтобы заблокировать данные, которые он получает - все, что делает, это то, что данные, которые он возвращает для вашего приложения, никогда не улучшатся, потому что он никогда не видит данных, на которые он мог бы дать лучшие предложения. Блокирование этого, конечно же, не заставит его использовать другие данные, это просто сделает его глупым для вашего приложения.

Вы не должны пытаться сделать «Сейчас на связи» глупым для вашего приложения.

+1

Как я уже упоминал в своем вопросе, Opera делает это только для своих закрытых вкладок, но Google Assist по-прежнему работает для своих публичных вкладок. Таким образом, похоже, что они не обновили свой браузер, чтобы сообщить данные об оказании помощи. Я понимаю вашу точку зрения, и я думаю, что должно быть много приложений, подобных Google Assist, и данных, которые имеют отношение к делу, но мой вопрос состоял в том, чтобы отключить его. – goRGon

5

Другим возможным решением, что я в конце концов, нужно попробовать, намекают на hackbod's one comment:

Кроме того, в этом случае нет никаких причин, чтобы сделать это, потому что вы можете использовать это: https://developer.android.com/reference/android/view/View.html#dispatchProvideStructure(android.view.ViewStructure)

код комментарий для dispatchProvideStructure() состояний: "создание Отправка ViewStructureвниз по иерархии." (акцент мой).

Таким образом, создать NoAssistFrameLayout подкласс FrameLayout, переопределить dispatchProvideStructure() не быть не-оп, и использовать его в качестве корневого контейнера для макета деятельности. Это блокирует автоматическую совокупность ViewStructure для чего-либо в теле действия.

Он не будет блокировать все, что может быть выведено из материала вне вашей основной области содержимого, например панели действий, поскольку это будет за пределами иерархии представлений NoAssistFrameLayout. Возможно, там не так много, что будет иметь последствия для конфиденциальности, но это ограничение этой техники.


ОК, я попробовал, и это похоже на работу:

/*** 
Copyright (c) 2015 CommonsWare, LLC 
Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance with the License. You may obtain a copy 
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required 
by applicable law or agreed to in writing, software distributed under the 
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
OF ANY KIND, either express or implied. See the License for the specific 
language governing permissions and limitations under the License. 

From _The Busy Coder's Guide to Android Development_ 
https://commonsware.com/Android 
*/ 

package com.commonsware.android.assist.no; 

import android.annotation.TargetApi; 
import android.content.Context; 
import android.os.Build; 
import android.util.AttributeSet; 
import android.view.ViewStructure; 
import android.widget.FrameLayout; 

public class NoAssistFrameLayout extends FrameLayout { 
    public NoAssistFrameLayout(Context context) { 
    super(context); 
    } 

    public NoAssistFrameLayout(Context context, 
          AttributeSet attrs) { 
    super(context, attrs); 
    } 

    public NoAssistFrameLayout(Context context, 
          AttributeSet attrs, 
          int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public NoAssistFrameLayout(Context context, 
          AttributeSet attrs, 
          int defStyleAttr, 
          int defStyleRes) { 
    super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @Override 
    public void dispatchProvideStructure(ViewStructure structure) { 
    // no, thanks 
    } 
} 
+0

Мне любопытно, как выглядит всплывающее окно «On Tap» после использования в качестве корневого представления. Можете ли вы описать, что появилось или опубликовать скриншот случайно? – Jeff

+0

@JeffAlexander: Я отключил Google Now, как само собой разумеющееся. Я тестировал «NoAssistFrameLayout» с помощью [моей собственной реализации помощника] (https://github.com/commonsguy/cw-omnibus/tree/master/Assist/AssistLogger), которая просто регистрирует то, что вызывается этой деятельностью. Я протестировал «NoAssistFrameLayout» для одной вкладки «ViewPager» в [этом примере проекта] (https://github.com/commonsguy/cw-omnibus/tree/master/Assist/NoAssist), и все работало, как ожидалось. – CommonsWare

+1

На случай, если кто-то захочет узнать, как он будет выглядеть, я протестировал Activity с корневым представлением, которое было FrameLayout внутри того, что был TextView с текстом, имеющим название фильма. On Tap показал информацию об этом фильме. Затем я переключился на NoAssistFrameLayout, и я получил «Nothing on tap». – Jeff

Смежные вопросы