Android 自动填充:dispatchProvideAutofillStructure() 未布局

Android autofill: dispatchProvideAutofillStructure() not laid out

我已将我的应用配置为支持 Android Oreo 和 compileSdkVersion 26。我还为 phone 数字输入字段设置了 android:autofillHints="phone"。当我点击该字段时,我可以看到 "Autofill" 弹出。但是,当我点击 "Autofill" 时,会出现 "Contents can't be autofilled" toast,我在 [=43= 中看到以下痕迹]:

RemoteFillService  Not handling { when=-3ms what=3 target=com.android.internal.os.HandlerCaller$MyHandler } as service for ComponentInfo{com.google.android.gms/com.google.android.gms.autofill.service.AutofillService} is already destroyed
View               dispatchProvideAutofillStructure(): not laid out, ignoring

我应该如何解决这个问题?我已确认我在 设置 > 系统 > 语言和输入法 > 高级 > 输入辅助 > 自动填充服务.

中配置了 phone 号码

更新示例 XML:在 API 26 模拟器设置中,我可以 select "Autofill with Google"。使用 Android Studio 的设计选项卡,我添加了一个 "Phone" 类型 EditText,然后在 [=] 中手动插入 android:autofillHints="phone" 48=] 元素:

<EditText
    android:id="@+id/editText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="phone"
    android:autofillHints="phone" />

Logcat 上面描述的特性可以使用这个 XML.

观察到

您 phone 上有实现自动填充服务的应用程序吗?我尝试使用 "Autofill with Google" 服务,并且可以毫无问题地自动填充我的 phone 号码(使用模拟器 运行 SDK 26)。您将需要一个服务部件才能使自动填充功能正常工作。参见 this example

这很可能就是问题所在 - 因为

as service for ComponentInfo{com.google.android.gms/com.google.android.gms.autofill.service.AutofillService} is already destroyed

Ensuring data is available
In some special cases, you need to take additional steps to make sure that the data is available to the Autofill Framework to save. For example, an activity can present a layout with standard text views, but then destroy the layout and replace it with one without child views, such as GLSurfaceView.

In this case, the data in the original layout is not available to the framework. To make the data available to the framework, you should call commit() on the AutofillManager object before replacing the original layout.

您需要在 java 代码中修复其中的一些问题。

添加IMPORTANT_FOR_AUTOFILL_AUTO and check that autofill isenabled().

您可能需要管理 java force the Autofill request:

中的一些设置

Sometimes, you may need to force an autofill request to occur in response to a user action. .../...

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

我是领导 Autofill Framework 项目的 Android 框架工程师,所以我会回答一些问题:

  • "Contents can't be autofilled" 消息通常表示自动填充服务不知道如何自动填充屏幕。当您向您的应用程序添加自动填充支持时,使用您可以首先控制的自动填充服务通常比使用密码管理器等 "real" 服务更容易。正如之前的回复中提到的,我们提供了一个sample service可以用于此目的。
  • 当您长按文本字段并 select AUTOFILL 时,您实际上是 "forcing" 另一个回复中提到的自动填充请求(即,在幕后,文本字段正在调用 AutofillManager.requestAutofill())。如果自动填充服务知道如何自动填充您的屏幕,您就不需要这样做,因为一旦您聚焦输入字段,自动填充建议就会立即显示。
  • 在您的情况下,您不需要设置 importantForAutofill 或调用 AutofillManager.cancel()

因此,我的建议是先尝试使用示例自动填充服务实现来测试您的应用。最有可能的是,您第一次访问您的应用程序时,不会显示自动填充弹出窗口,因为该服务没有数据。但是一旦您的应用程序触发保存 UI(例如,在您手动输入 phone 数字并且 activity 完成后)并且您点击保存,下次您应该可以使用该数据启动 activity。

希望对您有所帮助,

-- 费利佩

获取最新的 OS 图片。在为我的 Google Pixel XL 设备下载并安装 2017 年 9 月 21 日可用的更新后,autofill 运行良好。因此,XML 中有 android:autofillHints="phone" 就足够了,无需其他更改即可启用自动填充功能。

"Contents can't be autofilled" - 这是我造成的,因为我不同意自动填充服务。因此,进入 Oreo 及更高版本的 android 设置并搜索 "autofill" 。找到您的服务(我的是默认的谷歌),应该会提示您同意其服务。将其关闭,如果它不出现则关闭一个。之后我能够使用自动填充。