[英]Android Oreo: what should I do to publish my app as an Autofill service provider?
I'm an independent developer of a password manager app. 我是密码管理器应用程序的独立开发人员。 What should I do, or what should I implement (interface/API/Service), to make my app an Autofill service provider (in a device with Android Oreo API >= 26)? 我应该做什么,或者我应该实施什么(接口/ API /服务),使我的应用程序成为自动填充服务提供商(在Android Oreo API> = 26的设备中)?
I have read all kinds of related documentation, but I can't understand how to do this. 我已阅读各种相关文档,但我无法理解如何做到这一点。 Am I missing something? 我错过了什么吗?
At the moment I see that only well-known password managers support this feature: 目前我看到只有知名密码管理器才支持此功能:
Any hints are welcome. 任何提示都是受欢迎的。
As usual, Google's own examples repository provides a good starting point for learning the Autofill Framework's API, and covers much more material than I can fit into an answer. 像往常一样,Google自己的示例存储库为学习Autofill Framework的API 提供了一个良好的起点 ,并且涵盖了比我能够回答的更多的材料。 Here's an overview of the key concepts. 以下是关键概念的概述。 From the description in the documentation , we want to create an Autofill service that will handle requests from other apps (the clients) to store and retrieve Autofill field data. 根据文档中的描述,我们希望创建一个自动填充服务 ,该服务将处理来自其他应用程序(客户端)的请求,以存储和检索自动填充字段数据。
First, we need to create a service provider class that fulfills this contract. 首先,我们需要创建一个满足此合同的服务提供者类。 We can extend the base AutofillService
class : 我们可以扩展基本的AutofillService
类 :
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) { ... }
}
The service's onFillRequest()
and onSaveRequest()
methods are the most significant for our understanding. 服务的onFillRequest()
和onSaveRequest()
方法对我们的理解是最重要的。 The Android system calls onFillRequest()
to determine if our service can autofill fields for a particular activity, and gives the method a FillRequest
which contains the context and view information that our service will examine for fillable fields. Android系统调用onFillRequest()
来确定我们的服务是否可以自动填充特定活动的字段,并为该方法提供一个FillRequest
,其中包含我们的服务将检查可填充字段的上下文和视图信息。 When the service finishes, it invokes the provided callback
with the appropriate autofill data. 服务完成后,它会使用相应的自动填充数据调用提供的callback
。
Here's a dramatically simplified overview of the basic steps needed to provide autofill suggestions for a FillRequest
: 下面是需要一个提供自动填充建议的基本步骤大大简化概述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);
}
As we can see, the Autofill API requires a lot of code just to provide a single, static autofill suggestion for a View
that we already know in advance—the example assumes that viewNode
is a text input field that we want to provide autofill suggestions for. 我们可以看到,Autofill API需要大量代码才能为我们事先已经知道的View
提供单个静态自动填充建议 - 该示例假定viewNode
是一个文本输入字段,我们希望为其提供自动填充建议。 In reality, this example is too simple, but I wanted to clearly show the minimum implementation. 实际上,这个例子太简单了,但我想清楚地表明最小的实现。 For each WindowNode
, we need to walk through the view tree of the root ViewNode
and each of its children to find each of the input fields that our service wishes to provide autofill data for, and then create a RemoteViews
and Dataset
that contains the autofill suggestion for each field that we'll add to the FillResponse
using FillResponse.Builder.addDataset()
. 对于每个WindowNode
,我们需要遍历根ViewNode
及其每个子节点的视图树,以查找我们的服务希望为其提供自动填充数据的每个输入字段,然后创建包含自动填充建议的RemoteViews
和Dataset
对于我们将使用FillResponse.Builder.addDataset()
添加到FillResponse
每个字段。 This example doesn't show the plain XML layout for the R.layout.autofill_suggestion
TextView
used to create the suggestion display item for a RemoteViews
. 此示例未显示用于为RemoteViews
创建建议显示项的R.layout.autofill_suggestion
TextView
的纯XML布局。
Similarly, Android calls onSaveRequest()
when a user wants to save the data in an activity's fields for future completion requests and injects a SaveRequest
that our service uses to find autofill data to remember. 类似地,当用户想要将数据保存在活动的字段中以用于将来的完成请求时,Android会调用onSaveRequest()
并注入我们的服务用来查找要记住的自动填充数据的SaveRequest
。
The specific implementation of each of these methods will depend on the type of Autofill data that our app provides. 每种方法的具体实现将取决于我们的应用程序提供的自动填充数据的类型。 Autofill services must conscientiously examine the characteristics of each field and carefully select a set of appropriate autofill suggestions to avoid leaking the user's data to a malicious client activity (see comments). 自动填充服务必须认真检查每个字段的特征,并仔细选择一组适当的自动填充建议,以避免将用户的数据泄露给恶意客户端活动(请参阅注释)。 For a password manager in particular, we need to pay special attention to properly authenticating a user of the service and providing a safe set of suggestions when requesting and saving autofill data. 特别是对于密码管理器,我们需要特别注意正确地验证服务的用户,并在请求和保存自动填充数据时提供一组安全的建议。
We can now register the service in the <application>
block of the project's AndroidManifest.xml : 我们现在可以在项目的AndroidManifest.xml的<application>
块中注册该服务 :
<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>
As shown, this binds our Autofill service as an available option that appears in the Autofill services list show in the question. 如图所示,这会将我们的自动填充服务绑定为可用选项,该选项显示在问题中显示的自动填充服务列表中。 The android:name
attribute must match the name of our AutofillService
class, and our app must declare the BIND_AUTOFILL_SERVICE
permission. android:name
属性必须与我们的AutofillService
类的名称匹配,我们的应用程序必须声明BIND_AUTOFILL_SERVICE
权限。 Change the value of android:label
to a suitable name for the service (for example, "Autofill with Password Manager"). 将android:label
的值更改为服务的合适名称(例如,“使用Password Manager自动填充”)。 Alternatively, set this in a string resource. 或者,在字符串资源中设置它。 Note also that we should provide a "settings" activity used to configure our service which we specify in the <meta‑data>
for android.autofill
: 另请注意,我们应该提供一个“设置”活动,用于配置我们在android.autofill
的<meta‑data>
指定的服务:
<autofill-service android:settingsActivity="foo.bar.SettingsActivity" />
Then, the user can enable our Autofill service from their device Settings. 然后,用户可以通过其设备设置启用我们的自动填充服务。 We can broadcast the ACTION_REQUEST_SET_AUTOFILL_SERVICE
intent during setup or first launch to assist the user in finding this screen. 我们可以在设置或首次启动期间广播ACTION_REQUEST_SET_AUTOFILL_SERVICE
意图,以帮助用户找到此屏幕。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.