Overview
Fillr is the most advanced and accurate autofill technology ever created. By integrating Fillr you will give your users access to world leading autofill within your browser.
The Fillr Embedded library provides an easy way to integrate Fillr Autofill in to your own WebView based application, allowing users to populate web forms without leaving your application.
The advantage of the Embedded Fillr Library is that the entire Fillr profile functionality is tightly integrated within your app which means no Fillr standalone app is required to be downloaded by the user.
Prerequisites
- Contact us for the Developer Key, Secret Key and SDK information required for the integration.
- Java 7/8
- Android Studio along with:
- Android Build Tools 29.0.2
- Android SDK 29
Technical Overview
To completely integrate Fillr Embedded Autofill library you will need to integrate both the Fillr SDK and Fillr Embedded library.
The SDK acts as the middleman between the browser WebView and the users Fillr profile which is managed via the Embedded Application.
Getting Started
- Add the following dependencies to the
build.gradle
file located in the application’s directory (i.e. not the root build.gradle). Our repo is located on jcenter (See Troubleshooting below if your receive dependency resolution errors during buildimplementation 'com.fillr:fillrcore-fillrembedded:<latest_version>'
or
implementation 'com.fillr:fillrcore-fillrembeddedlite:<latest_version>'
-
Integrate the Fillr SDK by following the instructions here - from section ‘Enable Fillr on Your Browser Tabs’. You can skip the Getting Started steps 1 to 6 from that document since the Browser SDK is already included in via the gradle dependency above.
-
If your application extends
android.app.Application
, add the following lines to the onCreate method of the class that inherits fromandroid.app.Application
:@Override public void onCreate() { super.onCreate(); FillrApplication init = FillrApplication.getPopApplication(); init.init(this); }
If your application does not extend
android.app.Application
, you will need to create a class that does inherit fromandroid.app.Application
and add the code above once your application has been altered.For more help on extending
android.app.Application
please refer to:https://www.mobomo.com/2011/05/how-to-use-application-object-of-android/
https://developer.android.com/reference/android/app/Application.html
-
Enable merging of the Fillr Embedded library AndroidManifest.xml with your app’s manifest by adding the following attributes to your app manifest:
tools:node="merge" tools:replace="android:allowBackup,android:label,android:name,android:icon"
This will ensure that the manifests are merged and that the Fillr manifest does not overwrite important settings in your app.
Example: Your manifest file application node might look like this after this change:
<application android:name=".app.BrowserApp" android:allowBackup="false" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" tools:node="merge" tools:replace="android:allowBackup,android:label,android:name,android:icon"> ...... </application>
You also need to add the following namespace to your app’s manifest root node:
xmlns:tools="http://schemas.android.com/tools"
-
In the root gradle file add the following lines (if they aren’t already there)
``` buildscript { repositories { mavenCentral() maven { url “https://fillr.jfrog.io/artifactory/fillr-android-sdk/” credentials { username = “” // Contact Fillr for username and password password = “” } } } dependencies { classpath ‘com.android.tools.build:gradle:3.1.4’ } }
allprojects { repositories { mavenLocal() jcenter() mavenCentral() maven { url “https://fillr.jfrog.io/artifactory/fillr-android-sdk/” credentials { username = “” // Contact Fillr for username and password password = “” } } flatDir { dirs ‘libs’ } } }
6. Add a menu item in your browser menu named `Autofill Settings - Autofill Powered by Fillr`. This menu item should invoke the Fillr Embedded Settings activity using the following call:
startActivity(new Intent(this, FEMainActivity.class)); ``` 7. If you are using pro-guard to obfuscate your code. Please add the following lines:
-optimizations !class/unboxing/enum
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keepattributes JavascriptInterface
-keepattributes Signature
-keepattributes InnerClasses
-dontwarn okio.**
-dontwarn com.fillr.**
-dontwarn net.oneformapp.**
-dontwarn com.google.**
-dontwarn org.apache.commons.lang3.**
-dontwarn org.apache.commons.text.**
-dontwarn org.androidannotations.**
-dontwarn com.google.common.**
-keepattributes Exceptions
-keepattributes EnclosingMethod
-keep class com.fillr.** { *; }
-keep interface com.fillr.** { *; }
-keep class com.fillr.analytics.**
-keep interface com.fillr.analytics.**
-keep class net.oneformapp.** { *; }
-keep interface net.oneformapp.** { *; }
-keep class com.fillr.browsersdk.Fillr$JSNativeInterface
-keepclassmembers class com.fillr.browsersdk.Fillr
-keepclassmembers class com.fillr.browsersdk.Fillr$JSNativeInterface
-keep public class * implements com.fillr.browsersdk.Fillr$JSNativeInterface
-keepclassmembers class com.fillr.browsersdk.Fillr$JSNativeInterface {
<methods>;
}
-keep class com.google.android.gms.** { *; }
-keep interface com.google.android.gms.** { *; }
-keep class com.nineoldandroids.** { *; }
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
-keep class **.R$* {
<fields>;
}
Updating to the Fillr Embedded SDK (v6.x) from the Fillr Browser SDK (v7.x)
If you have previously integrated version v6.x of the Fillr SDK, you will need to supply a widget username and password as part of the initialization process in V7.
We no longer support the following initilization,
String devKey = "dev_key";
String secretKey = "secret_key";
FillrConfig config = new FillrConfig(devKey, secretKey);
Fillr.getInstance().initialise(config, .....);
Instead, please do the following
```
String devKey = "dev_key";
String secretKey = "secret_key";
String username = "username";
String password = "password";
FillrConfig config = new FillrConfig(devKey, secretKey, new FillrWidgetAuth(username, password));
Fillr.getInstance().initialise(config, .....);
```
Test Forms
The following are recommended forms for testing Fillr Autofill and validating your integration. They are easy to access and exercise a good range of fields from the Fillr profile:
- https://psr.slv.vic.gov.au
- https://www.gpcu.org/Applications/Loan-Payment-Form.aspx
- https://www.bradford.com.au/onlinepayment.html
Troubleshooting
If you face any issues during integration. We suggest trying the following,
- Adding MultiDex support.
- https://developer.android.com/studio/build/multidex.html
- Fillr uses the following dependencies,
+--- org.androidannotations:androidannotations-api:4.5.2 +--- com.android.support:multidex:1.0.2 +--- project :fillr-browser-sdk | +--- project :fillr-analytics | | +--- com.google.code.gson:gson:2.8.0 | | \--- com.android.support:support-v4:28.0.0 | | +--- com.android.support:support-compat:28.0.0 | | | +--- com.android.support:support-annotations:28.0.0 | | | +--- com.android.support:collections:28.0.0 | | | | \--- com.android.support:support-annotations:28.0.0 | | | +--- android.arch.lifecycle:runtime:1.1.1 | | | | +--- android.arch.lifecycle:common:1.1.1 | | | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0 | | | | +--- android.arch.core:common:1.1.1 | | | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0 | | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0 | | | \--- com.android.support:versionedparcelable:28.0.0 | | | +--- com.android.support:support-annotations:28.0.0 | | | \--- com.android.support:collections:28.0.0 (*) | | +--- com.android.support:support-media-compat:28.0.0 | | | +--- com.android.support:support-annotations:28.0.0 | | | +--- com.android.support:support-compat:28.0.0 (*) | | | \--- com.android.support:versionedparcelable:28.0.0 (*) | | +--- com.android.support:support-core-utils:28.0.0 | | | +--- com.android.support:support-annotations:28.0.0 | | | +--- com.android.support:support-compat:28.0.0 (*) | | | +--- com.android.support:documentfile:28.0.0 | | | | \--- com.android.support:support-annotations:28.0.0 | | | +--- com.android.support:loader:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | +--- android.arch.lifecycle:livedata:1.1.1 | | | | | +--- android.arch.core:runtime:1.1.1 | | | | | | +--- com.android.support:support-annotations:26.1.0 -> 28.0.0 | | | | | | \--- android.arch.core:common:1.1.1 (*) | | | | | +--- android.arch.lifecycle:livedata-core:1.1.1 | | | | | | +--- android.arch.lifecycle:common:1.1.1 (*) | | | | | | +--- android.arch.core:common:1.1.1 (*) | | | | | | \--- android.arch.core:runtime:1.1.1 (*) | | | | | \--- android.arch.core:common:1.1.1 (*) | | | | \--- android.arch.lifecycle:viewmodel:1.1.1 | | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0 | | | +--- com.android.support:localbroadcastmanager:28.0.0 | | | | \--- com.android.support:support-annotations:28.0.0 | | | \--- com.android.support:print:28.0.0 | | | \--- com.android.support:support-annotations:28.0.0 | | +--- com.android.support:support-core-ui:28.0.0 | | | +--- com.android.support:support-annotations:28.0.0 | | | +--- com.android.support:support-compat:28.0.0 (*) | | | +--- com.android.support:support-core-utils:28.0.0 (*) | | | +--- com.android.support:customview:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | \--- com.android.support:support-compat:28.0.0 (*) | | | +--- com.android.support:viewpager:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | \--- com.android.support:customview:28.0.0 (*) | | | +--- com.android.support:coordinatorlayout:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | \--- com.android.support:customview:28.0.0 (*) | | | +--- com.android.support:drawerlayout:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | \--- com.android.support:customview:28.0.0 (*) | | | +--- com.android.support:slidingpanelayout:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | \--- com.android.support:customview:28.0.0 (*) | | | +--- com.android.support:interpolator:28.0.0 | | | | \--- com.android.support:support-annotations:28.0.0 | | | +--- com.android.support:swiperefreshlayout:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | \--- com.android.support:interpolator:28.0.0 (*) | | | +--- com.android.support:asynclayoutinflater:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | \--- com.android.support:support-compat:28.0.0 (*) | | | \--- com.android.support:cursoradapter:28.0.0 | | | \--- com.android.support:support-annotations:28.0.0 | | \--- com.android.support:support-fragment:28.0.0 | | +--- com.android.support:support-compat:28.0.0 (*) | | +--- com.android.support:support-core-ui:28.0.0 (*) | | +--- com.android.support:support-core-utils:28.0.0 (*) | | +--- com.android.support:support-annotations:28.0.0 | | +--- com.android.support:loader:28.0.0 (*) | | \--- android.arch.lifecycle:viewmodel:1.1.1 (*) | +--- com.android.support:appcompat-v7:28.0.0 | | +--- com.android.support:support-annotations:28.0.0 | | +--- com.android.support:support-compat:28.0.0 (*) | | +--- com.android.support:collections:28.0.0 (*) | | +--- com.android.support:cursoradapter:28.0.0 (*) | | +--- com.android.support:support-core-utils:28.0.0 (*) | | +--- com.android.support:support-fragment:28.0.0 (*) | | +--- com.android.support:support-vector-drawable:28.0.0 | | | +--- com.android.support:support-annotations:28.0.0 | | | \--- com.android.support:support-compat:28.0.0 (*) | | \--- com.android.support:animated-vector-drawable:28.0.0 | | +--- com.android.support:support-vector-drawable:28.0.0 (*) | | \--- com.android.support:support-core-ui:28.0.0 (*) | +--- com.android.support:cardview-v7:28.0.0 | | \--- com.android.support:support-annotations:28.0.0 | \--- com.google.guava:guava-jdk5:17.0 +--- project :fillr-analytics (*) +--- android.arch.lifecycle:extensions:1.1.1 | +--- android.arch.lifecycle:runtime:1.1.1 (*) | +--- android.arch.core:common:1.1.1 (*) | +--- android.arch.core:runtime:1.1.1 (*) | +--- com.android.support:support-fragment:26.1.0 -> 28.0.0 (*) | +--- android.arch.lifecycle:common:1.1.1 (*) | +--- android.arch.lifecycle:livedata:1.1.1 (*) | \--- android.arch.lifecycle:viewmodel:1.1.1 (*) +--- android.arch.lifecycle:runtime:1.1.1 (*) +--- com.android.support:cardview-v7:28.0.0 (*) +--- com.android.support:appcompat-v7:28.0.0 (*) +--- com.android.support:recyclerview-v7:28.0.0 | +--- com.android.support:support-annotations:28.0.0 | +--- com.android.support:support-compat:28.0.0 (*) | \--- com.android.support:support-core-ui:28.0.0 (*) +--- com.android.support.constraint:constraint-layout:1.1.3 | \--- com.android.support.constraint:constraint-layout-solver:1.1.3 +--- com.android.support:design:28.0.0 | +--- com.android.support:support-annotations:28.0.0 | +--- com.android.support:support-compat:28.0.0 (*) | +--- com.android.support:support-core-ui:28.0.0 (*) | +--- com.android.support:support-core-utils:28.0.0 (*) | +--- com.android.support:support-fragment:28.0.0 (*) | +--- com.android.support:transition:28.0.0 | | +--- com.android.support:support-annotations:28.0.0 | | \--- com.android.support:support-compat:28.0.0 (*) | +--- com.android.support:appcompat-v7:28.0.0 (*) | +--- com.android.support:cardview-v7:28.0.0 (*) | \--- com.android.support:recyclerview-v7:28.0.0 (*) +--- com.google.android.gms:play-services-places:15.0.1 | +--- com.google.android.gms:play-services-base:[15.0.1,16.0.0) -> 15.0.1 | | +--- com.google.android.gms:play-services-basement:[15.0.1] -> 15.0.1 | | \--- com.google.android.gms:play-services-tasks:[15.0.1] -> 15.0.1 | | \--- com.google.android.gms:play-services-basement:[15.0.1] -> 15.0.1 | +--- com.google.android.gms:play-services-basement:[15.0.1,16.0.0) -> 15.0.1 | +--- com.google.android.gms:play-services-maps:[15.0.1,16.0.0) -> 15.0.1 | | +--- com.google.android.gms:play-services-base:[15.0.1,16.0.0) -> 15.0.1 (*) | | \--- com.google.android.gms:play-services-basement:[15.0.1,16.0.0) -> 15.0.1 | +--- com.google.android.gms:play-services-places-placereport:[15.0.1,16.0.0) -> 15.0.1 | | \--- com.google.android.gms:play-services-basement:[15.0.1,16.0.0) -> 15.0.1 | \--- com.google.android.gms:play-services-tasks:[15.0.1,16.0.0) -> 15.0.1 (*) +--- com.android.support:multidex:1.0.1 -> 1.0.2 +--- com.google.code.gson:gson:2.8.0 \--- org.greenrobot:eventbus:3.0.0
If there is a conflicting dependency, you can exclude it in the following manner,
implementation ('com.fillr:fillrcore-fillrembedded:<version>') {
transitive true
exclude group: '<group name>', module: '<module name>'
}
or force a particular dependency version,
configurations.all {
resolutionStrategy {
force 'com.android.support:support-v4:<version>'
}
}
Importing user data from your app to Fillr
To import user data, create an instance of com.fillr.userdataaccessor.UserDataAccessor class and pass data to it by calling the import methods as described below.
Every time an import method is called, it will overwrite the related data in Fillr. For example, if you import email addresses, it will remove all existing emails in Fillr profile. Ideally, the import methods should only be called once, when Fillr is first initialized.
When importing cell phone, telephone, credit card or address, a corresponding Fillr data model instance need to be created as below:
if (alreadyImportedData) {
return;
}
UserDataAccessor userDataAccessor = new UserDataAccessor(this);
// Import first name
userDataAccessor.importFirstName("First Name");
// Import last name
userDataAccessor.importLastName("Last Name");
// Import emails
List<String> testEmails = new ArrayList<>();
testEmails.add("name@domain.com");
userDataAccessor.importEmail(testEmails);
// Import cell phones
List<UserCellPhoneNumber> cellPhones = new ArrayList<>();
UserCellPhoneNumber userCellPhoneNumber1 = new UserCellPhoneNumber("Country Code", "Cell Phone Number");
cellPhones.add(userCellPhoneNumber1);
userDataAccessor.importCellPhoneNumber(cellPhones);
// Import telephones
List<UserTelephoneNumber> telephones = new ArrayList<>();
UserTelephoneNumber userTelephoneNumber1 = new UserTelephoneNumber("Country Code", "Area Code", "Telephone Number", "Telephone Extension");
telephones.add(userTelephoneNumber1);
userDataAccessor.importTelephoneNumber(telephones);
// Import credit cards and addresses
List<UserCreditCard> creditCards = new ArrayList<>();
UserCreditCard userCreditCard1 = new UserCreditCard("Nick Name 1", "Credit Card Number 1", "Credit Card Type 1", "Expiry 1", "CCV 1", "Name On Card 1");
UserCreditCard userCreditCard2 = new UserCreditCard("Nick Name 2", "Credit Card Number 2", "Credit Card Type 2", "Expiry 2", "CCV 2", "Name On Card 2");
creditCards.add(userCreditCard1);
creditCards.add(userCreditCard2);
userDataAccessor.importCreditCards(creditCards);
// Import addresses
List<UserAddress> userAddresses = new ArrayList<>();
UserAddress userAddress1 = new UserAddress("Po Box 1", "Level Number 1", "Unit Number 1", "Street Number 1", "Street Name 1", "Street Type 1", "Quadrant 1", "Suburb 1", "Administrative Area 1", "Postal Code 1", "Country 1", "Building Name 1", "Company Name 1");
UserAddress userAddress2 = new UserAddress("Po Box 2", "Level Number 2", "Unit Number 2", "Street Number 2", "Street Name 2", "Street Type 2", "Quadrant 2", "Suburb 2", "Administrative Area 2", "Postal Code 2", "Country 2", "Building Name 2", "Company Name 2");
userAddresses.add(userAddress1);
userAddresses.add(userAddress2);
userDataAccessor.importAddresses(userAddresses);
You can also pass address as single line of string to importRawAddresses methods:
List<String> rawAddresses = Arrays.asList("268 Little Collins St. Melbourne VIC 3000 Australia");
userDataAccessor.importRawAddresses(rawAddresses);
Optional Configuration
Disable Capture Value
Capture value is a feature that fillr sdk can save user input data from webview back into Fillr profile. Capture value is enabled by default, it can be turned off as follow:
Fillr.getInstance().setCaptureValueDisabled(true);
Form Filled Listener
In order to know when a form has been filled, the following method can be implemented,
Fillr.getInstance().setOnFormFilledListener(new Fillr.FormFilledListener() {
@Override
public void onFillPerformed(String mappings, String profileData) {
}
});
Web Form Field Focused Listener
A callback to notify when a field within a web form has received focused. The field param in the method specifies the field namespace of the focused field.
Fillr.getInstance().setFormEventListener(new Fillr.FormEventListener() {
@Override
public void onFieldFocused(String fieldMapping) {
}
});
Support
For technical support contact support@fillr.com
Draft document only. API subject to change.