下面列出了android.app.assist.AssistStructure.ViewNode#getAutofillHints ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
@NonNull ViewNode node) {
String[] hints = node.getAutofillHints();
if (hints != null) {
// We're simple, we only care about the first hint
String hint = hints[0];
AutofillId id = node.getAutofillId();
if (!fields.containsKey(hint)) {
Log.v(TAG, "Setting hint '" + hint + "' on " + id);
fields.put(hint, id);
} else {
Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
+ " because it was already set");
}
}
int childrenSize = node.getChildCount();
for (int i = 0; i < childrenSize; i++) {
addAutofillableFields(fields, node.getChildAt(i));
}
}
/**
* Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
*/
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
@NonNull ViewNode node) {
String[] hints = node.getAutofillHints();
if (hints != null) {
// We're simple, we only care about the first hint
String hint = hints[0].toLowerCase();
if (hint != null) {
AutofillId id = node.getAutofillId();
if (!fields.containsKey(hint)) {
Log.v(TAG, "Setting hint '" + hint + "' on " + id);
fields.put(hint, id);
} else {
Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
+ " because it was already set");
}
}
}
int childrenSize = node.getChildCount();
for (int i = 0; i < childrenSize; i++) {
addAutofillableFields(fields, node.getChildAt(i));
}
}
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
@NonNull ViewNode node) {
String[] hints = node.getAutofillHints();
if (hints != null) {
// We're simple, we only care about the first hint
String hint = hints[0];
AutofillId id = node.getAutofillId();
if (!fields.containsKey(hint)) {
Log.v(TAG, "Setting hint '" + hint + "' on " + id);
fields.put(hint, id);
} else {
Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
+ " because it was already set");
}
}
int childrenSize = node.getChildCount();
for (int i = 0; i < childrenSize; i++) {
addAutofillableFields(fields, node.getChildAt(i));
}
}
/**
* Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
*/
private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
@NonNull ViewNode node) {
String[] hints = node.getAutofillHints();
if (hints != null) {
// We're simple, we only care about the first hint
String hint = hints[0].toLowerCase();
if (hint != null) {
AutofillId id = node.getAutofillId();
if (!fields.containsKey(hint)) {
Log.v(TAG, "Setting hint '" + hint + "' on " + id);
fields.put(hint, id);
} else {
Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
+ " because it was already set");
}
}
}
int childrenSize = node.getChildCount();
for (int i = 0; i < childrenSize; i++) {
addAutofillableFields(fields, node.getChildAt(i));
}
}
@Nullable
protected String getHint(@NonNull ViewNode node) {
// First try the explicit autofill hints...
String[] hints = node.getAutofillHints();
if (hints != null) {
// We're simple, we only care about the first hint
return hints[0].toLowerCase();
}
// Then try some rudimentary heuristics based on other node properties
String viewHint = node.getHint();
String hint = inferHint(node, viewHint);
if (hint != null) {
Log.d(TAG, "Found hint using view hint(" + viewHint + "): " + hint);
return hint;
} else if (!TextUtils.isEmpty(viewHint)) {
Log.v(TAG, "No hint using view hint: " + viewHint);
}
String resourceId = node.getIdEntry();
hint = inferHint(node, resourceId);
if (hint != null) {
Log.d(TAG, "Found hint using resourceId(" + resourceId + "): " + hint);
return hint;
} else if (!TextUtils.isEmpty(resourceId)) {
Log.v(TAG, "No hint using resourceId: " + resourceId);
}
CharSequence text = node.getText();
CharSequence className = node.getClassName();
if (text != null && className != null && className.toString().contains("EditText")) {
hint = inferHint(node, text.toString());
if (hint != null) {
// NODE: text should not be logged, as it could contain PII
Log.d(TAG, "Found hint using text(" + text + "): " + hint);
return hint;
}
} else if (!TextUtils.isEmpty(text)) {
// NODE: text should not be logged, as it could contain PII
Log.v(TAG, "No hint using text: " + text + " and class " + className);
}
return null;
}
private static void dumpNode(StringBuilder builder, String prefix, ViewNode node, int childNumber) {
builder.append(prefix)
.append("child #").append(childNumber).append("\n");
builder.append(prefix)
.append("autoFillId: ").append(node.getAutofillId())
.append("\tidEntry: ").append(node.getIdEntry())
.append("\tid: ").append(node.getId())
.append("\tclassName: ").append(node.getClassName())
.append('\n');
builder.append(prefix)
.append("focused: ").append(node.isFocused())
.append("\tvisibility").append(node.getVisibility())
.append("\tchecked: ").append(node.isChecked())
.append("\twebDomain: ").append(node.getWebDomain())
.append("\thint: ").append(node.getHint())
.append('\n');
HtmlInfo htmlInfo = node.getHtmlInfo();
if (htmlInfo != null) {
builder.append(prefix)
.append("HTML TAG: ").append(htmlInfo.getTag())
.append(" attrs: ").append(htmlInfo.getAttributes())
.append('\n');
}
String[] afHints = node.getAutofillHints();
CharSequence[] options = node.getAutofillOptions();
builder.append(prefix).append("afType: ").append(getTypeAsString(node.getAutofillType()))
.append("\tafValue:")
.append(getAutofillValueAndTypeAsString(node.getAutofillValue()))
.append("\tafOptions:").append(options == null ? "N/A" : Arrays.toString(options))
.append("\tafHints: ").append(afHints == null ? "N/A" : Arrays.toString(afHints))
.append("\tinputType:").append(node.getInputType())
.append('\n');
int numberChildren = node.getChildCount();
builder.append(prefix).append("# children: ").append(numberChildren)
.append("\ttext: ").append(node.getText())
.append('\n');
final String prefix2 = prefix + " ";
for (int i = 0; i < numberChildren; i++) {
dumpNode(builder, prefix2, node.getChildAt(i), i);
}
logv(builder.toString());
}
private static void dumpNode(String prefix, ViewNode node) {
StringBuilder builder = new StringBuilder();
builder.append(prefix)
.append("autoFillId: ").append(node.getAutofillId())
.append("\tidEntry: ").append(node.getIdEntry())
.append("\tid: ").append(node.getId())
.append("\tclassName: ").append(node.getClassName())
.append('\n');
builder.append(prefix)
.append("focused: ").append(node.isFocused())
.append("\tvisibility").append(node.getVisibility())
.append("\tchecked: ").append(node.isChecked())
.append("\twebDomain: ").append(node.getWebDomain())
.append("\thint: ").append(node.getHint())
.append('\n');
HtmlInfo htmlInfo = node.getHtmlInfo();
if (htmlInfo != null) {
builder.append(prefix)
.append("HTML TAG: ").append(htmlInfo.getTag())
.append(" attrs: ").append(htmlInfo.getAttributes())
.append('\n');
}
String[] afHints = node.getAutofillHints();
CharSequence[] options = node.getAutofillOptions();
builder.append(prefix).append("afType: ").append(getAutofillTypeAsString(node.getAutofillType()))
.append("\tafValue:")
.append(getAutofillValueAndTypeAsString(node.getAutofillValue()))
.append("\tafOptions:").append(options == null ? "N/A" : Arrays.toString(options))
.append("\tafHints: ").append(afHints == null ? "N/A" : Arrays.toString(afHints))
.append("\tinputType:").append(node.getInputType())
.append('\n');
int numberChildren = node.getChildCount();
builder.append(prefix).append("# children: ").append(numberChildren)
.append("\ttext: ").append(node.getText())
.append('\n');
Log.v(TAG, builder.toString());
final String prefix2 = prefix + " ";
for (int i = 0; i < numberChildren; i++) {
Log.v(TAG, prefix + "child #" + i);
dumpNode(prefix2, node.getChildAt(i));
}
}
@Nullable
protected String getHint(@NonNull ViewNode node) {
// First try the explicit autofill hints...
String[] hints = node.getAutofillHints();
if (hints != null) {
// We're simple, we only care about the first hint
return hints[0].toLowerCase();
}
// Then try some rudimentary heuristics based on other node properties
String viewHint = node.getHint();
String hint = inferHint(node, viewHint);
if (hint != null) {
Log.d(TAG, "Found hint using view hint(" + viewHint + "): " + hint);
return hint;
} else if (!TextUtils.isEmpty(viewHint)) {
Log.v(TAG, "No hint using view hint: " + viewHint);
}
String resourceId = node.getIdEntry();
hint = inferHint(node, resourceId);
if (hint != null) {
Log.d(TAG, "Found hint using resourceId(" + resourceId + "): " + hint);
return hint;
} else if (!TextUtils.isEmpty(resourceId)) {
Log.v(TAG, "No hint using resourceId: " + resourceId);
}
CharSequence text = node.getText();
CharSequence className = node.getClassName();
if (text != null && className != null && className.toString().contains("EditText")) {
hint = inferHint(node, text.toString());
if (hint != null) {
// NODE: text should not be logged, as it could contain PII
Log.d(TAG, "Found hint using text(" + text + "): " + hint);
return hint;
}
} else if (!TextUtils.isEmpty(text)) {
// NODE: text should not be logged, as it could contain PII
Log.v(TAG, "No hint using text: " + text + " and class " + className);
}
return null;
}
private static void dumpNode(StringBuilder builder, String prefix, ViewNode node, int childNumber) {
builder.append(prefix)
.append("child #").append(childNumber).append("\n");
builder.append(prefix)
.append("autoFillId: ").append(node.getAutofillId())
.append("\tidEntry: ").append(node.getIdEntry())
.append("\tid: ").append(node.getId())
.append("\tclassName: ").append(node.getClassName())
.append('\n');
builder.append(prefix)
.append("focused: ").append(node.isFocused())
.append("\tvisibility").append(node.getVisibility())
.append("\tchecked: ").append(node.isChecked())
.append("\twebDomain: ").append(node.getWebDomain())
.append("\thint: ").append(node.getHint())
.append('\n');
HtmlInfo htmlInfo = node.getHtmlInfo();
if (htmlInfo != null) {
builder.append(prefix)
.append("HTML TAG: ").append(htmlInfo.getTag())
.append(" attrs: ").append(htmlInfo.getAttributes())
.append('\n');
}
String[] afHints = node.getAutofillHints();
CharSequence[] options = node.getAutofillOptions();
builder.append(prefix).append("afType: ").append(getTypeAsString(node.getAutofillType()))
.append("\tafValue:")
.append(getAutofillValueAndTypeAsString(node.getAutofillValue()))
.append("\tafOptions:").append(options == null ? "N/A" : Arrays.toString(options))
.append("\tafHints: ").append(afHints == null ? "N/A" : Arrays.toString(afHints))
.append("\tinputType:").append(node.getInputType())
.append('\n');
int numberChildren = node.getChildCount();
builder.append(prefix).append("# children: ").append(numberChildren)
.append("\ttext: ").append(node.getText())
.append('\n');
final String prefix2 = prefix + " ";
for (int i = 0; i < numberChildren; i++) {
dumpNode(builder, prefix2, node.getChildAt(i), i);
}
logv(builder.toString());
}
private static void dumpNode(String prefix, ViewNode node) {
StringBuilder builder = new StringBuilder();
builder.append(prefix)
.append("autoFillId: ").append(node.getAutofillId())
.append("\tidEntry: ").append(node.getIdEntry())
.append("\tid: ").append(node.getId())
.append("\tclassName: ").append(node.getClassName())
.append('\n');
builder.append(prefix)
.append("focused: ").append(node.isFocused())
.append("\tvisibility").append(node.getVisibility())
.append("\tchecked: ").append(node.isChecked())
.append("\twebDomain: ").append(node.getWebDomain())
.append("\thint: ").append(node.getHint())
.append('\n');
HtmlInfo htmlInfo = node.getHtmlInfo();
if (htmlInfo != null) {
builder.append(prefix)
.append("HTML TAG: ").append(htmlInfo.getTag())
.append(" attrs: ").append(htmlInfo.getAttributes())
.append('\n');
}
String[] afHints = node.getAutofillHints();
CharSequence[] options = node.getAutofillOptions();
builder.append(prefix).append("afType: ").append(getAutofillTypeAsString(node.getAutofillType()))
.append("\tafValue:")
.append(getAutofillValueAndTypeAsString(node.getAutofillValue()))
.append("\tafOptions:").append(options == null ? "N/A" : Arrays.toString(options))
.append("\tafHints: ").append(afHints == null ? "N/A" : Arrays.toString(afHints))
.append("\tinputType:").append(node.getInputType())
.append('\n');
int numberChildren = node.getChildCount();
builder.append(prefix).append("# children: ").append(numberChildren)
.append("\ttext: ").append(node.getText())
.append('\n');
Log.v(TAG, builder.toString());
final String prefix2 = prefix + " ";
for (int i = 0; i < numberChildren; i++) {
Log.v(TAG, prefix + "child #" + i);
dumpNode(prefix2, node.getChildAt(i));
}
}