بهینه‌سازی برنامه برای تکمیل خودکار

برنامه‌هایی که از نماهای استاندارد استفاده می‌کنند با چارچوب تکمیل خودکار کار می‌کنند و به پیکربندی خاصی نیاز ندارند. همچنین می‌توانید نحوه کار برنامه‌تان با چارچوب را بهینه‌سازی کنید.

راه‌اندازی محیط تکمیل خودکار

این بخش نحوه راه‌اندازی عملکرد تکمیل خودکار پایه را برای برنامه‌تان شرح می‌دهد.

پیکربندی سرویس تکمیل خودکار

برای اینکه برنامه‌تان بتواند از چارچوب تکمیل خودکار استفاده کند، باید سرویس تکمیل خودکار در دستگاهتان پیکربندی شده باشد. اگرچه اکثر تلفن‌ها و رایانه‌های لوحی که Android 8.0 (سطح API ‏۲۶) و بالاتر را اجرا می‌کنند با سرویس تکمیل خودکار عرضه می‌شوند، توصیه می‌کنیم هنگام آزمایش برنامه‌تان از یک سرویس آزمایشی استفاده کنید، مانند سرویس تکمیل خودکار در نمونه چارچوب تکمیل خودکار Android. هنگام استفاده از شبیه‌ساز، سرویس تکمیل خودکار را به‌طور صریح تنظیم کنید، زیرا شبیه‌ساز ممکن است با سرویس پیش‌فرض همراه نباشد.

پس‌از نصب سرویس تکمیل خودکار آزمایشی از برنامه نمونه، با رفتن به تنظیمات > سیستم > زبان‌ها و ورودی > پیشرفته > دستیار ورودی > سرویس تکمیل خودکار، سرویس تکمیل خودکار را فعال کنید.

برای کسب اطلاعات بیشتر درباره پیکربندی شبیه‌ساز برای آزمایش تکمیل خودکار، به آزمایش کردن برنامه با تکمیل خودکار مراجعه کنید.

استفاده از «بافت فعالیت» برای بازدیدها

سرویس تکمیل خودکار برای عملکرد صحیح به «بافت فعالیت» نیاز دارد. هنگام نمونه‌سازی نما، از Activity به‌عنوان زمینه استفاده کنید تا بتواند به‌درستی تکمیل خودکار شود.

ارائه راهنمایی برای تکمیل خودکار

سرویس تکمیل خودکار نوع هر نما را بااستفاده از اکتشافی تعیین می‌کند. اما اگر برنامه شما به این اکتشافات متکی باشد، ممکن است رفتار تکمیل خودکار با به‌روزرسانی برنامه به‌طور غیرمنتظره‌ای تغییر کند. برای اطمینان از اینکه سرویس تکمیل خودکار عوامل شکل برنامه شما را به‌درستی شناسایی می‌کند، نکات تکمیل خودکار را ارائه دهید.

می‌توانید بااستفاده از مشخصه android:autofillHints نکات تکمیل خودکار را تنظیم کنید. مثال زیر راهنمایی "password" را در EditText تنظیم می‌کند:

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:autofillHints="password" />

همچنین می‌توانید بااستفاده از روش setAutofillHints() نکات را به‌صورت برنامه‌نویسی‌شده تنظیم کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

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);

افزودن ثابت‌های راهنمای ازپیش‌تعریف‌شده

چارچوب تکمیل خودکار نکات را اعتبارسنجی نمی‌کند؛ آن‌ها بدون تغییر یا اعتبارسنجی به سرویس تکمیل خودکار منتقل می‌شوند. اگرچه می‌توانید از هر مقداری استفاده کنید، کلاس‌های 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 استفاده کنید.

برای تاریخ انقضای کارت اعتباری، یکی از کارهای زیر را انجام دهید:

نشانی حقیقی

برای فیلدهای فرم نشانی فیزیکی، می‌توانید از نکته‌هایی مانند موارد زیر استفاده کنید:

نام افراد

هنگام درخواست نام افراد، می‌توانید از نکته‌هایی مانند موارد زیر استفاده کنید:

شماره‌های تلفن

برای شماره تلفن، می‌توانید از موارد زیر استفاده کنید:

گذرواژه یکبارمصرف (OTP)

برای گذرواژه یک‌بارمصرف در یک نما، می‌توانید از AUTOFILL_HINT_SMS_OTP استفاده کنید.

برای نماهای چندگانه که هر نما به یک رقم از گذرواژه یک‌بارمصرف نگاشت می‌شود، می‌توانید از روش generateSmsOtpHintForCharacterPosition() برای تولید راهنمایی‌های نویسه‌ای استفاده کنید.

مرتبط کردن داده‌های وب‌سایت و برنامه تلفن همراه

سرویس‌های تکمیل خودکار مانند «تکمیل خودکار با Google» می‌توانند داده‌های ورود به سیستم کاربر را پس‌از مرتبط شدن برنامه و وب‌سایت، بین مرورگرها و دستگاه‌های Android هم‌رسانی کنند. وقتی کاربر سرویس تکمیل خودکار یکسانی را در هر دو پلاتفرم انتخاب می‌کند، ورود به سیستم برنامه وب شما باعث می‌شود اعتبارنامه ورود به سیستم او برای تکمیل خودکار دردسترس قرار گیرد وقتی به سیستم برنامه Android متناظر شما وارد می‌شود.

برای مرتبط کردن برنامه Android با وب‌سایتتان، یک پیوند دارایی دیجیتال با رابطه delegate_permission/common.get_login_creds در سایتتان میزبانی کنید. سپس، ارتباط را در فایل AndroidManifest.xml برنامه‌تان اعلام کنید. برای دستورالعمل‌های دقیق درباره نحوه مرتبط کردن وب‌سایتتان با برنامه Android، به فعال کردن ورود خودکار به سیستم در برنامه‌ها و وب‌سایت‌ها مراجعه کنید.

تکمیل کردن گردش کار تکمیل خودکار

این بخش سناریوهای خاصی را شرح می‌دهد که در آن‌ها می‌توانید اقداماتی برای بهبود عملکرد تکمیل خودکار برای کاربران برنامه‌تان انجام دهید.

تعیین اینکه تکمیل خودکار فعال است یا نه

کاربران می‌توانند با رفتن به تنظیمات > سیستم > زبان‌ها و ورودی > پیشرفته > دستیار ورودی > سرویس تکمیل خودکار، تکمیل خودکار را فعال یا غیرفعال کنند و همچنین سرویس تکمیل خودکار را تغییر دهند. برنامه شما نمی‌تواند تنظیمات تکمیل خودکار کاربر را لغو کند، اما می‌توانید عملکرد تکمیل خودکار اضافی را در برنامه‌تان یا در نماهای خاصی از برنامه‌تان پیاده‌سازی کنید، اگر تکمیل خودکار برای کاربر دردسترس باشد.

برای مثال، TextView ورودی تکمیل خودکار را در منو سرریز نشان می‌دهد اگر تکمیل خودکار برای کاربر فعال باشد. برای بررسی اینکه تکمیل خودکار برای کاربر فعال است یا نه، روش isEnabled() شیء AutofillManager را فراخوانی کنید.

برای اطمینان از اینکه تجربه ثبت‌نام و ورود به سیستم شما برای کاربران بدون تکمیل خودکار بهینه‌سازی شده است، ورود به سیستم با یک تک‌ضرب را پیاده‌سازی کنید.

اجباری کردن درخواست تکمیل خودکار

گاهی اوقات لازم است درخواست تکمیل خودکار را مجبور کنید در پاسخ به کنش کاربر اتفاق بیفتد. برای مثال، وقتی کاربر روی نما لمس می‌کند و نگه می‌دارد، 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 را به‌درستی مدیریت کند.

وقتی نوع داده تکمیل خودکار را مشخص می‌کنید، سرویس تکمیل خودکار می‌تواند نمایش مناسبی از داده‌های نمایش‌داده‌شده در نما ایجاد کند. برای اطلاعات بیشتر، به استفاده از انتخاب‌گرها با تکمیل خودکار مراجعه کنید.

تکمیل کردن بافت تکمیل خودکار

چارچوب تکمیل خودکار ورودی کاربر را برای استفاده در آینده ذخیره می‌کند و پس‌از تکمیل بافت تکمیل خودکار، کادر گفتگوی «برای تکمیل خودکار ذخیره شود؟» را نشان می‌دهد. معمولاً وقتی فعالیتی تمام می‌شود، بافت تکمیل خودکار نیز تمام می‌شود. بااین‌حال، در برخی شرایط باید به‌طور صریح به چارچوب اطلاع دهید—برای مثال، اگر از فعالیت یکسان اما قطعه‌های متفاوت برای هر دو صفحه ورود به سیستم و محتوا استفاده می‌کنید. در این شرایط، می‌توانید با فراخوانی AutofillManager.commit()، بافت را به‌طور صریح تمام کنید.

پشتیبانی از نماهای سفارشی

نماهای سفارشی می‌توانند فراداده‌ای را که در چارچوب تکمیل خودکار نشان داده می‌شود بااستفاده از میانای برنامه‌سازی کاربردی تکمیل خودکار مشخص کنند. برخی‌از نماها به‌عنوان محفظه فرزندان مجازی عمل می‌کنند، مثل نماهایی که حاوی میانای کاربر با رندر OpenGL هستند. این نماها باید از API برای مشخص کردن ساختار اطلاعات استفاده‌شده در برنامه استفاده کنند تا بتوانند با چارچوب تکمیل خودکار کار کنند.

اگر برنامه‌تان از نماهای سفارشی استفاده می‌کند، سناریوهای زیر را درنظر بگیرید:

  • نمای سفارشی ساختار نمای استاندارد یا ساختار نمای پیش‌فرض را ارائه می‌دهد.
  • نمای سفارشی دارای ساختار مجازی یا ساختار نمایی است که برای چارچوب تکمیل خودکار دردسترس نیست.

نماهای سفارشی با ساختار نمای استاندارد

نماهای سفارشی می‌توانند فراداده‌ای را که تکمیل خودکار برای کار کردن نیاز دارد تعریف کنند. مطمئن شوید نمای سفارشی‌تان فراداده را به‌درستی مدیریت می‌کند تا با چارچوب تکمیل خودکار کار کند. نمای سفارشی شما باید اقدامات زیر را انجام دهد:

  • مقدار تکمیل خودکار را که چارچوب به برنامه‌تان ارسال می‌کند مدیریت کنید.
  • نوع و مقدار تکمیل خودکار را به چارچوب ارائه دهید.

وقتی تکمیل خودکار راه‌اندازی می‌شود، چارچوب تکمیل خودکار autofill() را در نمای شما فراخوانی می‌کند و مقداری را که نمای شما باید استفاده کند ارسال می‌کند. autofill() را پیاده‌سازی کنید تا مشخص کنید نمای سفارشی شما چگونه مقدار تکمیل خودکار را مدیریت می‌کند.

نمای شما باید با لغو کردن روش‌های getAutofillType() و getAutofillValue() به‌ترتیب نوع و مقدار تکمیل خودکار را مشخص کند.

درنهایت، اگر کاربر نتواند مقداری برای نمای فعلی ارائه دهد، تکمیل خودکار نباید نما را تکمیل کند—برای مثال، اگر نما غیرفعال باشد. در این موارد، getAutofillType() باید AUTOFILL_TYPE_NONE را برگرداند، getAutofillValue() باید null را برگرداند، و autofill() نباید کاری انجام دهد.

موارد زیر برای عملکرد صحیح در چارچوب به مراحل اضافی نیاز دارند:

  • نمای سفارشی ویرایش‌شدنی است.
  • نمای سفارشی حاوی داده‌های حساس است.

نمای سفارشی قابل‌ویرایش است

اگر نما قابل‌ویرایش است، با فراخوانی notifyValueChanged() در شیء AutofillManager، چارچوب تکمیل خودکار را از تغییرات مطلع کنید.

نمای سفارشی حاوی داده‌های حساس است

اگر نمایی حاوی اطلاعات شناساننده شخصی (PII) مانند نشانی ایمیل، شماره کارت اعتباری، و گذرواژه باشد، باید به‌عنوان حساس علامت‌گذاری شود.

به‌طور کلی، نماهایی که محتوای آن‌ها از منابع ایستا می‌آید حاوی داده‌های حساس نیستند، درحالی‌که نماهایی که محتوای آن‌ها به‌طور پویا تنظیم می‌شود ممکن است حاوی داده‌های حساس باشند. برای مثال، برچسبی که حاوی نام کاربری‌تان را وارد کنید است، داده‌های حساس ندارد، اما برچسبی که حاوی سلام، جان است، داده‌های حساس دارد.

چارچوب تکمیل خودکار فرض می‌کند که همه داده‌ها به‌طور پیش‌فرض حساس هستند. می‌توانید داده‌هایی را که حساس نیستند علامت‌گذاری کنید.

برای علامت‌گذاری اینکه آیا نمایی حاوی داده‌های حساس است یا نه، onProvideAutofillStructure() را پیاده‌سازی کنید و setDataIsSensitive() را در شیء ViewStructure فراخوانی کنید.

نمونه کد زیر نشان می‌دهد که چگونه داده‌ها را در ساختار نما به‌عنوان غیرحساس علامت‌گذاری کنید:

کاتلین

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، مورد مشابهی هستند. برای مثال، یک اسپینر که سال‌های ایجادشده به‌صورت پویا را براساس سال جاری ارائه می‌دهد تا در فیلدهای انقضای کارت اعتباری استفاده شود، می‌تواند روش getAutofillOptions() از میانای Adapter را برای ارائه فهرستی از سال‌ها پیاده‌سازی کند.

نماهایی که از ArrayAdapter استفاده می‌کنند همچنین می‌توانند فهرست‌هایی از مقادیر ارائه دهند. ‫ArrayAdapter به‌طور خودکار گزینه‌های تکمیل خودکار را برای منابع ایستا تنظیم می‌کند. اگر مقادیر را به‌صورت پویا ارائه می‌دهید، getAutofillOptions() را لغو کنید.

نماهای سفارشی با ساختار مجازی

چارچوب تکمیل خودکار به ساختار نمایشی نیاز دارد تا بتواند اطلاعات را در میانای کاربری برنامه‌تان ویرایش و ذخیره کند. ساختار نما در شرایط زیر برای چارچوب دردسترس نیست:

  • برنامه از موتور پرداز سطح پایین، مانند OpenGL، برای پرداز کردن میانای کاربری استفاده می‌کند.
  • برنامه از نمونه‌ای از Canvas برای ترسیم واسط کاربر استفاده می‌کند.

در این موارد، می‌توانید با پیاده‌سازی onProvideAutofillVirtualStructure() و دنبال کردن این مراحل، ساختار نمایشی را مشخص کنید:

  1. با فراخوانی addChildCount()، تعداد فرزندان ساختار نما را افزایش دهید.
  2. با تماس با newChild()، فرزندی اضافه کنید.
  3. با فراخوانی setAutofillId()، شناسه تکمیل خودکار را برای فرزند تنظیم کنید.
  4. ویژگی‌های مربوطه، مثل مقدار و نوع تکمیل خودکار، را تنظیم کنید.
  5. اگر داده‌های موجود در فرزند مجازی حساس است، 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 است که برنامه‌تان می‌تواند با نماهای مجازی استفاده کند. وضعیت‌های دردسترس به‌عنوان ثابت‌ها در callback تعریف می‌شوند.

می‌توانید بااستفاده از روش registerCallback() کلاس AutofillManager، یک فراخوانی برگشتی ثبت کنید. نمونه کد زیر نشان می‌دهد چگونه یک callback برای رویدادهای تکمیل خودکار اعلام کنیم:

کاتلین

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 زمینه مورداستفاده برنامه یا فعالیت سفارشی‌سازی کرد، همان‌طور که در این مثال نشان داده شده است:

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 نسخه ۹ (سطح میانای برنامه‌سازی کاربردی ۲۸) و بالاتر دارند، شناسه تکمیل خودکار نماهایی را که توسط RecyclerView استفاده می‌شود بااستفاده از این روش‌ها به‌طور صریح مدیریت کنید:

  • روش getNextAutofillId() شناسه تکمیل خودکار جدیدی دریافت می‌کند که برای فعالیت یکتا است.
  • روش setAutofillId() شناسه تکمیل خودکار منطقی و یکتای این نما را در فعالیت تنظیم می‌کند.

رسیدگی به مشکلات شناخته‌شده

این بخش راه‌حل‌های موقتی برای مشکلات شناخته‌شده در چارچوب تکمیل خودکار ارائه می‌دهد.

تکمیل خودکار باعث ازکار افتادن برنامه‌ها در Android 8.0 و 8.1 می‌شود

در Android نسخه ۸.۰ (سطح میانای برنامه‌سازی کاربردی ۲۶) و ۸.۱ (سطح میانای برنامه‌سازی کاربردی ۲۷)، تکمیل خودکار می‌تواند در برخی سناریوها باعث از کار افتادن برنامه‌تان شود. برای حل مشکلات احتمالی، هر نمایی را که با importantForAutofill=no تکمیل خودکار نشده است برچسب‌گذاری کنید. همچنین می‌توانید کل فعالیت را با importantForAutofill=noExcludeDescendants برچسب‌گذاری کنید.

کادرهای گفتگویی که اندازه آن‌ها تغییر کرده است برای تکمیل خودکار درنظر گرفته نمی‌شوند

در Android 8.1 (سطح API‏ ۲۷) و نسخه‌های پایین‌تر، اگر اندازه نمای موجود در کادر گفتگو پس‌از نمایش تغییر کند، آن نما برای تکمیل خودکار درنظر گرفته نمی‌شود. این نماها در شیء AssistStructure که سیستم Android به سرویس تکمیل خودکار ارسال می‌کند گنجانده نمی‌شود. درنتیجه، سرویس نمی‌تواند نماها را تکمیل کند.

برای حل این مشکل، ویژگی 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();
    }
}

آزمایش کردن برنامه با تکمیل خودکار

پس‌از بهینه‌سازی برنامه‌تان برای کار با سرویس‌های تکمیل خودکار، آزمایش کنید که آیا با سرویس‌های تکمیل خودکار به‌درستی کار می‌کند یا نه.

برای آزمایش برنامه‌تان، از شبیه‌ساز یا دستگاه فیزیکی با Android نسخه ۸.۰ (سطح API‏ ۲۶) یا بالاتر استفاده کنید. برای اطلاعات بیشتر درباره نحوه ایجاد شبیه‌ساز، به ایجاد و مدیریت دستگاه‌های مجازی مراجعه کنید.

نصب سرویس تکمیل خودکار

قبل‌از اینکه بتوانید برنامه‌تان را با تکمیل خودکار آزمایش کنید، باید برنامه دیگری را که سرویس‌های تکمیل خودکار ارائه می‌دهد نصب کنید. می‌توانید از برنامه طرف سوم برای این منظور استفاده کنید، اما استفاده از سرویس تکمیل خودکار نمونه آسان‌تر است تا نیازی به ثبت‌نام در سرویس‌های طرف سوم نداشته باشید.

می‌توانید از نمونه چارچوب تکمیل خودکار Android در Java برای آزمایش کردن برنامه‌تان با سرویس‌های تکمیل خودکار استفاده کنید. برنامه نمونه سرویس تکمیل خودکار و کلاس‌های مشتری Activity را ارائه می‌دهد که می‌توانید از آن‌ها برای آزمایش کردن گردش کار قبل‌از استفاده از آن با برنامه‌تان استفاده کنید. این صفحه به برنامه نمونه android-AutofillFramework ارجاع می‌دهد.

پس‌از نصب برنامه، سرویس تکمیل خودکار را در تنظیمات سیستم شبیه‌ساز با رفتن به تنظیمات > سیستم > زبان‌ها و ورودی > پیشرفته > کمک ورودی > سرویس تکمیل خودکار فعال کنید.

تجزیه‌وتحلیل الزامات داده‌ها

برای آزمایش کردن برنامه‌تان با سرویس تکمیل خودکار، سرویس باید داده‌هایی داشته باشد که بتواند از آن‌ها برای تکمیل کردن برنامه‌تان استفاده کند. همچنین سرویس باید بداند چه نوع داده‌ای در نماهای برنامه‌تان انتظار می‌رود. برای مثال، اگر برنامه‌تان نمایی دارد که انتظار نام کاربری دارد، سرویس باید مجموعه داده‌ای داشته باشد که حاوی نام کاربری باشد و سازوکاری داشته باشد که بداند نما انتظار چنین داده‌ای را دارد.

با تنظیم کردن ویژگی android:autofillHints، به سرویس بگویید چه نوع داده‌ای در نماهای شما انتظار می‌رود. برخی‌از سرویس‌ها از اکتشافات پیچیده برای تعیین نوع داده استفاده می‌کنند، اما برخی دیگر، مانند برنامه نمونه، برای ارائه این اطلاعات به توسعه‌دهنده متکی هستند. اگر مشخصه android:autofillHints را در نماهایی که برای تکمیل خودکار مناسب هستند تنظیم کنید، برنامه‌تان با سرویس‌های تکمیل خودکار بهتر کار می‌کند.

اجرای آزمایش

پس‌از تجزیه‌وتحلیل الزامات داده، می‌توانید آزمایشتان را اجرا کنید که شامل ذخیره کردن داده‌های آزمایش در سرویس تکمیل خودکار و راه‌اندازی تکمیل خودکار در برنامه‌تان می‌شود.

ذخیره کردن داده‌ها در سرویس

برای ذخیره کردن داده‌ها در سرویس تکمیل خودکاری که درحال‌حاضر فعال است، کارهای زیر را انجام دهید:

  1. برنامه‌ای را باز کنید که حاوی نمایی باشد که نوع داده موردنظرتان را برای استفاده درطول آزمایش انتظار دارد. برنامه نمونه android-AutofillFramework واسط کاربر را با نماهایی ارائه می‌دهد که چندین نوع داده را انتظار دارند، مثل شماره کارت اعتباری و نام کاربری.
  2. روی نمایی که نوع داده موردنیازتان را دارد ضربه بزنید.
  3. مقداری را در نما وارد کنید.
  4. روی دکمه تأیید، مثلاً ورود به سیستم یا ارسال، تک‌ضرب بزنید. معمولاً باید فرم را قبل‌از اینکه سرویس داده‌ها را ذخیره کند ارسال کنید.
  5. درخواست اجازه را از کادر گفتگوی سیستم درستی‌سنجی کنید. کادر گفتگوی سیستم نام سرویسی را که درحال‌حاضر فعال است نشان می‌دهد و می‌پرسد آیا این همان سرویسی است که می‌خواهید در آزمایشتان استفاده کنید. اگر می‌خواهید از این سرویس استفاده کنید، روی ذخیره تک‌ضرب بزنید.

اگر Android کادر گفتگوی اجازه را نمایش نمی‌دهد، یا اگر سرویس همان سرویسی نیست که می‌خواهید در آزمایشتان استفاده کنید، بررسی کنید که سرویس درحال‌حاضر در تنظیمات سیستم فعال باشد.

راه‌اندازی تکمیل خودکار در برنامه شما

برای راه‌اندازی تکمیل خودکار در برنامه‌تان، کارهای زیر را انجام دهید:

  1. برنامه‌تان را باز کنید و به فعالیتی بروید که نماهای مدنظرتان برای آزمایش را دارد.
  2. روی نمایی که باید تکمیل شود تک‌ضرب بزنید.
  3. سیستم میانای کاربری تکمیل خودکار را نمایش می‌دهد که حاوی مجموعه‌داده‌هایی است که می‌توانند نما را پر کنند، همان‌طور که در شکل ۱ نشان داده شده است.
  4. روی مجموعه داده‌ای که حاوی داده‌های موردنظرتان برای استفاده است تک‌ضرب بزنید. نمای داده‌های ذخیره‌شده قبلی در سرویس را نمایش می‌دهد.
کادر گفتگوی تکمیل خودکار که انتخاب‌های مجموعه داده دردسترس را نمایش می‌دهد
شکل ۱. میانای کاربری «تکمیل خودکار» که مجموعه‌داده‌های دردسترس را نمایش می‌دهد.

اگر Android واسط کاربری تکمیل خودکار را نمایش نمی‌دهد، می‌توانید گزینه‌های عیب‌یابی زیر را امتحان کنید:

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