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

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

محیط تکمیل خودکار را تنظیم کنید

این بخش نحوه تنظیم عملکرد اولیه تکمیل خودکار را برای برنامه خود توضیح می دهد.

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

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

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

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

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

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

می توانید نکات تکمیل خودکار را با استفاده از ویژگی 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 استفاده کنید.

برای نماهای متعدد که هر نما به یک رقم OTP نگاشت می شود، می توانید از متد generateSmsOtpHintForCharacterPosition() برای ایجاد نکات برای هر کاراکتر استفاده کنید.

فیلدها را برای تکمیل خودکار مهم علامت گذاری کنید

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

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

  • یک فیلد CAPTCHA در یک فعالیت ورود به سیستم
  • نمایی که در آن کاربر محتوا ایجاد می کند، مانند ویرایشگر متن یا صفحه گسترده
  • نماها در برخی از فعالیت های درون بازی ها، مانند مواردی که گیم پلی را نمایش می دهند

با استفاده از ویژگی android:importantForAutofill می‌توانید اهمیت یک نما را برای تکمیل خودکار تنظیم کنید:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:importantForAutofill="no" />

مقدار importantForAutofill می تواند یکی از موارد زیر باشد:

auto
به سیستم Android اجازه دهید از اکتشافات خود برای تعیین اینکه آیا نما برای تکمیل خودکار مهم است استفاده کند.
no
این نما برای تکمیل خودکار مهم نیست.
noExcludeDescendants
این نما و فرزندان آن برای تکمیل خودکار مهم نیستند.
yes
این نمای برای تکمیل خودکار مهم است.
yesExcludeDescendants
این نمای برای تکمیل خودکار مهم است، اما فرزندان آن برای تکمیل خودکار مهم نیستند.

همچنین می توانید از متد setImportantForAutofill() استفاده کنید:

کاتلین

val captcha = findViewById<TextView>(R.id.captcha)
captcha.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO)

جاوا

TextView captcha = findViewById(R.id.captcha);
captcha.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);

می‌توانید موارد استفاده مثال قبلی را برای تکمیل خودکار بی‌اهمیت اعلام کنید:

  • یک فیلد CAPTCHA در یک فعالیت ورود به سیستم: از android:importantForAutofill="no" یا IMPORTANT_FOR_AUTOFILL_NO برای علامت گذاری این نما به عنوان بی اهمیت استفاده کنید.
  • نمایی که در آن کاربر محتوا ایجاد می کند: از android:importantForAutofill="noExcludeDescendants" یا IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS برای علامت گذاری کل ساختار نمای به عنوان بی اهمیت استفاده کنید.
  • نماها در برخی فعالیت‌های درون بازی‌ها: از android:importantForAutofill="noExcludeDescendants" یا IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS برای علامت‌گذاری کل ساختار نمای به‌عنوان بی‌اهمیت استفاده کنید.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • نمای سفارشی قابل ویرایش است.
  • نمای سفارشی حاوی داده های حساس است.

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

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

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

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

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

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

برای مشخص کردن اینکه آیا یک view حاوی داده‌های حساس است یا خیر، 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);
}

اگر یک view فقط مقادیر از پیش تعریف شده را می پذیرد، می توانید از متد setAutofillOptions() برای تنظیم گزینه هایی استفاده کنید که می توانند برای تکمیل خودکار view استفاده شوند. به طور خاص، نماهایی که نوع تکمیل خودکار آنها AUTOFILL_TYPE_LIST است باید از این روش استفاده کنند، زیرا سرویس تکمیل خودکار اگر گزینه های موجود برای پر کردن نما را بداند می تواند کار بهتری انجام دهد.

نماهایی که از آداپتور استفاده می کنند، مانند Spinner ، مورد مشابهی هستند. برای مثال، اسپینری که سال‌های ایجاد شده به صورت پویا را بر اساس سال جاری برای استفاده در فیلدهای انقضای کارت اعتباری فراهم می‌کند، می‌تواند متد getAutofillOptions() رابط Adapter را برای ارائه فهرستی از سال‌ها پیاده‌سازی کند.

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

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

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

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

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

  1. با فراخوانی addChildCount() تعداد فرزند ساختار view را افزایش دهید.
  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 فراخوانی کنید.
  • اگر سلسله مراتب view دیگر در دسترس نیست زیرا کاربر یک مرحله را در گردش کار انجام داده است، مانند زمانی که با استفاده از یک فرم ورود به سیستم وارد می شود، commit() در شی AutofillManager فراخوانی کنید.
  • اگر سلسله مراتب view معتبر نیست زیرا کاربر یک مرحله از گردش کار را لغو کرده است، مانند زمانی که کاربر روی دکمه ای ضربه می زند که فرم ورود را پاک می کند، cancel() در شی AutofillManager فراخوانی کنید.

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

اگر برنامه شما نماهای تکمیل خودکار خود را ارائه می دهد، به مکانیزمی نیاز دارید که به برنامه بگوید در پاسخ به تغییرات در هزینه تکمیل خودکار UI، نماها را فعال یا غیرفعال کند. چارچوب تکمیل خودکار این مکانیسم را در قالب AutofillCallback فراهم می کند.

این کلاس متد onAutofillEvent(View, int) را ارائه می دهد که برنامه پس از تغییر در حالت تکمیل خودکار مرتبط با یک view آن را فراخوانی می کند. همچنین یک نسخه اضافه بار از این روش وجود دارد که شامل یک پارامتر childId است که برنامه شما می‌تواند با نماهای مجازی از آن استفاده کند. حالت های موجود به عنوان ثابت در تماس برگشتی تعریف می شوند.

شما می توانید با استفاده از متد 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 بر روی نما ارائه می دهد تا نشان دهد که محتوای نما به صورت خودکار تکمیل شده است. به طور پیش فرض، این قابل ترسیم یک مستطیل یکدست با رنگ شفاف است که کمی تیره تر از رنگ تم مورد استفاده برای ترسیم پس زمینه است. ترسیم نیازی به تغییر ندارد، اما می‌توان آن را با نادیده گرفتن مورد 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 فعالیت تأیید اعتبار سرویس را به عنوان بخشی از پشته فعالیت شما راه‌اندازی می‌کند.

برای پشتیبانی از احراز هویت، نیازی به به روز رسانی برنامه خود ندارید، زیرا احراز هویت در سرویس انجام می شود. با این حال، باید مطمئن شوید که ساختار view اکتیویتی هنگام راه اندازی مجدد فعالیت حفظ می شود، مانند ایجاد ساختار view در onCreate() , نه در onStart() یا onResume() .

با استفاده از HeuristicsService از نمونه AutofillFramework و پیکربندی آن برای نیاز به احراز هویت پاسخ پاسخ، می‌توانید نحوه عملکرد برنامه خود را در زمانی که یک سرویس تکمیل خودکار نیاز به احراز هویت دارد، بررسی کنید. همچنین می توانید از نمونه BadViewStructureCreationSignInActivity برای شبیه سازی این مشکل استفاده کنید.

شناسه های تکمیل خودکار را به نماهای بازیافتی اختصاص دهید

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

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

برای حل این مشکل در دستگاه‌های دارای Android 9 (سطح API 28) و بالاتر، شناسه تکمیل خودکار نماهایی را که توسط RecyclerView استفاده می‌شود به‌صراحت با استفاده از این روش‌ها مدیریت کنید:

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

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

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

تکمیل خودکار باعث از کار افتادن برنامه‌ها در اندروید ۸.۰، ۸.۱ می‌شود

در Android 8.0 (سطح API 26) و 8.1 (سطح API 27)، تکمیل خودکار می‌تواند باعث از کار افتادن برنامه شما در سناریوهای خاصی شود. برای حل مشکلات احتمالی، نماهایی را که به صورت خودکار تکمیل نشده اند با importantForAutofill=no تگ کنید. همچنین می توانید کل فعالیت را با importantForAutofill=noExcludeDescendants تگ کنید.

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

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

برای حل این مشکل، ویژگی token پارامترهای پنجره گفتگو را با ویژگی token مربوط به فعالیتی که دیالوگ را ایجاد می کند جایگزین کنید. بعد از اینکه تأیید کردید تکمیل خودکار فعال است، پارامترهای پنجره را در متد onWindowAttributesChanged() کلاسی که از Dialog به ارث می برد ذخیره کنید. سپس، در متد onAttachedToWindow() ویژگی token پارامترهای ذخیره شده را با ویژگی token مربوط به فعالیت والد جایگزین کنید.

قطعه کد زیر کلاسی را نشان می دهد که این راه حل را پیاده سازی می کند:

کاتلین

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 8.0 (سطح API 26) یا بالاتر برای آزمایش برنامه خود استفاده کنید. برای اطلاعات بیشتر در مورد نحوه ایجاد یک شبیه ساز، به ایجاد و مدیریت دستگاه های مجازی مراجعه کنید.

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

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

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

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

تجزیه و تحلیل داده های مورد نیاز

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

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

تست خود را اجرا کنید

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

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

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

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

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

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

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

  1. برنامه خود را باز کنید و به فعالیتی بروید که دارای نماهایی است که می خواهید آزمایش کنید.
  2. روی نمایی که باید پر شود ضربه بزنید.
  3. سیستم UI تکمیل خودکار را نشان می دهد که شامل مجموعه داده هایی است که می تواند نمای را پر کند، همانطور که در شکل 1 نشان داده شده است.
  4. روی مجموعه داده ای که حاوی داده هایی است که می خواهید استفاده کنید ضربه بزنید. نما داده هایی را که قبلاً در سرویس ذخیره شده بود نمایش می دهد.
تکمیل خودکار UI "مجموعه داده-2" را به عنوان مجموعه داده در دسترس نمایش می دهد
شکل 1. UI تکمیل خودکار مجموعه داده های موجود را نمایش می دهد.

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

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