How to use Android autofill API
Asked Answered
L

3

12

I've built a little browser using the android webview component and am looking to integrate password/credential manager support using the Android AutoFill API.

I've read the docs but am completely lost and can't find any examples of integration with complex things like webviews.

The javascript side of this is not a problem for me, I already have events that are triggered when a user selects an input on a login form (and the auto-fill dialog should be presented), and when a finishes entering a username and password and submits the page (and the credentials should be saved back to the password manager) but I'm struggling to understand the android side of this.

The webview seems to have some basic support for this already, for example if I long press on a login form input, and select "auto-fill" in the context menu, I can get it to insert some values saved in the credential manager. The problem is though that the credentials have been saved against my app ID, not the website domain, so my first question, how do I tell the API that when I'm requesting the auto fill menu that it's for a specific field type (e.g. username/password) and belonging to a particular website so it knows which credentials to fetch and can update them later? Here is my attempt to trigger the auto-fill dialog to appear when selecting a field in the login form.

UPDATE: When I create a static webview in my app the autofill correctly saves and prompts for credentials on forms and saves them correctly per site BUT I need this to work in webviews that are in a recyclerview and for some reason they don't despite sharing the same settings. I found this info about autofill in recyclerviews https://developer.android.com/guide/topics/text/autofill-optimize#recycle but using setAutofillId() doesn't seem to help and even the official example here seems a bit unreliable when I test it on my phone https://github.com/android/input-samples/blob/master/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/RecyclerViewActivity.java

Le answered 24/7, 2020 at 14:54 Comment(4)
I don't know the answer, but i'm sure its solvable. I'd love to research and try to find the solution, for 300 bounty :). Would be great if you could share the repo link, unless its commercial of course.Safekeeping
I can't share the source but I guess it's easy enough to add a webview to a basic app. The key thing is that the auto-fill works across different domains, currently Bitwarden for example treats everything as from my app id (as if it thinks there's a single username and password for my whole app).Le
have you checked the samples? github.com/android/input-samples/tree/master/AutofillFramework/…Decommission
Load the web page in the WebView: https://mcmap.net/q/1011995/-how-can-i-autofill-a-websites-fields-forms-in-a-webview-in-android-studioShagreen
L
0

The problem I was having is that my webviews were embedded in a recyclerview, and to enable autofill on a web view in a recyclerview, you must set it to be enabled on the recyclerview, NOT on the webview itself.

Le answered 4/10, 2021 at 16:55 Comment(0)
N
3

A simple solution would be to let webview handle this.

webView.getSettings().setSaveFormData(true);

    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setPluginState(WebSettings.PluginState.ON);
    webView.getSettings().setBuiltInZoomControls(true);
    webView.getSettings().setDisplayZoomControls(true);
    webView.setWebChromeClient(new WebChromeClient() /*Or yourOwnWebChromeClient*/);
    webView.setWebViewClient(new WebViewClient() /*Or yourOwnWebViewClient*/);
    webView.getSettings().setDomStorageEnabled(true);
    webView.getSettings().setSaveFormData(true);

    CookieSyncManager.createInstance(this);
    CookieManager cookieManager = CookieManager.getInstance();
    cookieManager.setAcceptCookie(true);
    CookieSyncManager.getInstance().startSync();

You may also add JavaScript Interface if needed

    webView.addJavascriptInterface(this, JSInterface);

I used this approach and it saved the login tokens for facebook, instagram, as well as dailymotion.com .

Please try this https://mcmap.net/q/1011996/-how-to-cache-multiple-urls-for-a-webview-activity-from-recycler-view-onclick

you may try Creating multiple cache

You might want to refer this too - https://developer.android.com/guide/webapps/managing-webview#java

Noseband answered 4/8, 2020 at 10:39 Comment(6)
The documentation says "This function does not have any effect." for setSaveFormData() and has been deprecated since Oreo. If you've tested it and remembers login credentials across multiple websites then it sounds like I have done something wrong though. So you didn't do anything special in the manifest or XML? Maybe I need to try this in a simpler appLe
I used all of these settings from various answers on stack-overflow... Not sure exactly which setting helped. May be the cookieNoseband
Ok, it's definitely something to do with my set up. If I create a static webview it works, but the webviews I am using for my browser don't work, maybeee it's because they are on a recyclerview? hmmmmLe
you may try Creating multiple cacheNoseband
You may consider awarding bounty before grace period is over so that it may not be wastedNoseband
The link about changing the cache mode seems unrelated and I don't want to force it to use caches but leave it on the default mode (which works for other webviews). As I don't have a working solution yet I'm not sure I should gift the bounty. It seems to be a problem with the fact that the webview is in a recyclerview. Any ideas about that? I found documentation that shows you need to set the autofillId when using autofill in a recyclerview but it doesn't seem to work with webviews stillLe
A
2

There's a guide available here describing how to get your app ready to leverage Autofill. Here's the most relevant part describing your choices, especially if using a Webview:

In many cases, Autofill may work in your app without any effort. But to ensure consistent behavior, we recommend providing explicit hints to tell the framework about the contents of your field. You can do this using either the android:autofillHints attribute or the setAutofillHints() method.

To associate your app with a website, though, you'll need to add some settings to your app's Manifest. You'll see this under Step 2 of the link above.

You'll need to update your app's manifest file with an asset_statements resource, which links to the URL where your assetlinks.json file is hosted. Once that's done, you'll need to submit your updated app to the Play Store, and fill out the Affiliation Submission Form for the association to go live.

When using Android Studio 3.0, the App Links Assistant can generate all of this for you. When you open the DAL generator tool (Tools -> App Links Assistant -> Open Digital Asset Links File Generator), simply make sure you enable the new checkbox labeled "Support sharing credentials between the app and website". Similarly, with WebViews in your apps, you can use HTML Autocomplete Attributes to provide hints about fields. Autofill will work in WebViews as long as you have Chrome 61 or later installed on your device. Even if your app is using custom views, you can also define the metadata that allows autofill to work.

Alloway answered 3/8, 2020 at 16:16 Comment(1)
Thanks for the answer but I don't think this helps on it's own. It's a browser app so the user could be visiting any website so hosting JSON files on them is not an option. There might be a way I can fake it but unfortunately I won't have a lot of time tomorrow evening to experiment with itLe
L
0

The problem I was having is that my webviews were embedded in a recyclerview, and to enable autofill on a web view in a recyclerview, you must set it to be enabled on the recyclerview, NOT on the webview itself.

Le answered 4/10, 2021 at 16:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.