下面列出了怎么用android.view.autofill.AutofillValue的API类实例代码及写法,或者点击链接到github查看源代码。
static Dataset newUnlockedDataset(@NonNull Map<String, AutofillId> fields,
@NonNull String packageName, int i) {
Dataset.Builder dataset = new Dataset.Builder();
for (Entry<String, AutofillId> field : fields.entrySet()) {
String hint = field.getKey();
AutofillId id = field.getValue();
String value = i + "-" + hint;
// We're simple - our dataset values are hardcoded as "N-hint" (for example,
// "1-username", "2-username") and they're displayed as such, except if they're a
// password
String displayValue = hint.contains("password") ? "password for #" + i : value;
RemoteViews presentation = newDatasetPresentation(packageName, displayValue);
dataset.setValue(id, AutofillValue.forText(value), presentation);
}
return dataset.build();
}
/** @hide */
@Override
@TestApi
public void apply(@NonNull ValueFinder finder, @NonNull RemoteViews parentTemplate,
int childViewId) throws Exception {
final AutofillValue value = finder.findRawValueByAutofillId(mFieldId);
if (value == null) {
Log.w(TAG, "No value for id " + mFieldId);
return;
}
if (!value.isDate()) {
Log.w(TAG, "Value for " + mFieldId + " is not date: " + value);
return;
}
try {
final Date date = new Date(value.getDateValue());
final String transformed = mDateFormat.format(date);
if (sDebug) Log.d(TAG, "Transformed " + date + " to " + transformed);
parentTemplate.setCharSequence(childViewId, "setText", transformed);
} catch (Exception e) {
Log.w(TAG, "Could not apply " + mDateFormat + " to " + value + ": " + e);
}
}
private void setLifeTheUniverseAndEverything(@NonNull AutofillId id,
@Nullable AutofillValue value, @Nullable RemoteViews presentation,
@Nullable DatasetFieldFilter filter) {
Preconditions.checkNotNull(id, "id cannot be null");
if (mFieldIds != null) {
final int existingIdx = mFieldIds.indexOf(id);
if (existingIdx >= 0) {
mFieldValues.set(existingIdx, value);
mFieldPresentations.set(existingIdx, presentation);
mFieldFilters.set(existingIdx, filter);
return;
}
} else {
mFieldIds = new ArrayList<>();
mFieldValues = new ArrayList<>();
mFieldPresentations = new ArrayList<>();
mFieldFilters = new ArrayList<>();
}
mFieldIds.add(id);
mFieldValues.add(value);
mFieldPresentations.add(presentation);
mFieldFilters.add(filter);
}
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
return;
}
check(child.getId());
}
@Override
public final void autofill(AutofillValue value) {
if (value == null || !value.isDate()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final long time = value.getDateValue();
final Calendar cal = Calendar.getInstance(mLocale);
cal.setTimeInMillis(time);
setDate(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
// Must set mAutofilledValue *after* calling subclass method to make sure the value
// returned by getAutofillValue() matches it.
mAutofilledValue = time;
}
@Override
public final void autofill(AutofillValue value) {
if (value == null || !value.isDate()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final long time = value.getDateValue();
final Calendar cal = Calendar.getInstance(mCurrentLocale);
cal.setTimeInMillis(time);
updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH));
// Must set mAutofilledValue *after* calling subclass method to make sure the value
// returned by getAutofillValue() matches it.
mAutofilledValue = time;
}
@TargetApi(Build.VERSION_CODES.O)
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
return;
}
nestedRadioGroupManager.check(child.getId());
}
@TargetApi(Build.VERSION_CODES.O)
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
return;
}
nestedRadioGroupManager.check(child.getId());
}
@TargetApi(Build.VERSION_CODES.O)
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
return;
}
nestedRadioGroupManager.check(child.getId());
}
@TargetApi(Build.VERSION_CODES.O)
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
return;
}
nestedRadioGroupManager.check(child.getId());
}
static Dataset newUnlockedDataset(@NonNull Map<String, AutofillId> fields,
@NonNull String packageName, int i) {
Dataset.Builder dataset = new Dataset.Builder();
for (Entry<String, AutofillId> field : fields.entrySet()) {
String hint = field.getKey();
AutofillId id = field.getValue();
String value = i + "-" + hint;
// We're simple - our dataset values are hardcoded as "N-hint" (for example,
// "1-username", "2-username") and they're displayed as such, except if they're a
// password
String displayValue = hint.contains("password") ? "password for #" + i : value;
RemoteViews presentation = newDatasetPresentation(packageName, displayValue);
dataset.setValue(id, AutofillValue.forText(value), presentation);
}
return dataset.build();
}
private void parseAutofillFields(AssistStructure.ViewNode viewNode,
DatasetWithFilledAutofillFields datasetWithFilledAutofillFields, int partition) {
String[] hints = viewNode.getAutofillHints();
if (hints == null || hints.length == 0) {
return;
}
AutofillValue autofillValue = viewNode.getAutofillValue();
String textValue = null;
Long dateValue = null;
Boolean toggleValue = null;
CharSequence[] autofillOptions = null;
Integer listIndex = null;
if (autofillValue != null) {
if (autofillValue.isText()) {
// Using toString of AutofillValue.getTextValue in order to save it to
// SharedPreferences.
textValue = autofillValue.getTextValue().toString();
} else if (autofillValue.isDate()) {
dateValue = autofillValue.getDateValue();
} else if (autofillValue.isList()) {
autofillOptions = viewNode.getAutofillOptions();
listIndex = autofillValue.getListValue();
} else if (autofillValue.isToggle()) {
toggleValue = autofillValue.getToggleValue();
}
}
appendViewMetadata(datasetWithFilledAutofillFields,
hints, partition, textValue, dateValue, toggleValue,
autofillOptions, listIndex);
}
private static String getAutofillValueAndTypeAsString(AutofillValue value) {
if (value == null) return "null";
StringBuilder builder = new StringBuilder(value.toString()).append('(');
if (value.isText()) {
builder.append("isText");
} else if (value.isDate()) {
builder.append("isDate");
} else if (value.isToggle()) {
builder.append("isToggle");
} else if (value.isList()) {
builder.append("isList");
}
return builder.append(')').toString();
}
@Override
public AutofillValue getAutofillValue() {
Calendar c = getCalendar();
AutofillValue value = AutofillValue.forDate(c.getTimeInMillis());
if (DEBUG) Log.d(TAG, "getAutofillValue(): " + value);
return value;
}
@Override
public void autofill(AutofillValue value) {
if (value == null || !value.isDate()) {
Log.w(TAG, "autofill(): invalid value " + value);
return;
}
long time = value.getDateValue();
mTempCalendar.setTimeInMillis(time);
int year = mTempCalendar.get(Calendar.YEAR);
int month = mTempCalendar.get(Calendar.MONTH);
if (DEBUG) Log.d(TAG, "autofill(" + value + "): " + month + "/" + year);
setDate(year, month);
}
@Override
public AutofillValue getAutofillValue() {
Calendar calendar = Calendar.getInstance();
// Set hours, minutes, seconds, and millis to 0 to ensure getAutofillValue() == the value
// set by autofill(). Without this line, the view will not turn yellow when updated.
calendar.clear();
int year = Integer.parseInt(mCcExpYearSpinner.getSelectedItem().toString());
int month = mCcExpMonthSpinner.getSelectedItemPosition();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
long unixTime = calendar.getTimeInMillis();
return AutofillValue.forDate(unixTime);
}
@Override
public void autofill(AutofillValue value) {
if (!value.isDate()) {
Log.w(TAG, "Ignoring autofill() because service sent a non-date value:" + value);
return;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(value.getDateValue());
int month = calendar.get(Calendar.MONTH);
int year = calendar.get(Calendar.YEAR);
mCcExpMonthSpinner.setSelection(month);
mCcExpYearSpinner.setSelection(year - Integer.parseInt(mYears[0]));
}
protected AutofillValue getAutofillValue() {
switch (type) {
case AUTOFILL_TYPE_TEXT:
return (TextUtils.getTrimmedLength(text) > 0)
? AutofillValue.forText(text)
: null;
case AUTOFILL_TYPE_DATE:
return AutofillValue.forDate(date);
default:
return null;
}
}
private static String getAutofillValueAndTypeAsString(AutofillValue value) {
if (value == null) return "null";
StringBuilder builder = new StringBuilder(value.toString()).append('(');
if (value.isText()) {
builder.append("isText");
} else if (value.isDate()) {
builder.append("isDate");
} else if (value.isToggle()) {
builder.append("isToggle");
} else if (value.isList()) {
builder.append("isList");
}
return builder.append(')').toString();
}
/**
* Updates the {@link AutofillValue} of this structure.
*
* <p>Should be used just before sending the structure to the
* {@link android.service.autofill.AutofillService} for saving, since it will override the
* initial value.
*
* @hide
*/
public void updateAutofillValue(AutofillValue value) {
mAutofillValue = value;
if (value.isText()) {
if (mText == null) {
mText = new ViewNodeText();
}
mText.mText = value.getTextValue();
}
}
private void getScores(RemoteCallback callback, String algorithmName, Bundle algorithmArgs,
List<AutofillValue> actualValues, String[] userDataValues) {
final Bundle data = new Bundle();
final float[][] scores = onGetScores(algorithmName, algorithmArgs, actualValues,
Arrays.asList(userDataValues));
if (scores != null) {
data.putParcelable(EXTRA_SCORES, new Scores(scores));
}
callback.sendResult(data);
}
@Override
public void getScores(RemoteCallback callback, String algorithmName, Bundle algorithmArgs,
List<AutofillValue> actualValues, String[] userDataValues)
throws RemoteException {
mHandler.sendMessage(obtainMessage(
AutofillFieldClassificationService::getScores,
AutofillFieldClassificationService.this,
callback, algorithmName, algorithmArgs, actualValues, userDataValues));
}
/** @hide */
@Override
@TestApi
@Nullable
public AutofillValue sanitize(@NonNull AutofillValue value) {
if (value == null) {
Log.w(TAG, "sanitize() called with null value");
return null;
}
if (!value.isDate()) {
if (sDebug) Log.d(TAG, value + " is not a date");
return null;
}
try {
final Date date = new Date(value.getDateValue());
// First convert it to string
final String converted = mDateFormat.format(date);
if (sDebug) Log.d(TAG, "Transformed " + date + " to " + converted);
// Then parse it back to date
final Date sanitized = mDateFormat.parse(converted);
if (sDebug) Log.d(TAG, "Sanitized to " + sanitized);
return AutofillValue.forDate(sanitized.getTime());
} catch (Exception e) {
Log.w(TAG, "Could not apply " + mDateFormat + " to " + value + ": " + e);
return null;
}
}
@Override
public Dataset createFromParcel(Parcel parcel) {
// Always go through the builder to ensure the data ingested by
// the system obeys the contract of the builder to avoid attacks
// using specially crafted parcels.
final RemoteViews presentation = parcel.readParcelable(null);
final Builder builder = (presentation == null)
? new Builder()
: new Builder(presentation);
final ArrayList<AutofillId> ids =
parcel.createTypedArrayList(AutofillId.CREATOR);
final ArrayList<AutofillValue> values =
parcel.createTypedArrayList(AutofillValue.CREATOR);
final ArrayList<RemoteViews> presentations =
parcel.createTypedArrayList(RemoteViews.CREATOR);
final ArrayList<DatasetFieldFilter> filters =
parcel.createTypedArrayList(DatasetFieldFilter.CREATOR);
for (int i = 0; i < ids.size(); i++) {
final AutofillId id = ids.get(i);
final AutofillValue value = values.get(i);
final RemoteViews fieldPresentation = presentations.get(i);
final DatasetFieldFilter filter = filters.get(i);
builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation, filter);
}
builder.setAuthentication(parcel.readParcelable(null));
builder.setId(parcel.readString());
return builder.build();
}
/** @hide */
@Override
@TestApi
@Nullable
public AutofillValue sanitize(@NonNull AutofillValue value) {
if (value == null) {
Slog.w(TAG, "sanitize() called with null value");
return null;
}
if (!value.isText()) {
if (sDebug) Slog.d(TAG, "sanitize() called with non-text value: " + value);
return null;
}
final CharSequence text = value.getTextValue();
try {
final Matcher matcher = mRegex.matcher(text);
if (!matcher.matches()) {
if (sDebug) Slog.d(TAG, "sanitize(): " + mRegex + " failed for " + value);
return null;
}
final CharSequence sanitized = matcher.replaceAll(mSubst);
return AutofillValue.forText(sanitized);
} catch (Exception e) {
Slog.w(TAG, "Exception evaluating " + mRegex + "/" + mSubst + ": " + e);
return null;
}
}
@Override
public AutofillValue getAutofillValue() {
if (!isEnabled()) return null;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getId() == mCheckedId) {
return AutofillValue.forList(i);
}
}
return null;
}
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
setSelection(value.getListValue());
}
@Override
public final AutofillValue getAutofillValue() {
if (mAutofilledValue != 0) {
return AutofillValue.forDate(mAutofilledValue);
}
final Calendar cal = Calendar.getInstance(mLocale);
cal.set(Calendar.HOUR_OF_DAY, getHour());
cal.set(Calendar.MINUTE, getMinute());
return AutofillValue.forDate(cal.getTimeInMillis());
}
@Override
public void autofill(AutofillValue value) {
if (!isEnabled()) return;
if (!value.isToggle()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
return;
}
setChecked(value.getToggleValue());
}
@Override
public final AutofillValue getAutofillValue() {
final long time = mAutofilledValue != 0
? mAutofilledValue
: mCurrentDate.getTimeInMillis();
return AutofillValue.forDate(time);
}