I'm trying to develop an simple app whose uses Autofill Framework in Android Oreo for autofill email in the other apps. I've followed this tutorial to develop the app. But after running the app, I can't see my autofill service in the autofill service list in the settings to start it. I don't know why, please help!
Here is my code to build my autofill service:
My service:
public class EmailAddFiller extends AutofillService {
@Override
public void onFillRequest( @NonNull FillRequest request, @NonNull CancellationSignal cancellationSignal, FillCallback callback) {
List<AssistStructure.ViewNode> emailFields = new ArrayList<>();
// Get the structure from the request
List<FillContext> context = request.getFillContexts();
AssistStructure structure = context.get(context.size() - 1).getStructure();
identifyEmailFields(structure
.getWindowNodeAt(0)
.getRootViewNode(), emailFields);
AssistStructure.ViewNode emailField = emailFields.get(0);
SharedPreferences sharedPreferences =
getSharedPreferences("EMAIL_STORAGE", MODE_PRIVATE);
String primaryEmail =
sharedPreferences.getString("PRIMARY_EMAIL", "");
String secondaryEmail =
sharedPreferences.getString("SECONDARY_EMAIL", "");
Dataset primaryEmailDataSet =
new Dataset.Builder()
.setValue(
emailField.getAutofillId(),
AutofillValue.forText(primaryEmail)
).build();
Dataset secondaryEmailDataSet =
new Dataset.Builder()
.setValue(
emailField.getAutofillId(),
AutofillValue.forText(secondaryEmail)
).build();
FillResponse response = new FillResponse.Builder()
.addDataset(primaryEmailDataSet)
.addDataset(secondaryEmailDataSet)
.build();
callback.onSuccess(response);
}
private void identifyEmailFields(AssistStructure.ViewNode node, List<AssistStructure.ViewNode> emailFields) {
if(node.getClassName().contains("EditText")) {
String viewId = node.getIdEntry();
if(viewId!=null && (viewId.contains("email")
|| viewId.contains("username"))) {
emailFields.add(node);
return;
}
}
for(int i=0; i<node.getChildCount();i++) {
identifyEmailFields(node.getChildAt(i), emailFields);
}
}
@Override
public void onSaveRequest(@NonNull SaveRequest request, @NonNull SaveCallback callback) {
}
}
And the configuration in Manifestation file:
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".EmailAddFiller"
android:label="My Autofill Service"
android:permission="android.permission.BIND_AUTO_FILL">
<meta-data android:name="android.autofill"
android:resource="@xml/email_address_filler"/>
<intent-filter>
<action android:name="android.service.autofill.AutoFillService"/>
</intent-filter>
</service>
</application>
And build gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.tam.autofillapp"
minSdkVersion 26
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'com.android.support:design:28.+'
}
Do I miss something? If there is any other example about the topic, it's very appreciated. Thanks a lot!