אפליקציות שמשתמשות בתצוגות רגילות פועלות עם מסגרת המילוי האוטומטי בלי צורך בהגדרה מיוחדת. אתם יכולים גם לשפר את האופן שבו האפליקציה פועלת עם ה-framework.
הגדרת סביבת המילוי האוטומטי
בקטע הזה מוסבר איך להגדיר פונקציונליות בסיסית של מילוי אוטומטי באפליקציה.
הגדרת שירות מילוי אוטומטי
כדי שהאפליקציה תשתמש במסגרת המילוי האוטומטי, צריך להגדיר במכשיר שירות מילוי אוטומטי. רוב הטלפונים והטאבלטים עם Android מגרסה 8.0 (רמת API 26) ומעלה כוללים שירות מילוי אוטומטי, אבל אנחנו ממליצים להשתמש בשירות בדיקה כשבודקים את האפליקציה, כמו שירות המילוי האוטומטי בדוגמה למסגרת המילוי האוטומטי של Android. כשמשתמשים באמולטור, צריך להגדיר במפורש שירות מילוי אוטומטי, כי יכול להיות שהאמולטור לא מגיע עם שירות ברירת מחדל.
אחרי שמתקינים את שירות המילוי האוטומטי לבדיקה מהאפליקציה לדוגמה, מפעילים את שירות המילוי האוטומטי: עוברים אל הגדרות > מערכת > שפות וקלט > אפשרויות מתקדמות > סיוע בקלט > שירות מילוי אוטומטי.
מידע נוסף על הגדרת אמולטור לבדיקת המילוי האוטומטי זמין במאמר בדיקת האפליקציה באמצעות מילוי אוטומטי.
שימוש בהקשר של הפעילות בתצוגות
כדי ששירות המילוי האוטומטי יפעל כמו שצריך, נדרש הקשר של הפעילות. כשיוצרים מופע של תצוגה, צריך להשתמש ב-Activity בתור ההקשר כדי שהמילוי האוטומטי יפעל כמו שצריך.
הצגת רמזים למילוי אוטומטי
שירות המילוי האוטומטי קובע את הסוג של כל תצוגה באמצעות היוריסטיקה. עם זאת, אם האפליקציה שלכם מסתמכת על ההיוריסטיקה הזו, יכול להיות שההתנהגות של המילוי האוטומטי תשתנה באופן בלתי צפוי כשתעדכנו את האפליקציה. כדי לוודא ששירות המילוי האוטומטי מזהה בצורה נכונה את גורמי הצורה של האפליקציה, צריך לספק רמזים למילוי אוטומטי.
אפשר להגדיר רמזים למילוי אוטומטי באמצעות המאפיין android:autofillHints. בדוגמה הבאה מוגדרת הנחיה מסוג "password" ב-EditText:
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:autofillHints="password" />
אפשר גם להגדיר רמזים באופן פרוגרמטי באמצעות השיטה setAutofillHints(), כמו בדוגמה הבאה:
Kotlin
val password = findViewById<EditText>(R.id.password)
password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD)
Java
EditText password = findViewById(R.id.password);
password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD);
הכללת קבועים מוגדרים מראש של רמזים
מסגרת המילוי האוטומטי לא מאמתת את ההצעות, אלא מעבירה אותן לשירות המילוי האוטומטי בלי שינוי או אימות. אפשר להשתמש בכל ערך, אבל המחלקות View ו-AndroidX HintConstants מכילות רשימות של קבועים נתמכים רשמית של רמזים.
בעזרת שילוב של הקבועים האלה, אתם יכולים ליצור פריסות לתרחישים נפוצים של מילוי אוטומטי:
פרטי כניסה לחשבון
בטופס התחברות, אפשר לכלול רמזים לפרטי הכניסה לחשבון, כמו AUTOFILL_HINT_USERNAME ו-AUTOFILL_HINT_PASSWORD.
כדי ליצור חשבון חדש, או כשמשתמשים משנים את שם המשתמש והסיסמה שלהם, אתם יכולים להשתמש ב-AUTOFILL_HINT_NEW_USERNAME וב-AUTOFILL_HINT_NEW_PASSWORD.
פרטי כרטיס אשראי
כשמבקשים פרטי כרטיס אשראי, אפשר להשתמש ברמזים כמו
AUTOFILL_HINT_CREDIT_CARD_NUMBER
ו-
AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE.
כדי לעדכן את תאריך התפוגה של כרטיס האשראי, מבצעים אחת מהפעולות הבאות:
- אם אתם משתמשים בתצוגה אחת לתאריך התפוגה, השתמשו ב-
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE. - אם משתמשים בתצוגה שונה לכל חלק של תאריך התפוגה, אפשר להשתמש ב-
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY, ב-AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTHוב-AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEARלכל תצוגה בהתאמה.
כתובת פיזית
בשדות של טופס כתובת פיזית, אפשר להשתמש ברמזים כמו:
- כדי להציג כתובת בתצוגה אחת, משתמשים ב-
AUTOFILL_HINT_POSTAL_ADDRESS. - אם אתם משתמשים בתצוגות נפרדות לחלקים שונים של כתובת, אתם יכולים להשתמש באפשרויות הבאות:
שמות של אנשים
כשמבקשים שמות של אנשים, אפשר להשתמש ברמזים כמו:
- כדי למלא באופן אוטומטי את השם המלא של אדם בתצוגה אחת, משתמשים ב-
AUTOFILL_HINT_PERSON_NAME. - אם אתם משתמשים בתצוגות נפרדות לחלקים שונים של השם, אתם יכולים להשתמש בכל אחת מהאפשרויות הבאות:
מספרי טלפון
במספרי טלפון, אפשר להשתמש בפורמטים הבאים:
- כשמבקשים מספר טלפון מלא בתצוגה אחת, משתמשים ב-
AUTOFILL_HINT_PHONE_NUMBER. - אם אתם משתמשים בתצוגות נפרדות לחלקים שונים של מספר הטלפון, אתם יכולים להשתמש בכל אחת מהאפשרויות הבאות:
סיסמה חד-פעמית (OTP)
כדי להשתמש בסיסמה חד-פעמית בתצוגה אחת, אפשר להשתמש ב-AUTOFILL_HINT_SMS_OTP.
אם יש כמה תצוגות שכל אחת מהן ממפה ספרה אחת של ה-OTP, אפשר להשתמש ב-method generateSmsOtpHintForCharacterPosition() כדי ליצור הצעות לכל תו.
שיוך נתוני אתר ונתוני אפליקציה לנייד
שירותי מילוי אוטומטי, כמו "מילוי אוטומטי של Google", יכולים לשתף את פרטי ההתחברות של המשתמש בין דפדפנים ומכשירי Android אחרי שהאפליקציה והאתר משויכים. כשמשתמש בוחר באותו שירות מילוי אוטומטי בשתי הפלטפורמות, כניסה לאפליקציית האינטרנט שלכם הופכת את פרטי הכניסה שלו לזמינים למילוי אוטומטי כשהוא נכנס לאפליקציית Android התואמת.
כדי לשייך את האפליקציה ל-Android לאתר, צריך לארח באתר Digital Asset Link עם היחס delegate_permission/common.get_login_creds. לאחר מכן, מצהירים על השיוך בקובץ AndroidManifest.xml של האפליקציה. כאן מוסבר איך לשייך את האתר לאפליקציה ל-Android.
השלמת תהליך עבודה של מילוי אוטומטי
בקטע הזה מתוארים תרחישים ספציפיים שבהם אתם יכולים לבצע פעולות כדי לשפר את פונקציונליות המילוי האוטומטי למשתמשים באפליקציה.
איך בודקים אם המילוי האוטומטי מופעל
המשתמשים יכולים להפעיל או להשבית את המילוי האוטומטי וגם לשנות את שירות המילוי האוטומטי. כדי לעשות את זה, הם צריכים לעבור אל הגדרות > מערכת > שפות וקלט > אפשרויות מתקדמות > סיוע בקלט > שירות מילוי אוטומטי. האפליקציה לא יכולה לשנות את הגדרות המילוי האוטומטי של המשתמש, אבל אתם יכולים להטמיע פונקציונליות נוספת של מילוי אוטומטי באפליקציה, או בתצוגות מסוימות של האפליקציה, אם המילוי האוטומטי זמין למשתמש.
לדוגמה, אם המילוי האוטומטי מופעל למשתמש, הערך TextView מציג רשומה של מילוי אוטומטי בתפריט האפשרויות הנוספות. כדי לבדוק אם המילוי האוטומטי מופעל אצל המשתמש, מפעילים את ה-method isEnabled() של האובייקט AutofillManager.
כדי לוודא שחוויית ההרשמה וההתחברות מותאמת למשתמשים שלא משתמשים במילוי אוטומטי, כדאי להטמיע כניסה בלחיצה אחת.
איך לאלץ בקשה למילוי אוטומטי
לפעמים צריך לאלץ בקשת מילוי אוטומטי בתגובה לפעולה של המשתמש. לדוגמה, TextView מציע פריט בתפריט המילוי האוטומטי כשהמשתמש לוחץ לחיצה ארוכה על התצוגה.
בדוגמת הקוד הבאה אפשר לראות איך לאלץ בקשת מילוי אוטומטי:
Kotlin
fun eventHandler(view: View) {
val afm = requireContext().getSystemService(AutofillManager::class.java)
afm?.requestAutofill(view)
}
Java
public void eventHandler(View view) {
AutofillManager afm = context.getSystemService(AutofillManager.class);
if (afm != null) {
afm.requestAutofill(view);
}
}
אפשר גם להשתמש ב-method cancel() כדי לבטל את ההקשר הנוכחי של המילוי האוטומטי. האפשרות הזו יכולה להיות שימושית אם יש לכם לחצן שמנקה את השדות בדף התחברות.
שימוש בסוג המילוי האוטומטי הנכון לנתונים בפקדי בחירה
בוררים יכולים להיות שימושיים במילוי אוטומטי, כי הם מספקים ממשק משתמש שמאפשר למשתמשים לשנות את הערך של שדה שמאחסן נתוני תאריך או שעה. לדוגמה, בטופס של כרטיס אשראי, חלונית לבחירת תאריך מאפשרת למשתמשים להזין או לשנות את תאריך התפוגה של כרטיס האשראי שלהם. עם זאת, צריך להשתמש בתצוגה אחרת, כמו EditText, כדי להציג את הנתונים כשהבורר לא גלוי.
אובייקט EditText מצפה באופן טבעי לנתוני מילוי אוטומטי מסוג AUTOFILL_TYPE_TEXT.
אם אתם משתמשים בסוג אחר של נתונים, צרו תצוגה מותאמת אישית שיורשת מ-EditText ומיישמת את השיטות הנדרשות לטיפול בסוג הנתונים המתאים. לדוגמה, אם יש לכם שדה תאריך, אתם צריכים להטמיע את השיטות עם לוגיקה שמטפלת בצורה נכונה בערכים מסוג AUTOFILL_TYPE_DATE.
כשמציינים את סוג הנתונים למילוי אוטומטי, שירות המילוי האוטומטי יכול ליצור ייצוג מתאים של הנתונים שמוצגים בתצוגה. מידע נוסף זמין במאמר שימוש בבוררים עם מילוי אוטומטי.
סיום ההקשר של המילוי האוטומטי
המסגרת של המילוי האוטומטי שומרת את הקלט של המשתמשים לשימוש עתידי. לשם כך, אחרי שהמילוי האוטומטי מסתיים, מוצגת תיבת הדו-שיח "לשמור למילוי אוטומטי?". בדרך כלל, הקשר המילוי האוטומטי מסתיים כשהפעילות מסתיימת. עם זאת, יש מצבים שבהם צריך להודיע למסגרת באופן מפורש – לדוגמה, אם אתם משתמשים באותו Activity אבל ב-Fragment שונים גם למסך ההתחברות וגם למסך התוכן. במקרים כאלה, אפשר לסיים את ההקשר באופן מפורש על ידי קריאה ל-AutofillManager.commit().
תמיכה בתצוגות בהתאמה אישית
בתצוגות בהתאמה אישית אפשר לציין את המטא-נתונים שחשופים למסגרת המילוי האוטומטי באמצעות ה-API של המילוי האוטומטי. תצוגות מסוימות פועלות כמכל של צאצאים וירטואליים, כמו תצוגות שמכילות ממשק משתמש שעבר רינדור ב-OpenGL. כדי שהתצוגות האלה יוכלו לפעול עם מסגרת המילוי האוטומטי, הן צריכות להשתמש ב-API כדי לציין את מבנה המידע שבו נעשה שימוש באפליקציה.
אם האפליקציה שלכם משתמשת בתצוגות בהתאמה אישית, כדאי לשקול את התרחישים הבאים:
- התצוגה המותאמת אישית מספקת מבנה תצוגה סטנדרטי או מבנה תצוגה שמוגדר כברירת מחדל.
- לתצוגה המותאמת אישית יש מבנה וירטואלי, או מבנה תצוגה שלא זמין למסגרת המילוי האוטומטי.
תצוגות בהתאמה אישית עם מבנה של תצוגה רגילה
תצוגות מותאמות אישית יכולות להגדיר את המטא-נתונים שנדרשים כדי שהמילוי האוטומטי יפעל. חשוב לוודא שהתצוגה בהתאמה אישית מנהלת את המטא-נתונים בצורה שמתאימה למסגרת המילוי האוטומטי. התצוגה בהתאמה אישית צריכה לבצע את הפעולות הבאות:
- מטפלים בערך המילוי האוטומטי שה-framework שולח לאפליקציה.
- מספקים למסגרת את הסוג והערך של המילוי האוטומטי.
כשהמילוי האוטומטי מופעל, מסגרת המילוי האוטומטי קוראת ל-autofill() בתצוגה ושולחת את הערך שבו התצוגה צריכה להשתמש. מטמיעים את autofill() כדי לציין איך התצוגה המותאמת אישית מטפלת בערך המילוי האוטומטי.
התצוגה חייבת לציין סוג וערך של מילוי אוטומטי על ידי שינוי השיטות
getAutofillType()
ו-
getAutofillValue()
בהתאמה.
בנוסף, המילוי האוטומטי לא יכול למלא את התצוגה אם המשתמש לא יכול לספק ערך לתצוגה במצב הנוכחי שלה – לדוגמה, אם התצוגה מושבתת.
במקרים כאלה, getAutofillType() צריך להחזיר את הערך AUTOFILL_TYPE_NONE, getAutofillValue() צריך להחזיר את הערך null, ו-autofill() לא צריך לעשות כלום.
במקרים הבאים נדרשים שלבים נוספים כדי שהמסגרת תפעל כראוי:
- אפשר לערוך את התצוגה המותאמת אישית.
- התצוגה המותאמת אישית מכילה מידע רגיש.
אפשר לערוך את התצוגה המותאמת אישית
אם אפשר לערוך את התצוגה, צריך להודיע למסגרת המילוי האוטומטי על שינויים באמצעות קריאה ל-notifyValueChanged() באובייקט AutofillManager.
התצוגה המותאמת אישית מכילה מידע אישי רגיש
אם תצוגה מכילה פרטים אישיים מזהים (PII) כמו כתובות אימייל, מספרי כרטיסי אשראי וסיסמאות, צריך לסמן אותה כרגישה.
באופן כללי, תצוגות שהתוכן שלהן מגיע ממשאבים סטטיים לא מכילות מידע אישי רגיש, ואילו תצוגות שהתוכן שלהן מוגדר באופן דינמי עשויות להכיל מידע אישי רגיש. לדוגמה, תווית שמכילה את הטקסט הזן את שם המשתמש שלך לא מכילה מידע אישי רגיש, אבל תווית שמכילה את הטקסט שלום, ישראל כן מכילה מידע כזה.
כברירת מחדל, מסגרת המילוי האוטומטי מניחה שכל הנתונים רגישים. אתם יכולים לסמן נתונים שהם לא רגישים.
כדי לסמן אם תצוגה מכילה מידע אישי רגיש, מטמיעים את onProvideAutofillStructure() וקוראים ל-setDataIsSensitive() באובייקט ViewStructure.
הקוד לדוגמה הבא מראה איך לסמן את הנתונים במבנה התצוגה כלא רגישים:
Kotlin
override fun onProvideAutofillStructure(structure: ViewStructure, flags: Int) {
super.onProvideAutofillStructure(structure, flags)
structure.setDataIsSensitive(false)
}
Java
@Override
public void onProvideAutofillStructure(ViewStructure structure, int flags) {
super.onProvideAutofillStructure(structure, flags);
structure.setDataIsSensitive(false);
}
אם תצוגה מקבלת רק ערכים מוגדרים מראש, אתם יכולים להשתמש ב-method setAutofillOptions() כדי להגדיר את האפשרויות שבהן אפשר להשתמש למילוי אוטומטי של התצוגה. במיוחד, תצוגות שסוג המילוי האוטומטי שלהן הוא AUTOFILL_TYPE_LIST חייבות להשתמש בשיטה הזו, כי שירות המילוי האוטומטי יכול לפעול בצורה טובה יותר אם הוא יודע מהן האפשרויות הזמינות למילוי התצוגה.
תצוגות שמשתמשות במתאם, כמו Spinner, הן מקרה דומה. לדוגמה,
ספינר שמספק שנים שנוצרו באופן דינמי, על סמך השנה הנוכחית, לשימוש בשדות של תאריך התפוגה של כרטיס האשראי, יכול להטמיע את השיטה getAutofillOptions() של הממשק Adapter כדי לספק רשימה של שנים.
תצוגות שמשתמשות ב-ArrayAdapter יכולות גם לספק רשימות של ערכים. ArrayAdapter מגדיר באופן אוטומטי אפשרויות מילוי אוטומטי למשאבים סטטיים.
אם אתם מספקים את הערכים באופן דינמי, צריך לשנות את getAutofillOptions().
תצוגות בהתאמה אישית עם מבנה וירטואלי
כדי לערוך ולשמור את המידע בממשק המשתמש של האפליקציה, מסגרת המילוי האוטומטי דורשת מבנה תצוגה. מבנה התצוגה לא זמין ל-framework במצבים הבאים:
- האפליקציה משתמשת במנוע רינדור ברמה נמוכה, כמו OpenGL, כדי לרנדר את ממשק המשתמש.
- האפליקציה משתמשת במופע של
Canvasכדי לצייר את ממשק המשתמש.
במקרים כאלה, אפשר להגדיר מבנה תצוגה על ידי הטמעה של onProvideAutofillVirtualStructure() וביצוע השלבים הבאים:
- מגדילים את מספר הצאצאים של מבנה התצוגה באמצעות קריאה ל-
addChildCount(). - להוסיף ילד או ילדה באמצעות שיחה למספר
newChild(). - מגדירים את מזהה המילוי האוטומטי של הצאצא באמצעות קריאה ל-
setAutofillId(). - מגדירים מאפיינים רלוונטיים, כמו הערך והסוג של המילוי האוטומטי.
- אם הנתונים בצאצא הווירטואלי רגישים, מעבירים את הערך
trueאלsetDataIsSensitive(). אחרת, מעבירים את הערךfalse.
בקטע הקוד הבא מוצג איך ליצור צאצא חדש במבנה הווירטואלי:
Kotlin
override fun onProvideAutofillVirtualStructure(structure: ViewStructure, flags: Int) {
super.onProvideAutofillVirtualStructure(structure, flags)
// Create a new child in the virtual structure.
structure.addChildCount(1)
val child = structure.newChild(childIndex)
// Set the autofill ID for the child.
child.setAutofillId(structure.autofillId!!, childVirtualId)
// Populate the child by providing properties such as value and type.
child.setAutofillValue(childAutofillValue)
child.setAutofillType(childAutofillType)
// Some children can provide a list of values, such as when the child is
// a spinner.
val childAutofillOptions = arrayOf<CharSequence>("option1", "option2")
child.setAutofillOptions(childAutofillOptions)
// Just like other types of views, mark the data as sensitive when
// appropriate.
val sensitive = !contentIsSetFromResources()
child.setDataIsSensitive(sensitive)
}
Java
@Override
public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
super.onProvideAutofillVirtualStructure(structure, flags);
// Create a new child in the virtual structure.
structure.addChildCount(1);
ViewStructure child =
structure.newChild(childIndex);
// Set the autofill ID for the child.
child.setAutofillId(structure.getAutofillId(), childVirtualId);
// Populate the child by providing properties such as value and type.
child.setAutofillValue(childAutofillValue);
child.setAutofillType(childAutofillType);
// Some children can provide a list of values, such as when the child is
// a spinner.
CharSequence childAutofillOptions[] = { "option1", "option2" };
child.setAutofillOptions(childAutofillOptions);
// Just like other types of views, mark the data as sensitive when
// appropriate.
boolean sensitive = !contentIsSetFromResources();
child.setDataIsSensitive(sensitive);
}
כשרכיבים במבנה וירטואלי משתנים, צריך להודיע ל-framework על ידי ביצוע המשימות הבאות:
- אם המיקוד בתוך הצאצאים משתנה, צריך להפעיל את
notifyViewEntered()ואתnotifyViewExited()באובייקטAutofillManager. - אם הערך של צאצא משתנה, צריך להפעיל את
notifyValueChanged()באובייקטAutofillManager. - אם היררכיית התצוגות כבר לא זמינה כי המשתמש השלים שלב בתהליך העבודה, למשל כשהוא נכנס באמצעות טופס כניסה, צריך להפעיל את
commit()באובייקטAutofillManager. - אם היררכיית התצוגות לא תקינה כי המשתמש ביטל שלב בתהליך העבודה, למשל כשהמשתמש לוחץ על כפתור שמנקה טופס התחברות, צריך להפעיל את
cancel()באובייקטAutofillManager.
שימוש בקריאות חוזרות (callbacks) באירועים של מילוי אוטומטי
אם האפליקציה מספקת תצוגות משלה להשלמה אוטומטית, אתם צריכים מנגנון שיורה לאפליקציה להפעיל או להשבית את התצוגות בתגובה לשינויים באפשרות המילוי האוטומטי בממשק המשתמש. מסגרת המילוי האוטומטי מספקת את המנגנון הזה בצורה של AutofillCallback.
המחלקה הזו מספקת את השיטה onAutofillEvent(View, int), שהאפליקציה קוראת לה אחרי שינוי במצב המילוי האוטומטי שמשויך לתצוגה.
יש גם גרסה עמוסה של השיטה הזו שכוללת פרמטר childId שהאפליקציה יכולה להשתמש בו עם תצוגות וירטואליות. המצבים הזמינים מוגדרים כקבועים בקריאה החוזרת (callback).
אפשר לרשום קריאה חוזרת (callback) באמצעות ה-method registerCallback() של המחלקה AutofillManager. בדוגמת הקוד הבאה אפשר לראות איך להצהיר על קריאה חוזרת (callback) לאירועי מילוי אוטומטי:
Kotlin
val afm = context.getSystemService(AutofillManager::class.java)
afm?.registerCallback(object : AutofillManager.AutofillCallback() {
// For virtual structures, override
// onAutofillEvent(View view, int childId, int event) instead.
override fun onAutofillEvent(view: View, event: Int) {
super.onAutofillEvent(view, event)
when (event) {
EVENT_INPUT_HIDDEN -> {
// The autofill affordance associated with the view was hidden.
}
EVENT_INPUT_SHOWN -> {
// The autofill affordance associated with the view was shown.
}
EVENT_INPUT_UNAVAILABLE -> {
// Autofill isn't available.
}
}
}
})
Java
AutofillManager afm = getContext().getSystemService(AutofillManager.class);
afm.registerCallback(new AutofillManager.AutofillCallback() {
// For virtual structures, override
// onAutofillEvent(View view, int childId, int event) instead.
@Override
public void onAutofillEvent(@NonNull View view, int event) {
super.onAutofillEvent(view, event);
switch (event) {
case EVENT_INPUT_HIDDEN:
// The autofill affordance associated with the view was hidden.
break;
case EVENT_INPUT_SHOWN:
// The autofill affordance associated with the view was shown.
break;
case EVENT_INPUT_UNAVAILABLE:
// Autofill isn't available.
break;
}
}
});
כדי להסיר את הקריאה החוזרת, משתמשים ב-method unregisterCallback().
התאמה אישית של הרכיב הגרפי המודגש של המילוי האוטומטי
כשתצוגה מסוימת מתמלאת באופן אוטומטי, הפלטפורמה מעבדת Drawable מעל התצוגה כדי לציין שהתוכן שלה מולא באופן אוטומטי. כברירת מחדל, ה-drawable הזה הוא מלבן בצבע אחיד ושקוף למחצה, שכהה קצת יותר מהצבע של העיצוב שמשמש לציור רקעים. אין צורך לשנות את ה-drawable, אבל אפשר להתאים אותו אישית על ידי שינוי הפריט android:autofilledHighlight של העיצוב שבו משתמשים באפליקציה או בפעילות, כמו בדוגמה הזו:
res/values/styles.xml
<resources>
<style name="MyAutofilledHighlight" parent="...">
<item name="android:autofilledHighlight">@drawable/my_drawable</item>
</style>
</resources>
res/drawable/my_drawable.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#4DFF0000" />
</shape>
AndroidManifest.xml
<application ...
android:theme="@style/MyAutofilledHighlight">
<!-- or -->
<activity ...
android:theme="@style/MyAutofilledHighlight">
אימות למילוי אוטומטי
שירות מילוי אוטומטי יכול לדרוש מהמשתמש לבצע אימות לפני שהשירות יכול למלא שדות באפליקציה. במקרה כזה, מערכת Android מפעילה את פעילות האימות של השירות כחלק מהמחסנית של הפעילות שלכם.
אין צורך לעדכן את האפליקציה כדי לתמוך באימות, כי האימות מתבצע בתוך השירות. עם זאת, צריך לוודא שמבנה התצוגה של הפעילות נשמר כשהפעילות מופעלת מחדש, למשל על ידי יצירת מבנה התצוגה ב-onCreate(), ולא ב-onStart() או ב-onResume().
כדי לבדוק איך האפליקציה מתנהגת כששירות מילוי אוטומטי דורש אימות, אתם יכולים להשתמש ב-HeuristicsService מהדוגמה של AutofillFramework ולהגדיר אותו כך שידרוש אימות של תגובת המילוי. אפשר גם להשתמש בדוגמה BadViewStructureCreationSignInActivity כדי לדמות את הבעיה הזו.
הקצאת מזהי מילוי אוטומטי לתצוגות ממוחזרות
קונטיינרים שממחזרים תצוגות, כמו המחלקה RecyclerView, שימושיים לאפליקציות שצריכות להציג רשימות של רכיבים שאפשר לגלול בהן, על סמך קבוצות נתונים גדולות. כשהמשתמש גולל במאגר, המערכת משתמשת שוב בתצוגות בפריסה, אבל התצוגות מכילות תוכן חדש.
אם התוכן הראשוני של תצוגה ממוחזרת ממולא, שירות המילוי האוטומטי שומר על המשמעות הלוגית של התצוגות באמצעות מזהי המילוי האוטומטי שלהן. הבעיה מתעוררת כשהמערכת עושה שימוש חוזר בתצוגות בפריסה, והמזהים הלוגיים של התצוגות נשארים זהים. כתוצאה מכך, נתוני המשתמש השגויים למילוי אוטומטי משויכים למזהה של המילוי האוטומטי.
כדי לפתור את הבעיה הזו במכשירים עם Android בגרסה 9 (רמת API 28) ומעלה, צריך לנהל באופן מפורש את מזהה המילוי האוטומטי של התצוגות שמשמשות את RecyclerView באמצעות השיטות הבאות:
- ה-method
getNextAutofillId()מקבלת מזהה מילוי אוטומטי חדש שייחודי לפעילות. - השיטה
setAutofillId()מגדירה את המזהה הלוגי הייחודי של המילוי האוטומטי בתצוגה הזו בפעילות.
טיפול בבעיות מוכרות
בקטע הזה מוצגים פתרונות עקיפים לבעיות מוכרות במסגרת המילוי האוטומטי.
המילוי האוטומטי גורם לקריסה של אפליקציות ב-Android 8.0, 8.1
ב-Android 8.0 (רמת API 26) וב-Android 8.1 (רמת API 27), המילוי האוטומטי עלול לגרום לאפליקציה לקרוס בתרחישים מסוימים. כדי לעקוף בעיות פוטנציאליות, תייגו את כל התצוגות שלא מתמלאות באופן אוטומטי באמצעות importantForAutofill=no. אפשר גם לתייג את כל הפעילות באמצעות importantForAutofill=noExcludeDescendants.
תיבות דו-שיח שגודלן השתנה לא נכללות במילוי האוטומטי
ב-Android 8.1 (רמת API 27) ומטה, אם משנים את הגודל של תצוגה בתיבת דו-שיח אחרי שהיא כבר מוצגת, התצוגה לא נכללת במילוי האוטומטי. התצוגות האלה לא נכללות באובייקט AssistStructure שמערכת Android שולחת לשירות המילוי האוטומטי. לכן, השירות לא יכול למלא את התצוגות.
כדי לעקוף את הבעיה, מחליפים את המאפיין token של הפרמטרים של חלון תיבת הדו-שיח במאפיין token של הפעילות שיוצרת את תיבת הדו-שיח. אחרי שמוודאים שהמילוי האוטומטי מופעל, שומרים את הפרמטרים של החלון ב-method onWindowAttributesChanged() של המחלקה שיורשת מ-Dialog. לאחר מכן, מחליפים את המאפיין token של הפרמטרים השמורים במאפיין token של פעילות ההורה ב-method onAttachedToWindow().
בקטע הקוד הבא מוצגת מחלקה שמטמיעה את הפתרון העקיף הזה:
Kotlin
class MyDialog(context: Context) : Dialog(context) {
// Used to store the dialog window parameters.
private var token: IBinder? = null
private val isDialogResizedWorkaroundRequired: Boolean
get() {
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O || Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
return false
}
val autofillManager = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
context.getSystemService(AutofillManager::class.java)
} else {
null
}
return autofillManager?.isEnabled ?: false
}
override fun onWindowAttributesChanged(params: WindowManager.LayoutParams) {
if (params.token == null && token != null) {
params.token = token
}
super.onWindowAttributesChanged(params)
}
override fun onAttachedToWindow() {
if (isDialogResizedWorkaroundRequired) {
token = ownerActivity!!.window.attributes.token
}
super.onAttachedToWindow()
}
}
Java
public class MyDialog extends Dialog {
public MyDialog(Context context) {
super(context);
}
// Used to store the dialog window parameters.
private IBinder token;
@Override
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
if (params.token == null && token != null) {
params.token = token;
}
super.onWindowAttributesChanged(params);
}
@Override
public void onAttachedToWindow() {
if (isDialogResizedWorkaroundRequired()) {
token = getOwnerActivity().getWindow().getAttributes().token;
}
super.onAttachedToWindow();
}
private boolean isDialogResizedWorkaroundRequired() {
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O
|| Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
return false;
}
AutofillManager autofillManager =
null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
autofillManager = getContext().getSystemService(AutofillManager.class);
}
return autofillManager != null && autofillManager.isEnabled();
}
}
כדי להימנע מפעולות מיותרות, בקטע הקוד הבא אפשר לראות איך לבדוק אם המכשיר תומך במילוי אוטומטי, אם הוא מופעל אצל המשתמש הנוכחי ואם הפתרון הזה נדרש:
Kotlin
// AutofillExtensions.kt
fun Context.isDialogResizedWorkaroundRequired(): Boolean {
// After the issue is resolved on Android, check whether the
// workaround is still required for the current device.
return isAutofillAvailable()
}
fun Context.isAutofillAvailable(): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
// The autofill framework is available on Android 8.0
// or higher.
return false
}
val afm = getSystemService(AutofillManager::class.java)
// Return true if autofill is supported by the device and enabled
// for the current user.
return afm != null && afm.isEnabled
}
Java
public class AutofillHelper {
public static boolean isDialogResizedWorkaroundRequired(Context context) {
// After the issue is resolved on Android, check whether the
// workaround is still required for the current device.
return isAutofillAvailable(context);
}
public static boolean isAutofillAvailable(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
// The autofill framework is available on Android 8.0
// or higher.
return false;
}
AutofillManager afm = context.getSystemService(AutofillManager.class);
// Return true if autofill is supported by the device and enabled
// for the current user.
return afm != null && afm.isEnabled();
}
}
בדיקת האפליקציה עם מילוי אוטומטי
אחרי שמבצעים אופטימיזציה של האפליקציה לעבודה עם שירותי מילוי אוטומטי, בודקים אם היא פועלת כמצופה עם שירותי מילוי אוטומטי.
כדי לבדוק את האפליקציה, משתמשים באמולטור או במכשיר פיזי עם Android בגרסה 8.0 (רמת API 26) ומעלה. מידע נוסף על יצירת אמולטור זמין במאמר יצירה וניהול של מכשירים וירטואליים.
התקנת שירות מילוי אוטומטי
כדי לבדוק את האפליקציה עם מילוי אוטומטי, צריך להתקין אפליקציה אחרת שמספקת שירותי מילוי אוטומטי. אפשר להשתמש באפליקציה של צד שלישי למטרה הזו, אבל קל יותר להשתמש בשירות מילוי אוטומטי לדוגמה כדי שלא תצטרכו להירשם לשירותים של צד שלישי.
אתם יכולים להשתמש בדוגמה של מסגרת המילוי האוטומטי של Android ב-Java כדי לבדוק את האפליקציה שלכם עם שירותי מילוי אוטומטי. האפליקציה לדוגמה מספקת שירות מילוי אוטומטי ומחלקות לקוח של Activity, שבהן אתם יכולים להשתמש כדי לבדוק את תהליך העבודה לפני שאתם משתמשים בו באפליקציה שלכם. הדף הזה מתייחס לאפליקציה לדוגמה android-AutofillFramework.
אחרי שמתקינים את האפליקציה, מפעילים את שירות המילוי האוטומטי בהגדרות המערכת של האמולטור. כדי לעשות את זה, עוברים אל הגדרות > מערכת > שפות וקלט > אפשרויות מתקדמות > עזרה בקלט > שירות מילוי אוטומטי.
ניתוח דרישות הנתונים
כדי לבדוק את האפליקציה עם שירות המילוי האוטומטי, השירות צריך לכלול נתונים שבהם הוא יכול להשתמש כדי למלא את האפליקציה. השירות גם צריך להבין איזה סוג נתונים צפוי בתצוגות של האפליקציה. לדוגמה, אם באפליקציה יש תצוגה שצפויה לכלול שם משתמש, השירות צריך לכלול קבוצת נתונים שמכילה שם משתמש ומנגנון כלשהו כדי לדעת שהתצוגה צפויה לכלול נתונים כאלה.
כדי להגדיר את סוג הנתונים שהשירות מצפה לקבל בתצוגות, מגדירים את המאפיין android:autofillHints. בחלק מהשירותים נעשה שימוש ביוריסטיקה מתוחכמת כדי לקבוע את סוג הנתונים, אבל בשירותים אחרים, כמו האפליקציה לדוגמה, המפתחים צריכים לספק את המידע הזה. האפליקציה פועלת טוב יותר עם שירותי מילוי אוטומטי אם מגדירים את המאפיין android:autofillHints בתצוגות שרלוונטיות למילוי אוטומטי.
הרצת הבדיקה
אחרי שתנתחו את דרישות הנתונים, תוכלו להריץ את הבדיקה, שכוללת שמירת נתוני בדיקה בשירות המילוי האוטומטי והפעלת המילוי האוטומטי באפליקציה.
שמירת נתונים בשירות
כדי לשמור נתונים בשירות המילוי האוטומטי שפעיל כרגע:
- פותחים אפליקציה שמכילה תצוגה שמתאימה לסוג הנתונים שרוצים להשתמש בהם במהלך הבדיקה. האפליקציה לדוגמה android-AutofillFramework מספקת לממשק המשתמש תצוגות שמצפות לכמה סוגים של נתונים, כמו מספרי כרטיסי אשראי ושמות משתמשים.
- לוחצים על התצוגה שכוללת את סוג הנתונים שצריך.
- מזינים ערך בתצוגה.
- לוחצים על כפתור האישור, למשל כניסה או שליחה. בדרך כלל צריך לשלוח את הטופס כדי שהשירות ישמור את הנתונים.
- מאשרים את בקשת ההרשאה בתיבת הדו-שיח של המערכת. בתיבת הדו-שיח של המערכת מוצג שם השירות שפעיל כרגע, ומופיעה שאלה אם זה השירות שבו אתם רוצים להשתמש בבדיקה. אם רוצים להשתמש בשירות, לוחצים על שמירה.
אם תיבת הדו-שיח של ההרשאה לא מופיעה ב-Android, או אם השירות הוא לא השירות שבו אתם רוצים להשתמש בבדיקה, ודאו שהשירות פעיל כרגע בהגדרות המערכת.
הפעלת המילוי האוטומטי באפליקציה
כדי להפעיל את המילוי האוטומטי באפליקציה:
- פותחים את האפליקציה ועוברים לפעילות שכוללת את התצוגות שרוצים לבדוק.
- לוחצים על התצוגה שצריך למלא.
- המערכת מציגה את ממשק המשתמש של המילוי האוטומטי, שמכיל את מערכי הנתונים שיכולים למלא את התצוגה, כמו שמוצג באיור 1.
- לוחצים על קבוצת הנתונים שמכילה את הנתונים שבהם רוצים להשתמש. בתצוגה מוצגים הנתונים שאוחסנו בעבר בשירות.
אם ממשק המשתמש של המילוי האוטומטי לא מופיע ב-Android, אתם יכולים לנסות את האפשרויות הבאות לפתרון בעיות:
- מוודאים שהתצוגות באפליקציה משתמשות בערך הנכון במאפיין
android:autofillHints. רשימה של ערכים אפשריים למאפיין מופיעה בקבועים עם הקידומתAUTOFILL_HINTבמחלקהView. - צריך לוודא שהמאפיין
android:importantForAutofillמוגדר לערך שאינוnoבתצוגה שצריך למלא, או מוגדר לערך שאינוnoExcludeDescendantsבתצוגה או באחד מההורים שלה.