像往常一样,谷歌自己的示例存储库提供了一个很好的起点用于学习自动填充框架的 API,并且涵盖的内容比我在答案中所能容纳的内容要多得多。以下是关键概念的概述。从描述中文档,我们要创建一个自动填充service它将处理来自其他应用程序(客户端)的请求以存储和检索自动填充字段数据。
首先,我们需要创建一个履行此契约的服务提供者类。我们可以扩展基地AutofillService class:
import android.service.autofill.AutofillService;
...
public class MyAutofillService extends AutofillService {
...
@Override
public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
FillCallback callback) { ... }
@Override
public void onSaveRequest(SaveRequest request, SaveCallback callback) { ... }
}
该服务的onFillRequest() and onSaveRequest()方法对于我们的理解来说是最重要的。 Android系统调用onFillRequest()
确定我们的服务是否可以自动填充特定活动的字段,并为该方法提供FillRequest其中包含我们的服务将检查可填写字段的上下文和视图信息。当服务完成时,它会调用提供的callback
使用适当的自动填充数据。
这是一个戏剧性地为以下内容提供自动填充建议所需的基本步骤的简化概述FillRequest
:
@Override
public void onFillRequest(FillRequest request, CancellationSignal signal, FillCallback callback) {
List<FillContext> contexts = request.getFillContexts();
AssistStructure structure = contexts.get(contexts.size() - 1);
WindowNode windowNode = structure.getWindowNodeAt(0);
ViewNode viewNode = windowNode.getRootViewNode(); // pretend this is an EditText
String suggestionText = "This will appear in the autofill list for 'viewNode'.";
RemoteViews suggestion = new RemoteViews(getPackageName(), R.layout.autofill_suggestion);
suggestion.setTextViewText(R.id.autofill_suggestion, suggestionText);
Dataset suggestionDataset = new Dataset.Builder(suggestion)
.setValue(viewNode.getAutoFillId(), AutofillValue.forText(suggestionText))
.build();
FillResponse response = new FillResponse.Builder()
.addDataset(suggestionDataset)
.build();
callback.onSuccess(response);
}
正如我们所看到的,自动填充 API 需要大量代码才能为以下内容提供单个静态自动填充建议:View
我们已经提前知道了——这个例子假设viewNode
是一个文本输入字段,我们希望为其提供自动填充建议。事实上,这个例子太简单了,但我想清楚地展示最小的实现。对于每个WindowNode
,我们需要遍历根视图树ViewNode及其每个子项找到我们的服务希望为其提供自动填充数据的每个输入字段,然后创建一个RemoteViews and Dataset其中包含我们将添加到的每个字段的自动填充建议FillResponse using FillResponse.Builder.addDataset()。此示例不显示纯 XML 布局R.layout.autofill_suggestion
TextView
用于创建建议显示项RemoteViews
.
同样,Android 调用onSaveRequest()
当用户想要将数据保存在活动的字段中以供将来完成请求并注入SaveRequest我们的服务用来查找要记住的自动填充数据。
这些方法的具体实现将取决于我们的应用程序提供的自动填充数据的类型。自动填充服务must认真审视各个领域的特点,小心选择一组适当的自动填充建议,以避免将用户数据泄露给恶意客户端活动(请参阅评论)。特别是对于密码管理器,我们需要特别注意正确验证服务用户的身份,并在请求和保存自动填充数据时提供一组安全的建议。
我们现在可以注册服务 in the <application>
项目的 AndroidManifest.xml 块:
<service
android:name=".MyAutofillService"
android:label="Multi-Dataset Autofill Service"
android:permission="android.permission.BIND_AUTOFILL_SERVICE">
<meta-data
android:name="android.autofill"
android:resource="@xml/multidataset_service" />
<intent-filter>
<action android:name="android.service.autofill.AutofillService" />
</intent-filter>
</service>
如图所示,这将我们的自动填充服务绑定为出现在问题中显示的自动填充服务列表中的可用选项。这android:name
属性必须与我们的名称匹配AutofillService
类,我们的应用程序必须声明BIND_AUTOFILL_SERVICE
允许。改变值android:label
为该服务指定一个合适的名称(例如“使用密码管理器自动填充”)。或者,将其设置在字符串资源中。另请注意,我们应该提供一个“设置”活动,用于配置我们在<meta‑data>
for android.autofill
:
<autofill-service android:settingsActivity="foo.bar.SettingsActivity" />
然后,用户可以从其设备设置启用我们的自动填充服务。我们可以广播ACTION_REQUEST_SET_AUTOFILL_SERVICE意图在设置或首次启动期间帮助用户找到此屏幕。