- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我是密码管理器应用的独立开发者。我应该怎么做,或者我应该实现什么(接口(interface)/API/服务),使我的应用程序成为自动填充服务提供商(在 Android Oreo API >= 26 的设备中)?
我看了各种相关的文档,但是就是看不懂怎么弄。我错过了什么吗?
目前我看到只有知名的密码管理器支持这个功能:
欢迎任何提示。
最佳答案
像往常一样,谷歌自己的examples repository provides a good starting point用于学习 Autofill Framework 的 API,并且涵盖的 Material 比我能放入答案的 Material 多得多。下面是关键概念的概述。来自 documentation 中的描述,我们想要创建一个自动填充服务,它将处理来自其他应用程序(客户端)的请求以存储和检索自动填充字段数据。
首先,我们需要创建一个服务提供者类来履行这个契约。我们可以扩展基地 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()
和 onSaveRequest()
方法对我们的理解最重要。 Android系统调用onFillRequest()
确定我们的服务是否可以为特定 Activity 自动填充字段,并为方法提供 FillRequest
其中包含我们的服务将检查可填写字段的上下文和 View 信息。服务完成后,它会调用提供的 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
,我们需要遍历根的 View 树 ViewNode
及其每个 child 找到我们的服务希望为其提供自动填充数据的每个输入字段,然后创建一个 RemoteViews
和 Dataset
其中包含我们将添加到 FillResponse
的每个字段的自动填充建议使用 FillResponse.Builder.addDataset()
.此示例未显示 R.layout.autofill_suggestion
的纯 XML 布局TextView
用于为 RemoteViews
创建建议显示项.
同样,Android调用onSaveRequest()
当用户想要将数据保存在 Activity 的字段中以供将来完成请求并注入(inject) SaveRequest
时我们的服务使用它来查找要记住的自动填充数据。
这些方法中的每一个的具体实现将取决于我们的应用程序提供的自动填充数据的类型。自动填充服务必须认真检查每个字段的特征并仔细选择一组适当的自动填充建议以避免将用户数据泄露给恶意客户端 Activity (参见评论)。特别是对于密码管理器,我们需要特别注意正确验证服务的用户并在请求和保存自动填充数据时提供一组安全的建议。
我们现在可以 register the service在<application>
项目的 AndroidManifest.xml block :
<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>
如图所示,这会将我们的自动填充服务绑定(bind)为出现在问题中显示的自动填充服务列表中的可用选项。 android:name
属性必须匹配我们的名称 AutofillService
类,我们的应用程序必须声明 BIND_AUTOFILL_SERVICE
允许。更改 android:label
的值为该服务取一个合适的名称(例如,“Autofill with Password Manager”)。或者,在字符串资源中设置它。另请注意,我们应该提供一个“设置” Activity ,用于配置我们在 <meta‑data>
中指定的服务。对于 android.autofill
:
<autofill-service android:settingsActivity="foo.bar.SettingsActivity" />
然后,用户可以从他们的设备设置中启用我们的自动填充服务。我们可以广播 ACTION_REQUEST_SET_AUTOFILL_SERVICE
在设置或首次启动期间帮助用户找到此屏幕的 Intent 。
关于安卓奥利奥 : what should I do to publish my app as an Autofill service provider?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47367576/
根据下面的链接,我应该能够配置Web一键发布。甚至还有屏幕截图显示如何实现这一目标。但是,我在解决方案资源管理器中找不到该选项。我是弱智还是瞎子?! 如果有人质疑我的理智和在菜单上查找项目的能力,我很
我使用 OAuth 框架,它像这样异步创建经过身份验证的请求: OAuthSession.current.makeAuthenticatedRequest(request: myURLRequest)
我如何跨此 我为一个简单的秒表编写了代码,它也可以兼用作Rubik的立方计时器。源代码和可执行文件在这里: Cube timer 无论如何,我的疑问不是关于此代码的(它工作正常)。 我下载了我上传的可
我想使用 Apple 的新 Combine 框架从列表中的每个元素发出多个请求。然后我想要一个减少所有响应的单一结果。基本上,我想从发布者列表转到拥有响应列表的单个发布者。 我尝试制作一个发布商列表,
我在 EnvironmentObject 中为我的应用创建了一个“状态”对象像这样: class AppState: ObservableObject { @Published var cou
将企业应用程序部署到服务器(例如 Glassfish 或 JBoss)时,完全发布和增量发布有什么区别? 我看到部署的工件树中列出了几个模块,但是当我在 Web 存档上使用增量发布时,会发生一些事情,
我找不到这个记录。假设我想将一个端口发布到一个已知的地方,但有时会发布所有其他“暴露”的端口以进行调试或测试。 一个简单的 Dockerfile FROM alpine CMD /bin/sleep
在使用 ivy:publish ant 任务发布工件时,工件名称会附加我们为 ivy:publishrevision/pubrevision 属性指定的任何内容> 任务。 有没有办法将时间戳附加到这个
来自数据库系统概念,用于对象关系数据库的 SQL 命令: create type Publisher as (name varchar(20), branch varchar(20)); create
我有一个发布功能如下: Meteor.publish('tasks', function (name) { var project = Projects.findOne({name: name
我目前正在尝试实现两个出版商的合并。但是我找不到适合我的用例的解决方案。 我想合并 2 个发布者,它们都发出相同类型的结构数组。我希望合并的发布者在任一合并的发布者发出新值时发出值。 基本上这将是 P
我正在尝试复制 WWDC 2019 session “结合实践”中给出的“Wizard School Signup”示例 https://developer.apple.com/videos/play
我遇到 TweetInvi 0.9.9.7 无法上传视频的问题。该视频是一个 9MB 的 MP4 视频,我可以使用网络界面将它上传到 Twitter。我收到的错误消息是: The tweet cann
我在本地使用第三方库,我使用他们提供的步骤安装了所有内容。 我对包运行了 composer require 并运行了更新。这安装到 vendor 文件夹中。 然后我将路径添加到 config/app
尝试编译以下代码时: class LoginViewModel: ObservableObject, Identifiable { @Published var mailAdress: Str
我使用 .NET Core Framework 在 Visual Studio 2015 中创建了一个简单的 Web API 项目。当我使用默认设置发布此项目时,它会创建以下内容: 总共有 155 个
我正在 Laravel 7 中实现一个包并使用 https://github.com/jeroennoten/Laravel-AdminLTE作为引用。 在我的包内,我有以下结构 packages/m
当我尝试使用 Google 的结构化数据测试工具验证我的结构化数据时,出现错误: The attribute publisher.itemtype has an invalid value. 我在这条
刚从使用 Books 应用程序示例的 Djangobook 教程中学习时,您通过多对多关系将 Book 与 Author 相关,并将 Book 与 Publisher 相关。您可以使用 p.book_
我只是不得不这样做。绝对每个问题我都查找了有关此问题的问题,但他们的答案都没有帮助我解决问题。 我正在尝试在我的 Facebook 页面上发帖。 问题是: 错误:“(#100)您不能在已发布的帖子上指
我是一名优秀的程序员,十分优秀!