【问题标题】:Disabling Android O auto-fill service for an application禁用应用程序的 Android O 自动填充服务
【发布时间】:2018-01-25 15:33:25
【问题描述】:

Android O 具有支持Auto-filling 字段的功能。有什么方法可以为特定应用程序禁用它。那就是我想强制我的应用程序不使用自动填充服务。

有可能吗?

要阻止整个活动的自动填充,请在活动的 onCreate() 中使用:

getWindow()
  .getDecorView()
  .setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);

还有比这更好的方法吗?

【问题讨论】:

  • 自动填充会导致一个非常模糊的崩溃,当用户将焦点更改为 TextInputLayout 中先前填充的 textInputEditText 时,我们会发生这种情况:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.空对象引用上的 view.View.getBoundsOnScreen(android.graphics.Rect)'
  • 发布了一个错误issuetracker.google.com/issues/67675432,请加注星标
  • 创建一个活动类,供其他所有活动继承并添加此代码。
  • @Justin,这在 Android 8.1 上是固定的,你能用 8.1 测试它吗
  • 我相信,如果它尝试自动填充诸如 EditText 之类的数据超过 1MB 的内容,这也可能导致 TransactionTooLargeExceptions,这超出了 Bundle 的限制。请参阅AutoFillManager 的来源。解决方法是在视图的 xml 中包含 android:importantForAutofill="noExcludeDescendants"

标签: android textview autofill android-8.0-oreo android-autofill-manager


【解决方案1】:

目前没有直接的方法来禁用整个应用程序的自动填充,因为自动填充功能是特定于视图的。

您仍然可以尝试这种方式并在任何地方调用 BaseActivity。

public class BaseActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       disableAutofill();
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void disableAutofill() { 
        getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
    }
}

您也可以通过这种方式强制请求自动填充。

public void forceAutofill() {
    AutofillManager afm = context.getSystemService(AutofillManager.class);
    if (afm != null) {
        afm.requestAutofill();
    }
}

注意:目前自动填充功能仅在 API 26 Android Oreo 8.0

中可用

希望这会有所帮助!

【讨论】:

  • 非常好!我将把这个答案与 Android 8.1 的 API 检查结合起来;在 8.0 中禁用错误​​的自动填充,但在 8.1+ 中允许。否则我会花一个多小时将提示放入整个应用程序的 TextInputLayout 中。
  • if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) { getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS); }
  • 这个答案在模拟器(API 26)上不起作用:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.getBoundsOnScreen(android.graphics.Rect)' on a null object reference
  • 我无法在 Android 10 上获得 getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS) 的任何效果。
【解决方案2】:

我认为接受的答案不正确:

所以我有自己的类 extends android.support.v7.widget.AppCompatEditText 我所做的只是用以下值覆盖以下方法:

@Override
public int getAutofillType() {
    return AUTOFILL_TYPE_NONE;
}

没有其他解决方案有效,甚至 android:importantForAutofill="no"。

getAutofillType() 来自 View 类,因此它也应该适用于所有其他类,例如 TextInputEditText!

【讨论】:

  • 这是目前唯一可行的解​​决方案,它也适用于 TextInputEditText!
  • 添加代码示例以展示 repo github.com/BukT0p/AutofillBug
  • 如果您将任何第三方库与不扩展基类的可视化组件一起使用,这将不起作用
  • 我确认此解决方案有效,但在 EditText 上设置 android:importantForAutofill="no"android:importantForAutofill="noExcludeDescendants" 无效。在 Oreo 8.0(api 级别 26)和 Android Pie(api 级别 28)模拟器上测试
  • 尽管实施起来很烦人,但这应该是公认的答案
【解决方案3】:

我也遇到过。原来问题是由嵌套在 TextInputLayout 内的 EditText 上设置提示文本引起的。

我进行了一些挖掘,并在 26.0.0 Beta 2 发行说明中找到了这个块。 Andorid Support Release Notes June 2017

TextInputLayout 必须在 onProvideAutofillStructure() 上设置提示

这导致我尝试在 TextInputLayout 而不是嵌套的 EditText 上设置提示。

这为我解决了崩溃问题。 示例:

            <android.support.design.widget.TextInputLayout
                android:id="@+id/textInputLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Some Hint Text"
                android.support.design:hintAnimationEnabled="true"
                android.support.design:hintEnabled="true"
                android.support.design:layout_marginTop="16dp">

                <android.support.design.widget.TextInputEditText
                    android:id="@+id/editText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </android.support.design.widget.TextInputLayout>

【讨论】:

  • 它只解决了 TextInputEditText 错误,用你的解决方案更新了我的 repo(github.com/BukT0p/AutofillBug)。但是 AutoCompleteTextView 也有类似的错误。在 API 27 中,自动填充在同步模式下工作并导致 UI 冻结和滞后。所以也许最好对不应该填充的视图禁用自动填充
  • 即使我们使用此线程中的其他建议来禁用自动填充,用户仍然可以长按视图并从上下文菜单中选择自动填充。我观察到,在某些情况下,您会被告知无法自动填充视图,但我还没有找到该标志。我已经看到一些解决方案涉及自定义视图,该视图为自动填充选项返回 NONE,但这并非对所有人都可行实现。
  • 这个解决方案对我有用。用户仍然可以长按输入字段并选择自动填充,但它不会崩溃 - 它什么也不做。谢谢。
  • 这种方法有效,但它是最大的 PITA,因为我的应用程序有大量活动。请注意,我没有使用以android.support.design 开头的行,只需移动提示参数即可。
【解决方案4】:

似乎是一个需要修复的错误:https://issuetracker.google.com/issues/67675432
与此同时,目前的解决方法是禁用整个项目的自动填充功能。 您可以在 values-v26/styles.xml 文件中添加以下样式,或者如果您为 EditText 视图使用特定样式,则可以编辑 BaseEditTextStyle。

<style name="App_EditTextStyle" parent="@android:style/Widget.EditText">
<item name="android:importantForAutofill">noExcludeDescendants</item>
</style>

values-v26/themes.xml 文件中,您可以简单地将项目editTextStyleandroid:editTextStyle 添加到您在应用程序中使用的默认主题中,如下所示:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="android:editTextStyle">@style/App_EditTextStyle</item>
<item name="editTextStyle">@style/App_EditTextStyle</item>
</style>

通过这种方式,您可以将这些更改应用于所有您的 EditText,而无需更改您的布局文件或活动(稍后您可以在修复错误后轻松删除它)。

【讨论】:

    【解决方案5】:

    有可能吗?

    我不知道。当然,没有任何记录。

    还有比这更好的方法吗?

    我不知道。

    【讨论】:

    • 这个在Android 8.1上是固定的,你能用8.1测试一下吗
    • 有没有可能 android:importantForAutofill="no"
    • @appnweb31web:这是视图的属性,而不是清单中的&lt;application&gt;
    【解决方案6】:

    在您的 EditText 属性中添加 android:importantForAutofill="no" 这应该是临时修复,仅适用于 api 26+

    【讨论】:

    • 这与其他答案有何不同?
    【解决方案7】:

    创建自定义 EditText 样式并将android:importantForAutofill 设置为no

    <style name="EditTextStyleWithoutAutoFill" parent="Widget.AppCompat.EditText">
        <item name="android:importantForAutofill">no</item>
    </style>
    

    然后在您的活动主题中为 editTextStyle 设置此样式。

    <item name="android:editTextStyle">@style/EditTextStyleWithoutAutoFill</item>
    

    【讨论】:

    • importantForAutofill 记录在这里 developer.android.com/guide/topics/text/…
    • 接下来我会尝试这种方法,但将其与res/values-v26/styles.xml 合并,只会影响 Android 8.0,而不影响 8.1(我无法相信 Google 发布了这么大的错误!)
    【解决方案8】:

    在我的例子中,我们的应用针对 sdk 版本 21,但更新的设备 (26+) 仍然弹出自动完成功能。如果应用程序在人与人之间共享的设备上运行,那么问题就很大了。仅使用 android:importantForAutofill="no" 对我不起作用。

    我发现在我的案例中唯一可行的解​​决方案是:

    <EditText
        android:importantForAutofill="no"
        tools:targetApi="o"
        android:autofillHints="AUTOFILL_HINT_SMS_OTP" ...
    

    我添加android:autofillHints="AUTOFILL_HINT_SMS_OTP" 的原因是,如果您长按 EditText,它仍然会显示自动填充。基本上我告诉该字段的自动填充它正在等待一条永远不会发送的短信。我知道有点 hack ......

    注意:您可能需要将 xmlns:tools="http://schemas.android.com/tools" 添加到您的架构中,如果它还没有的话。

    【讨论】:

    • 这对我有用。它是否导致您在较低的 API 上出现问题?
    • 我不能和 Lollipop 下面的任何东西说话,还没有测试过。但是对于最新的 Lollipop,自发布以来没有任何问题。
    【解决方案9】:

    使用 API 28+ 时遇到同样的问题并禁用自动填充。对我来说,唯一的解决方案是禁用长按查看我的视图。

                    <com.google.android.material.textfield.TextInputEditText
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:longClickable="false"
                        android:text="@={model.emailAdress}"/>
    

    【讨论】:

      【解决方案10】:

      参考Google issue tracker,已修复。

      Android 8.1 已修复此问题

      如果任何问题仍然存在,请通过Google issue tracker 报告,他们将重新打开进行检查。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-17
      • 2020-09-22
      • 2023-03-16
      • 2019-05-17
      • 2021-04-30
      • 2013-03-22
      相关资源
      最近更新 更多