برنامههایی که از نماهای استاندارد استفاده میکنند، بدون نیاز به پیکربندی خاصی با چارچوب تکمیل خودکار کار میکنند. همچنین میتوانید نحوه عملکرد برنامه خود را با این چارچوب بهینه کنید.
محیط تکمیل خودکار را تنظیم کنید
این بخش نحوه تنظیم قابلیت تکمیل خودکار اولیه برای برنامه شما را شرح میدهد.
پیکربندی سرویس تکمیل خودکار
برای اینکه برنامه شما بتواند از چارچوب تکمیل خودکار استفاده کند، باید یک سرویس تکمیل خودکار روی دستگاه شما پیکربندی شود. اگرچه اکثر تلفنها و تبلتهایی که اندروید ۸.۰ (سطح API ۲۶) و بالاتر را اجرا میکنند، با یک سرویس تکمیل خودکار عرضه میشوند، اما توصیه میکنیم هنگام آزمایش برنامه خود از یک سرویس آزمایشی، مانند سرویس تکمیل خودکار در نمونه چارچوب تکمیل خودکار اندروید ، استفاده کنید. هنگام استفاده از یک شبیهساز، سرویس تکمیل خودکار را به صراحت تنظیم کنید، زیرا ممکن است شبیهساز با یک سرویس پیشفرض ارائه نشود.
پس از نصب سرویس تکمیل خودکار آزمایشی از برنامه نمونه، با رفتن به تنظیمات > سیستم > زبانها و ورودی > پیشرفته > کمک ورودی > سرویس تکمیل خودکار ، آن را فعال کنید.
برای اطلاعات بیشتر در مورد پیکربندی یک شبیهساز برای آزمایش تکمیل خودکار، به بخش «برنامه خود را با تکمیل خودکار آزمایش کنید» مراجعه کنید.
استفاده از Activity Context برای نماها
سرویس تکمیل خودکار برای عملکرد صحیح به Activity Context نیاز دارد. هنگام نمونهسازی یک نما، از Activity به عنوان context استفاده کنید تا بتواند به درستی به صورت خودکار تکمیل شود.
ارائه نکات برای تکمیل خودکار
سرویس تکمیل خودکار نوع هر نما را با استفاده از روشهای اکتشافی تعیین میکند. با این حال، اگر برنامه شما به این روشهای اکتشافی متکی باشد، ممکن است با بهروزرسانی برنامه، رفتار تکمیل خودکار بهطور غیرمنتظرهای تغییر کند. برای اطمینان از اینکه سرویس تکمیل خودکار، فرمفکتورهای برنامه شما را به درستی شناسایی میکند، نکات تکمیل خودکار را ارائه دهید.
شما میتوانید با استفاده از ویژگی android:autofillHints نکات مربوط به تکمیل خودکار را تنظیم کنید. مثال زیر یک نکته برای "password" روی EditText تنظیم میکند:
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:autofillHints="password" />
همچنین میتوانید با استفاده از متد setAutofillHints() به صورت برنامهنویسی شده، همانطور که در مثال زیر نشان داده شده است، نکات (hints) را تنظیم کنید:
کاتلین
val password = findViewById<EditText>(R.id.password) password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD)
جاوا
EditText password = findViewById(R.id.password); password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD);
ثابتهای راهنمایی از پیش تعریفشده را لحاظ کنید
چارچوب تکمیل خودکار، نکات (hints) را اعتبارسنجی نمیکند؛ آنها بدون تغییر یا اعتبارسنجی به سرویس تکمیل خودکار ارسال میشوند. در حالی که میتوانید از هر مقداری استفاده کنید، کلاسهای 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 نگاشت میشود، میتوانید از متد generateSmsOtpHintForCharacterPosition() برای تولید راهنماهای هر کاراکتر استفاده کنید.
دادههای وبسایت و اپلیکیشن موبایل را به هم مرتبط کنید
سرویسهای تکمیل خودکار مانند Autofill with Google میتوانند دادههای ورود کاربر را پس از مرتبط شدن برنامه و وبسایت، بین مرورگرها و دستگاههای اندروید به اشتراک بگذارند. وقتی کاربری سرویس تکمیل خودکار یکسانی را در هر دو پلتفرم انتخاب میکند، ورود به برنامه وب شما، اطلاعات ورود او را برای تکمیل خودکار هنگام ورود به برنامه اندروید مربوطه در دسترس قرار میدهد.
برای مرتبط کردن برنامه اندروید خود با وبسایتتان، یک پیوند دارایی دیجیتال با رابطه delegate_permission/common.get_login_creds در سایت خود میزبانی کنید. سپس، این ارتباط را در فایل AndroidManifest.xml برنامه خود اعلام کنید. برای دستورالعملهای دقیق در مورد نحوه مرتبط کردن وبسایت خود با برنامه اندروید، به بخش «فعال کردن ورود خودکار در برنامهها و وبسایتها» مراجعه کنید.
تکمیل گردش کار تکمیل خودکار
این بخش سناریوهای خاصی را شرح میدهد که در آنها میتوانید اقداماتی را برای بهبود عملکرد تکمیل خودکار برای کاربران برنامه خود انجام دهید.
تعیین اینکه آیا تکمیل خودکار فعال است یا خیر
کاربران میتوانند با رفتن به تنظیمات > سیستم > زبانها و ورودی > پیشرفته > کمک ورودی > سرویس تکمیل خودکار ، تکمیل خودکار را فعال یا غیرفعال کنند و همچنین سرویس تکمیل خودکار را تغییر دهند. برنامه شما نمیتواند تنظیمات تکمیل خودکار کاربر را لغو کند، اما میتوانید در صورت امکان تکمیل خودکار برای کاربر، قابلیتهای تکمیل خودکار اضافی را در برنامه خود یا به ویژه نماهای برنامه خود پیادهسازی کنید.
برای مثال، TextView در صورتی که قابلیت تکمیل خودکار برای کاربر فعال باشد، یک ورودی تکمیل خودکار را در منوی سرریز نشان میدهد. برای بررسی اینکه آیا تکمیل خودکار برای کاربر فعال است یا خیر، متد isEnabled() از شیء AutofillManager را فراخوانی کنید.
برای اطمینان از اینکه تجربه ثبت نام و ورود شما بدون تکمیل خودکار برای کاربران بهینه شده است، ورود با یک لمس (One Tap sign-in) را پیادهسازی کنید.
درخواست تکمیل خودکار را اجباری کنید
گاهی اوقات لازم است که در پاسخ به یک اقدام کاربر، درخواست تکمیل خودکار را اجباری کنید. برای مثال، TextView وقتی کاربر روی نما لمس کرده و نگه میدارد، یک آیتم منوی تکمیل خودکار ارائه میدهد. مثال کد زیر نحوهی اجباری کردن درخواست تکمیل خودکار را نشان میدهد:
کاتلین
fun eventHandler(view: View) { val afm = requireContext().getSystemService(AutofillManager::class.java) afm?.requestAutofill(view) }
جاوا
public void eventHandler(View view) { AutofillManager afm = context.getSystemService(AutofillManager.class); if (afm != null) { afm.requestAutofill(view); } }
همچنین میتوانید از متد cancel() برای لغو زمینه تکمیل خودکار فعلی استفاده کنید. این میتواند در صورتی مفید باشد که دکمهای داشته باشید که فیلدهای صفحه ورود را پاک کند.
از نوع تکمیل خودکار صحیح برای دادهها در کنترلهای انتخابگر استفاده کنید
انتخابگرها میتوانند با ارائه یک رابط کاربری که به کاربران اجازه میدهد مقدار فیلدی را که دادههای تاریخ یا زمان را ذخیره میکند، تغییر دهند، در تکمیل خودکار مفید باشند. به عنوان مثال، در فرم کارت اعتباری، انتخابگر تاریخ به کاربران اجازه میدهد تاریخ انقضای کارت اعتباری خود را وارد یا تغییر دهند. با این حال، شما باید از نمای دیگری مانند EditText برای نمایش دادهها در زمانی که انتخابگر قابل مشاهده نیست، استفاده کنید.
یک شیء EditText به طور طبیعی انتظار دادههای تکمیل خودکار از نوع AUTOFILL_TYPE_TEXT را دارد. اگر از نوع داده متفاوتی استفاده میکنید، یک نمای سفارشی ایجاد کنید که از EditText ارثبری کند و متدهای مورد نیاز برای مدیریت نوع داده مربوطه را پیادهسازی کند. به عنوان مثال، اگر یک فیلد تاریخ دارید، متدها را با منطقی پیادهسازی کنید که به درستی مقادیر نوع AUTOFILL_TYPE_DATE را مدیریت کند.
وقتی نوع داده autofill را مشخص میکنید، سرویس autofill میتواند نمایش مناسبی از دادههای نمایش داده شده در view ایجاد کند. برای اطلاعات بیشتر، به بخش «استفاده از انتخابگرها با autofill» مراجعه کنید.
زمینه تکمیل خودکار را تکمیل کنید
چارچوب تکمیل خودکار، ورودی کاربر را برای استفادههای بعدی با نمایش کادر محاورهای «ذخیره برای تکمیل خودکار؟» پس از اتمام تکمیل خودکار، ذخیره میکند. معمولاً، تکمیل خودکار با پایان یافتن یک فعالیت به پایان میرسد. با این حال، موقعیتهایی وجود دارد که باید صریحاً به چارچوب اطلاع دهید - برای مثال، اگر از یک فعالیت مشابه اما قطعات مختلف برای هر دو صفحه ورود و محتوا استفاده میکنید. در این موقعیتها، میتوانید با فراخوانی AutofillManager.commit() به طور صریح زمینه را تکمیل کنید.
پشتیبانی از نماهای سفارشی
نماهای سفارشی میتوانند با استفاده از API مربوط به تکمیل خودکار، متادیتایی را که در معرض چارچوب تکمیل خودکار قرار میگیرد، مشخص کنند. برخی از نماها به عنوان ظرفی از فرزندان مجازی عمل میکنند، مانند نماهایی که حاوی رابط کاربری رندر شده توسط OpenGL هستند. این نماها قبل از اینکه بتوانند با چارچوب تکمیل خودکار کار کنند، باید از API برای مشخص کردن ساختار اطلاعات مورد استفاده در برنامه استفاده کنند.
اگر برنامه شما از نماهای سفارشی استفاده میکند، سناریوهای زیر را در نظر بگیرید:
- نمای سفارشی یک ساختار نمای استاندارد یا یک ساختار نمای پیشفرض ارائه میدهد.
- نمای سفارشی دارای یک ساختار مجازی یا ساختار نمایی است که برای چارچوب تکمیل خودکار در دسترس نیست.
نماهای سفارشی با ساختار نمای استاندارد
نماهای سفارشی میتوانند متادیتایی را که تکمیل خودکار برای کار به آنها نیاز دارد، تعریف کنند. مطمئن شوید که نمای سفارشی شما، متادیتا را به طور مناسب مدیریت میکند تا با چارچوب تکمیل خودکار کار کند. نمای سفارشی شما باید اقدامات زیر را انجام دهد:
- مقدار تکمیل خودکاری که فریمورک به برنامه شما ارسال میکند را مدیریت کنید.
- نوع و مقدار تکمیل خودکار را به چارچوب ارائه دهید.
وقتی autofill فعال میشود، فریمورک autofill تابع autofill() را روی view شما فراخوانی میکند و مقداری را که view شما باید استفاده کند، ارسال میکند. autofill() را برای مشخص کردن نحوه مدیریت مقدار autofill توسط view سفارشی خود پیادهسازی کنید.
نمای شما باید با بازنویسی (override) متدهای getAutofillType() و getAutofillValue() به ترتیب، نوع و مقدار autofill را مشخص کند.
در نهایت، اگر کاربر نتواند مقداری برای نما در وضعیت فعلی آن ارائه دهد - مثلاً اگر نما غیرفعال باشد - تابع autofill نباید نما را پر کند. در این موارد، getAutofillType() باید AUTOFILL_TYPE_NONE را برگرداند، getAutofillValue() باید null را برگرداند و autofill() نباید هیچ کاری انجام دهد.
موارد زیر برای عملکرد صحیح در چارچوب، به مراحل اضافی نیاز دارند:
- نمای سفارشی قابل ویرایش است.
- نمای سفارشی حاوی دادههای حساس است.
نمای سفارشی قابل ویرایش است
اگر نما قابل ویرایش است، با فراخوانی notifyValueChanged() روی شیء AutofillManager ، فریمورک autofill را از تغییرات مطلع کنید.
نمای سفارشی حاوی دادههای حساس است
اگر یک دیدگاه حاوی اطلاعات شخصی قابل شناسایی (PII) مانند آدرسهای ایمیل، شماره کارتهای اعتباری و رمزهای عبور باشد، باید به عنوان حساس علامتگذاری شود.
به طور کلی، نماهایی که محتوای آنها از منابع استاتیک میآید، حاوی دادههای حساس نیستند، در حالی که نماهایی که محتوای آنها به صورت پویا تنظیم میشود، ممکن است حاوی دادههای حساس باشند. برای مثال، برچسبی که حاوی عبارت «نام کاربری خود را وارد کنید» است، حاوی دادههای حساس نیست، در حالی که برچسبی که حاوی عبارت «سلام، جان» است، این کار را انجام میدهد.
چارچوب تکمیل خودکار فرض میکند که همه دادهها به طور پیشفرض حساس هستند. میتوانید دادههایی را که حساس نیستند، علامتگذاری کنید.
برای مشخص کردن اینکه آیا یک نما حاوی دادههای حساس است یا خیر، onProvideAutofillStructure() را پیادهسازی کرده و setDataIsSensitive() را روی شیء ViewStructure فراخوانی کنید.
مثال کد زیر نحوه علامتگذاری دادهها در ساختار view به عنوان غیر حساس را نشان میدهد:
کاتلین
override fun onProvideAutofillStructure(structure: ViewStructure, flags: Int) { super.onProvideAutofillStructure(structure, flags) structure.setDataIsSensitive(false) }
جاوا
@Override public void onProvideAutofillStructure(ViewStructure structure, int flags) { super.onProvideAutofillStructure(structure, flags); structure.setDataIsSensitive(false); }
اگر یک نما فقط مقادیر از پیش تعریف شده را میپذیرد، میتوانید از متد setAutofillOptions() برای تنظیم گزینههایی که میتوانند برای پر کردن خودکار نما استفاده شوند، استفاده کنید. به طور خاص، نماهایی که نوع پر کردن خودکار آنها AUTOFILL_TYPE_LIST است، باید از این متد استفاده کنند، زیرا سرویس پر کردن خودکار اگر گزینههای موجود برای پر کردن نما را بداند، میتواند کار خود را بهتر انجام دهد.
ویوهایی که از یک آداپتور، مانند Spinner ، استفاده میکنند، مورد مشابهی هستند. برای مثال، یک Spinner که سالهای ایجاد شده پویا را بر اساس سال جاری، برای استفاده در فیلدهای انقضای کارت اعتباری ارائه میدهد، میتواند متد getAutofillOptions() از رابط Adapter را برای ارائه لیستی از سالها پیادهسازی کند.
ویوهایی که از ArrayAdapter استفاده میکنند، میتوانند فهرستهایی از مقادیر را نیز ارائه دهند. ArrayAdapter به طور خودکار گزینههای تکمیل خودکار را برای منابع استاتیک تنظیم میکند. اگر مقادیر را به صورت پویا ارائه میدهید، getAutofillOptions() نادیده بگیرید.
نماهای سفارشی با ساختار مجازی
چارچوب تکمیل خودکار قبل از اینکه بتواند اطلاعات را در رابط کاربری برنامه شما ویرایش و ذخیره کند، به یک ساختار نمایش (view) نیاز دارد. این ساختار نمایش در شرایط زیر برای چارچوب در دسترس نیست:
- این برنامه از یک موتور رندر سطح پایین مانند OpenGL برای رندر رابط کاربری استفاده میکند.
- این برنامه از نمونهای از
Canvasبرای ترسیم رابط کاربری استفاده میکند.
در این موارد، میتوانید با پیادهسازی onProvideAutofillVirtualStructure() و دنبال کردن مراحل زیر، ساختار نما را مشخص کنید:
- با فراخوانی تابع
addChildCount()، تعداد فرزندهای ساختار ویو را افزایش دهید. - با فراخوانی تابع
newChild()یک فرزند اضافه کنید. - با فراخوانی تابع
setAutofillId()شناسه تکمیل خودکار را برای فرزند تنظیم کنید. - ویژگیهای مربوطه، مانند مقدار و نوع تکمیل خودکار را تنظیم کنید.
- اگر دادههای موجود در فرزند مجازی حساس هستند، مقدار
trueبهsetDataIsSensitive()ارسال کنید؛ در غیر این صورت، مقدارfalseارسال کنید.
قطعه کد زیر نحوه ایجاد یک فرزند جدید در ساختار مجازی را نشان میدهد:
کاتلین
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) }
جاوا
@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); }
وقتی عناصر یک ساختار مجازی تغییر میکنند، با انجام وظایف زیر به چارچوب اطلاع دهید:
- اگر تمرکز درون فرزندان تغییر کند، متدهای
notifyViewEntered()وnotifyViewExited()را روی شیءAutofillManagerفراخوانی کنید. - اگر مقدار یک فرزند تغییر کند،
notifyValueChanged()را روی شیءAutofillManagerفراخوانی کنید. - اگر سلسله مراتب نماها دیگر در دسترس نیست زیرا کاربر یک مرحله از گردش کار را انجام داده است، مانند زمانی که با استفاده از فرم ورود به سیستم وارد سیستم میشود،
commit()روی شیءAutofillManagerفراخوانی کنید. - اگر سلسله مراتب نما به دلیل لغو یک مرحله در گردش کار توسط کاربر معتبر نیست، مانند زمانی که کاربر روی دکمهای که فرم ورود را پاک میکند، ضربه میزند، تابع
cancel()روی شیءAutofillManagerفراخوانی کنید.
استفاده از فراخوانیهای برگشتی در رویدادهای تکمیل خودکار
اگر برنامه شما نماهای تکمیل خودکار مخصوص به خود را ارائه میدهد، به مکانیزمی نیاز دارید که به برنامه بگوید نماها را در پاسخ به تغییرات در قابلیت تکمیل خودکار رابط کاربری فعال یا غیرفعال کند. فریمورک تکمیل خودکار این مکانیزم را در قالب AutofillCallback ارائه میدهد.
این کلاس متد onAutofillEvent(View, int) را ارائه میدهد که برنامه پس از تغییر در وضعیت تکمیل خودکار مرتبط با یک نما، آن را فراخوانی میکند. همچنین یک نسخه بارگذاریشده از این متد وجود دارد که شامل یک پارامتر childId است که برنامه شما میتواند با نماهای مجازی از آن استفاده کند. وضعیتهای موجود به عنوان ثابت در فراخوانی برگشتی تعریف میشوند.
شما میتوانید با استفاده از متد registerCallback() از کلاس AutofillManager یک callback ثبت کنید. مثال کد زیر نحوهی تعریف یک callback برای رویدادهای autofill را نشان میدهد:
کاتلین
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. } } } })
جاوا
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; } } });
وقتی زمان حذف تابع برگشتی رسید، از متد unregisterCallback() استفاده کنید.
سفارشیسازی قابلیت تکمیل خودکار هایلایتشده
وقتی یک نما به صورت خودکار پر میشود، پلتفرم یک Drawable روی نما رندر میکند تا نشان دهد که محتوای نما به صورت خودکار پر شده است. به طور پیشفرض، این drawable یک مستطیل توپر با رنگ شفاف است که کمی تیرهتر از رنگ تم مورد استفاده برای رسم پسزمینهها است. drawable نیازی به تغییر ندارد، اما میتوان آن را با بازنویسی آیتم android:autofilledHighlight از تم مورد استفاده توسط برنامه یا activity، همانطور که در این مثال نشان داده شده است، سفارشی کرد:
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">
برای تکمیل خودکار، احراز هویت کنید
یک سرویس تکمیل خودکار میتواند قبل از اینکه سرویس بتواند فیلدهای برنامه شما را تکمیل کند، از کاربر بخواهد که احراز هویت کند، که در این صورت سیستم اندروید، اکتیویتی احراز هویت سرویس را به عنوان بخشی از پشته اکتیویتی شما اجرا میکند.
لازم نیست برنامه خود را برای پشتیبانی از احراز هویت بهروزرسانی کنید، زیرا احراز هویت درون سرویس اتفاق میافتد. با این حال، باید مطمئن شوید که ساختار نمای اکتیویتی هنگام راهاندازی مجدد اکتیویتی حفظ میشود، مثلاً با ایجاد ساختار نما در onCreate() ، نه در onStart() یا onResume() .
شما میتوانید با استفاده از HeuristicsService از نمونه AutofillFramework و پیکربندی آن برای نیاز به احراز هویت در پاسخ به پر کردن، نحوه رفتار برنامه خود را هنگامی که یک سرویس تکمیل خودکار نیاز به احراز هویت دارد، بررسی کنید. همچنین میتوانید از نمونه BadViewStructureCreationSignInActivity برای شبیهسازی این مشکل استفاده کنید.
اختصاص شناسههای تکمیل خودکار به نماهای بازیافتی
کانتینرهایی که نماها را بازیافت میکنند، مانند کلاس RecyclerView ، برای برنامههایی که نیاز به نمایش لیستهای پیمایشی از عناصر بر اساس مجموعه دادههای بزرگ دارند، مفید هستند. با پیمایش کانتینر، سیستم از نماها در طرحبندی استفاده مجدد میکند، اما نماها سپس حاوی محتوای جدید میشوند.
اگر محتوای اولیه یک نمای بازیافتی پر شود، سرویس تکمیل خودکار معنای منطقی نماها را با استفاده از شناسههای تکمیل خودکار آنها حفظ میکند. مشکل زمانی ایجاد میشود که با استفاده مجدد سیستم از نماها در طرحبندی، شناسههای منطقی نماها ثابت میمانند و باعث میشود دادههای کاربر تکمیل خودکار اشتباه با شناسه تکمیل خودکار مرتبط شوند.
برای حل این مشکل در دستگاههایی که اندروید ۹ (سطح API 28) و بالاتر را اجرا میکنند، با استفاده از این روشها، شناسه تکمیل خودکار نماهایی را که توسط RecyclerView استفاده میشوند، به صراحت مدیریت کنید:
- متد
getNextAutofillId()یک شناسهی تکمیل خودکار جدید دریافت میکند که مختص به اکتیویتی است. - متد
setAutofillId()شناسهی منحصر به فرد و منطقیِ تکمیل خودکارِ این view در activity را تنظیم میکند.
رسیدگی به مشکلات شناخته شده
این بخش راهحلهایی برای مشکلات شناختهشده در چارچوب تکمیل خودکار ارائه میدهد.
تکمیل خودکار باعث خرابی برنامهها در اندروید ۸.۰ و ۸.۱ میشود
در اندروید ۸.۰ (سطح API ۲۶) و ۸.۱ (سطح API ۲۷)، تکمیل خودکار میتواند در برخی سناریوها باعث از کار افتادن برنامه شما شود. برای حل مشکلات احتمالی، هر ویو (view) که به صورت خودکار پر نمیشود را با importantForAutofill=no برچسبگذاری کنید. همچنین میتوانید کل اکتیویتی را با importantForAutofill=noExcludeDescendants برچسبگذاری کنید.
کادرهای محاورهای تغییر اندازه داده شده برای تکمیل خودکار در نظر گرفته نمیشوند
در اندروید ۸.۱ (سطح API ۲۷) و پایینتر، اگر یک نمای (view) در یک کادر محاورهای پس از نمایش، تغییر اندازه دهد، آن نما برای تکمیل خودکار در نظر گرفته نمیشود. این نماها در شیء AssistStructure که سیستم اندروید به سرویس تکمیل خودکار ارسال میکند، گنجانده نشدهاند. در نتیجه، سرویس نمیتواند نماها را پر کند.
برای حل این مشکل، ویژگی token پارامترهای پنجرهی محاورهای را با ویژگی token اکتیویتی که دیالوگ را ایجاد میکند، جایگزین کنید. پس از تأیید فعال بودن قابلیت تکمیل خودکار، پارامترهای پنجره را در متد onWindowAttributesChanged() از کلاسی که از Dialog ارثبری میکند، ذخیره کنید. سپس، ویژگی token پارامترهای ذخیره شده را با ویژگی token اکتیویتی والد در متد onAttachedToWindow() جایگزین کنید.
قطعه کد زیر کلاسی را نشان میدهد که این راهحل را پیادهسازی میکند:
کاتلین
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() } }
جاوا
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(); } }
برای جلوگیری از عملیات غیرضروری، قطعه کد زیر نحوه بررسی پشتیبانی از تکمیل خودکار فرم در دستگاه و فعال بودن آن برای کاربر فعلی و همچنین لزوم استفاده از این راهکار را نشان میدهد:
کاتلین
// 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 }
جاوا
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(); } }
برنامه خود را با قابلیت تکمیل خودکار (autofill) آزمایش کنید
پس از اینکه برنامه خود را برای کار با سرویسهای تکمیل خودکار بهینه کردید، آزمایش کنید که آیا با سرویسهای تکمیل خودکار مطابق انتظار کار میکند یا خیر.
برای تست برنامه خود از یک شبیهساز یا یک دستگاه فیزیکی که اندروید ۸.۰ (سطح API 26) یا بالاتر را اجرا میکند، استفاده کنید. برای اطلاعات بیشتر در مورد نحوه ایجاد یک شبیهساز، به بخش ایجاد و مدیریت دستگاههای مجازی مراجعه کنید.
یک سرویس تکمیل خودکار نصب کنید
قبل از اینکه بتوانید برنامه خود را با قابلیت تکمیل خودکار (autofill) آزمایش کنید، باید برنامه دیگری را که خدمات تکمیل خودکار ارائه میدهد، نصب کنید. میتوانید برای این منظور از یک برنامه شخص ثالث استفاده کنید، اما استفاده از یک سرویس تکمیل خودکار نمونه آسانتر است تا نیازی به ثبت نام در سرویسهای شخص ثالث نداشته باشید.
شما میتوانید از نمونه چارچوب تکمیل خودکار اندروید در جاوا برای آزمایش برنامه خود با سرویسهای تکمیل خودکار استفاده کنید. این برنامه نمونه، یک سرویس تکمیل خودکار و کلاسهای Activity کلاینت را ارائه میدهد که میتوانید قبل از استفاده از آن در برنامه خود، برای آزمایش گردش کار از آنها استفاده کنید. این صفحه به برنامه نمونه android-AutofillFramework ارجاع میدهد.
پس از نصب برنامه، سرویس تکمیل خودکار را در تنظیمات سیستم شبیهساز با رفتن به تنظیمات > سیستم > زبانها و ورودی > پیشرفته > کمک ورودی > سرویس تکمیل خودکار فعال کنید.
تجزیه و تحلیل الزامات دادهها
برای آزمایش برنامه خود با سرویس تکمیل خودکار، سرویس باید دادههایی داشته باشد که بتواند از آنها برای پر کردن برنامه شما استفاده کند. همچنین سرویس باید بفهمد که چه نوع دادهای در نماهای برنامه شما مورد انتظار است. به عنوان مثال، اگر برنامه شما نمایی دارد که انتظار یک نام کاربری را دارد، سرویس باید یک مجموعه داده داشته باشد که شامل یک نام کاربری باشد و مکانیزمی داشته باشد تا بداند که نما انتظار چنین دادههایی را دارد.
با تنظیم ویژگی android:autofillHints به سرویس بگویید که چه نوع دادهای در ویوهای شما انتظار میرود. برخی سرویسها از روشهای اکتشافی پیچیده برای تعیین نوع داده استفاده میکنند، اما برخی دیگر، مانند برنامه نمونه، برای ارائه این اطلاعات به توسعهدهنده متکی هستند. اگر ویژگی android:autofillHints در ویوهایی که مربوط به تکمیل خودکار هستند تنظیم کنید، برنامه شما با سرویسهای تکمیل خودکار بهتر کار میکند.
آزمون خود را اجرا کنید
پس از تجزیه و تحلیل الزامات دادهها، میتوانید تست خود را اجرا کنید، که شامل ذخیره دادههای تست در سرویس تکمیل خودکار و فعالسازی تکمیل خودکار در برنامه شما میشود.
ذخیره اطلاعات در سرویس
برای ذخیره دادهها در سرویس تکمیل خودکار که در حال حاضر فعال است، موارد زیر را انجام دهید:
- برنامهای را باز کنید که شامل نمایی است که انتظار نوع دادهای را دارد که میخواهید در طول تست خود استفاده کنید. برنامه نمونه android-AutofillFramework ، رابط کاربری را با نماهایی ارائه میدهد که انتظار انواع مختلفی از دادهها، مانند شماره کارتهای اعتباری و نامهای کاربری را دارند.
- روی نمایی که نوع داده مورد نیاز شما را در خود جای داده است، ضربه بزنید.
- یک مقدار را در نما وارد کنید.
- روی دکمه تأیید، مانند ورود یا ارسال، ضربه بزنید. معمولاً باید فرم را قبل از اینکه سرویس دادهها را ذخیره کند، ارسال کنید.
- درخواست مجوز را از طریق پنجرهی سیستم تأیید کنید. پنجرهی سیستم نام سرویسی را که در حال حاضر فعال است نشان میدهد و میپرسد که آیا این همان سرویسی است که میخواهید در آزمایش خود استفاده کنید. اگر میخواهید از این سرویس استفاده کنید، روی ذخیره ضربه بزنید.
اگر اندروید پنجرهی مجوزها را نمایش نمیدهد، یا اگر سرویس مورد نظر شما در تست شما نیست، بررسی کنید که آیا سرویس در حال حاضر در تنظیمات سیستم فعال است یا خیر.
فعال کردن قابلیت تکمیل خودکار فرمها در برنامه شما
برای فعال کردن قابلیت تکمیل خودکار فرمها در برنامه خود، مراحل زیر را انجام دهید:
- برنامه خود را باز کنید و به activity ای که view های مورد نظر برای تست در آن قرار دارند، بروید.
- روی نمایی که باید پر شود ضربه بزنید.
- سیستم رابط کاربری تکمیل خودکار را نمایش میدهد که شامل مجموعه دادههایی است که میتوانند نما را پر کنند، همانطور که در شکل ۱ نشان داده شده است.
- روی مجموعه دادهای که حاوی دادههایی است که میخواهید استفاده کنید، ضربه بزنید. این نما، دادههایی را که قبلاً در سرویس ذخیره شدهاند، نمایش میدهد.

اگر اندروید رابط کاربری تکمیل خودکار را نمایش نمیدهد، میتوانید گزینههای عیبیابی زیر را امتحان کنید:
- بررسی کنید که view های برنامه شما از مقدار صحیح در ویژگی
android:autofillHintsاستفاده کنند. برای مشاهده لیستی از مقادیر ممکن برای این ویژگی، به ثابتهایی که با پیشوندAUTOFILL_HINTدر کلاسViewآمدهاند، مراجعه کنید. - بررسی کنید که ویژگی
android:importantForAutofillدر نمایی که باید پر شود، مقداری غیر ازno، یا در نمای مورد نظر یا یکی از والدین آن، مقداری غیر ازnoExcludeDescendantsتنظیم شده باشد.