針對自動填入功能最佳化應用程式

使用標準檢視的應用程式可與自動填入架構中搭配使用,不需進行特殊設定。但是,您可以最佳化應用程式與架構搭配使用的方式。

設定自動填入環境

本節說明如何為應用程式設定基本自動填入功能。

設定自動填入服務

您必須在裝置上為應用程式設定自動填入服務,才能使用自動填入架構。雖然多數搭載 Android 8.0 (API 級別 26) 以上版本的手機和平板電腦會預先安裝自動填入服務,但我們建議您在測試應用程式時使用測試服務,例如 Android 中的自動填入架構範例中的自動填入服務Java|Kotlin。使用模擬器時,您必須明確設定自動填入服務,因為模擬器可能沒有預設服務。

從範例應用程式安裝測試自動填入服務之後,請依序前往「設定」>「系統」>「語言與輸入設定」>「進階」>「輸入協助」>「自動填入服務」啟用自動填入服務。

如要進一步瞭解如何設定模擬器以測試自動填入功能,請參閱使用自動填入功能測試應用程式

針對自動填入提供提示

自動填入服務會嘗試利用經驗法則判斷各檢視畫面的類型。不過,如果您的應用程式仰賴這些經驗法則,自動填入行為可能會在您更新應用程式時意外變更。為確保自動填入服務可正確識別應用程式的板型規格,您應提供自動填入提示。

您可以使用 android:autofillHints 屬性來設定這些提示。下列範例在 EditText 上設定「密碼」提示:

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

您也可以使用 setAutofillHints() 方法,以程式輔助方式設定提示,如下列範例所示:

Kotlin

val password = findViewById<EditText>(R.id.password)
password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD)

Java

EditText password = findViewById(R.id.password);
password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD);

預先定義的提示常數

自動填入架構不會驗證提示;提示將直接傳遞至自動填入服務,而不會進行變更或驗證。您可以使用任何值,但 View 類別和 AndroidX HintConstants 類別也會包含官方支援的提示常數清單。

透過使用這些常數組合,您即可針對常見的自動填入情境建構版面配置:

帳戶憑證

在自動填入帳戶憑證時,登入表單可能包含提示 例如 AUTOFILL_HINT_USERNAMEAUTOFILL_HINT_PASSWORD

建立新帳戶或使用者變更使用者名稱和密碼時,您可以使用 AUTOFILL_HINT_NEW_USERNAMEAUTOFILL_HINT_NEW_PASSWORD

信用卡資訊

系統要求信用卡資訊時,您可以使用 AUTOFILL_HINT_CREDIT_CARD_NUMBERAUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE 等提示。

針對信用卡到期日,請執行下列任一操作:

實際地址

自動填入實際地址時,您可以使用下列提示:

使用者姓名

自動填入使用者姓名時,您可以使用下列提示:

電話號碼

針對電話號碼,您可以使用下列提示:

動態密碼 (OTP)

針對單一檢視表中的動態密碼,您可以使用 AUTOFILL_HINT_SMS_OTP

如果使用多個檢視畫面,且每個檢視畫面都對應至動態密碼的一個數字,您可以使用 generateSmsOptHintForCharacterPosition() 方法按字元產生提示。

將欄位標示為自動填入的重要項目

您可以告知系統是否應將應用程式中的個別欄位納入檢視畫面結構中,以便自動填入。根據預設,檢視畫面採用 IMPORTANT_FOR_AUTOFILL_AUTO 模式,讓 Android 利用經驗法則判斷檢視畫面是否有必要自動填入。

您可以使用 android:importantForAutofill 屬性設定重要性:

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

importantForAutofill 的值可以是 android:importantForAutofill 中定義的任何值:

auto
讓 Android 系統利用經驗法則判斷檢視畫面是否有必要自動填入。
no
此檢視畫面沒有必要自動填入。
noExcludeDescendants
此檢視畫面及其子項沒有必要自動填入。
yes
此檢視畫面有必要自動填入。
yesExcludeDescendants
此檢視畫面有必要自動填入,但其子項沒有必要自動填入。

您也可以使用 setImportantForAutofill() 方法:

Kotlin

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

Java

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

在某些情況下,檢視畫面、檢視畫面結構或整個活動沒有必要自動填入:

  • 登入活動中的人機驗證 (Captcha) 欄位通常沒有必要自動填入。在這種情況下,您可以將檢視畫面標示為 IMPORTANT_FOR_AUTOFILL_NO
  • 在使用者建立內容的檢視畫面 (例如文字或試算表編輯器) 中,整個檢視畫面的結構通常沒有必要自動填入。在這種情況下,您可以將檢視畫面標示為 IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS,確保所有子項也都標示為沒有必要自動填入。
  • 在遊戲的某些活動 (例如顯示遊戲過程的活動) 中,活動的所有檢視畫面都沒有必要自動填入。您可以將根層級檢視畫面標示為 IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS,確保該活動中的所有檢視畫面都標示為沒有必要自動填入。

連結網站和行動應用程式資料

透過 Google 自動填入等自動填入服務,當應用程式與網站建立關聯後,就可在瀏覽器和 Android 裝置之間共用使用者登入資料。當使用者在這兩個平台上選擇相同的自動填入服務時,只要登入您的網頁應用程式,他們的登入憑證就可在登入相應的 Android 應用程式時自動填入。

如要將 Android 應用程式與網站建立關聯,您必須在網站中代管一個具有 delegate_permission/common.get_login_creds 關係的Digital Asset Links (數位資產連結)。然後在應用程式的 AndroidManifest.xml 檔案中宣告關聯。如需如何將網站與 Android 應用程式建立關聯的詳細操作說明,請參閱「啟用跨應用程式和網站的自動登入功能」

完成自動填入工作流程

本節說明幾個特定情境,在這些情境下,您可以採取多個步驟,針對您應用程式的使用者改善自動填入功能。

判斷是否已啟用自動填入功能

如果使用者可以使用自動填入功能,則您可以在應用程式或甚至應用程式的特定檢視畫面中,實作其他自動填入功能。例如,如果已針對啟用自動填入功能,TextView 就會在溢位選單中顯示自動填入項目。如要檢查是否已針對使用者啟用自動填入功能,請呼叫 AutofillManager 物件的 isEnabled() 方法。

使用者可以依序前往 「設定」>「系統」 > 「語言與輸入設定」>「進階」 > 「輸入協助」>「自動填入服務」 來啟用或停用自動填入功能,以及變更自動填入服務。您的應用程式無法覆寫使用者的自動填入設定。

針對沒有自動填入功能的使用者,為確保您取得最佳的註冊和登入體驗,建議您實作密碼專用 Smart Lock

強制執行自動填入要求

您有時可能需要強制執行自動填入要求,以回應使用者動作。例如,TextView 會在使用者長按檢視畫面時,提供自動填入選單項目。以下程式碼範例顯示如何強制執行自動填入要求:

Kotlin

fun eventHandler(view: View) {
    val afm = requireContext().getSystemService(AutofillManager::class.java)
    afm?.requestAutofill(view)
}

Java

public void eventHandler(View view) {
    AutofillManager afm = context.getSystemService(AutofillManager.class);
    if (afm != null) {
        afm.requestAutofill(view);
    }
}

您也可以使用 cancel() 方法取消目前的自動填入內容。例如ㄌ,如果有用於清除登入頁面中欄位的按鈕,這項功能就很實用。

針對挑選器控制項中的資料使用正確的自動填入類型

挑選器在某些自動填入情境下非常實用,可提供 UI 讓使用者變更日期或時間資料儲存欄位中的值。例如,在信用卡表單中,日期挑選器可讓使用者輸入或變更信用卡的到期日。不過,如要在沒有可見挑選器時顯示挑選器資料,必須使用另一檢視畫面 (例如 EditText)。

EditText 物件原生需要 AUTOFILL_TYPE_TEXT 類型的自動填入資料。如果您使用不同的資料類型,則應建立繼承自 EditText 的自訂檢視畫面,並實作處理對應資料類型所需的方法。例如,如果您有一個日期欄位,請採用能夠正確處理 AUTOFILL_TYPE_DATE 類型值的邏輯來實作方法。

當您指定自動填入資料類型時,自動填入服務就能為檢視畫面中顯示的資料建立適當的表示法。詳情請參閱請參閱使用具自動填入功能的挑選器

完成自動填入內容

自動填入架構會在完成自動填入內容後顯示「要儲存自動填入內容嗎?」對話方塊,以儲存使用者輸入內容,供未來使用。一般而言,系統會在活動結束時完成自動填入內容。然而,某些情況下您會需要明確通知架構;例如,如果您在登入頁面和內容畫面上使用相同的活動,但片段不同。在這些特殊情況下,您可以呼叫 AutofillManager.commit() 明確完成內容。

支援自訂檢視畫面

自訂檢視畫面可以使用自動填入 API 指定對自動填入架構公開的中繼資料。某些檢視畫面可做為虛擬子項的容器,例如包含 OpenGL 轉譯 UI 的檢視畫面。這些檢視畫面必須使用 API 指定用於應用程式的資訊結構,才能與自動填入架構搭配使用。

如果您的應用程式使用自訂檢視畫面,必須考量下列情境:

  • 自訂檢視畫面會提供標準檢視畫面結構或預設檢視畫面結構。
  • 自訂檢視畫面具有虛擬結構,或自動填入架構無法使用的檢視畫面結構。

使用標準檢視畫面結構的自訂檢視畫面

自訂檢視畫面可以定義自動填入功能運作所需的中繼資料。您應確保自訂檢視畫面適當管理中繼資料,以便與自動填入架構搭配使用。您的自訂檢視畫面應包含下列動作:

  • 處理架構傳送給應用程式的自動填入值。
  • 為架構提供自動填入類型和值。

當自動填入功能觸發時,自動填入架構會在您的檢視畫面中呼叫 autofill(),並傳送檢視畫面應使用的值。您應該實作 autofill() 以指定自訂檢視畫面處理自動填入值的方式。

您的檢視畫面應分別覆寫 getAutofillType()getAutofillValue() 方法,藉此指定自動填入類型和值。透過新增此程式碼,您可以確保檢視畫面能為架構提供適當的自動填入類型和值。

最後,如果使用者無法針對目前狀態下的檢視畫面 (例如檢視畫面停用) 提供值,自動填入功能不應為檢視畫面填入內容。在這些情況下,getAutofillType() 應返回傳回 AUTOFILL_TYPE_NONEgetAutofillValue() 應回傳 null,而 autofill() 應不會執行任何動作。

在下列情況下,您需要額外的步驟才能在架構中正確運作:

  • 自訂檢視畫面可以編輯。
  • 自訂檢視畫面含有機密資料。

自訂檢視畫面可以編輯

如果檢視畫面可以編輯,請呼叫 AutofillManager 物件上的 notifyValueChanged(),以通知自動填入架構的變更。

自訂檢視畫面含有機密資料

如果檢視畫面包含電子郵件地址、信用卡號碼和密碼等個人識別資訊 (PII),應標示為此類別。一般而言,如果內容是由靜態資源提供,就不會包含機密資料,但透過動態方式設定的檢視畫面可能包含機密資料。例如,包含輸入您的使用者名稱的標籤就不包含機密資料,而包含 Hello, John 的標籤則有。如要標示檢視畫面是否含有機密資料,請在 ViewStructure 物件上實作 onProvideAutofillStructure() 並呼叫 setDataIsSensitive()

以下程式碼範例顯示如何將檢視畫面結構中的資料標示為機密:

Kotlin

override fun onProvideAutofillStructure(structure: ViewStructure, flags: Int) {
    super.onProvideAutofillStructure(structure, flags)

    // Content that comes from static resources generally isn't sensitive.
    val sensitive = !contentIsSetFromResources()
    structure.setDataIsSensitive(sensitive)
}

Java

@Override
public void onProvideAutofillStructure(ViewStructure structure, int flags) {
    super.onProvideAutofillStructure(structure, flags);

    // Content that comes from static resources generally isn't sensitive.
    boolean sensitive = !contentIsSetFromResources();
    structure.setDataIsSensitive(sensitive);
}

如果檢視表只接受預先定義的值,您可以使用 setAutofillOptions() 方法來設定可用來自動填入這個檢視表的選項。自動填入類型為 AUTOFILL_TYPE_LIST 的檢視畫面更應使用此方法,因為自動填入服務如果知道可以填入檢視畫面的選項,就能發揮更好的效果。

使用轉接程式的檢視畫面 (例如 Spinner) 也是類似的。例如,提供動態建立年份 (根據目前年份而定) 供信用卡到期欄位使用的旋轉圖示,可以實作 Adapter 介面的 getAutofillOptions() 方法,以提供年份清單。

使用 ArrayAdapter 的檢視畫面也可以提供值的清單。ArrayAdapter 會自動為靜態資源設定自動填入選項。 不過,如果您以動態方式提供值,就應該覆寫 getAutofillOptions()

使用虛擬結構的自訂檢視畫面

自動填入架構需要一個檢視畫面結構,才能在應用程式的使用者介面中編輯和儲存資訊。在某些情況下,檢視畫面結構不適用架構:

  • 應用程式使用低階轉譯引擎 (例如 OpenGL) 來轉譯 UI。
  • 應用程式使用 Canvas 的執行個體來繪製使用者介面。

在這些情況下,您可以實作 onProvideAutofillVirtualStructure() 並按照下列步驟指定檢視畫面結構:

  1. 呼叫 addChildCount() 增加檢視畫面結構的子項數量。
  2. 呼叫 newChild() 新增子項。
  3. 呼叫 setAutofillId() 為子項設定自動填入 ID。
  4. 設定相關屬性,例如自動填入值和類型。
  5. 如果虛擬子項中的資料具機密性,您應將 true 傳遞至 setDataIsSensitive()false

下列程式碼片段顯示如何在虛擬結構中建立新的子項:

Kotlin

override fun onProvideAutofillVirtualStructure(structure: ViewStructure, flags: Int) {

    super.onProvideAutofillVirtualStructure(structure, flags)

    // Create a new child in the virtual structure.
    structure.addChildCount(1)
    val child = structure.newChild(childIndex)

    // Set the autofill ID for the child.
    child.setAutofillId(structure.autofillId!!, childVirtualId)

    // Populate the child by providing properties such as value and type.
    child.setAutofillValue(childAutofillValue)
    child.setAutofillType(childAutofillType)

    // Some children can provide a list of values. For example, if 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, if
    // appropriate.
    val sensitive = !contentIsSetFromResources()
    child.setDataIsSensitive(sensitive)
}

Java

@Override
public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {

    super.onProvideAutofillVirtualStructure(structure, flags);

    // Create a new child in the virtual structure.
    structure.addChildCount(1);
    ViewStructure child =
            structure.newChild(childIndex);

    // Set the autofill ID for the child.
    child.setAutofillId(structure.getAutofillId(), childVirtualId);

    // Populate the child by providing properties such as value and type.
    child.setAutofillValue(childAutofillValue);
    child.setAutofillType(childAutofillType);

    // Some children can provide a list of values. For example, if the child is
    // a spinner.
    CharSequence childAutofillOptions[] = { "option1", "option2" };
    child.setAutofillOptions(childAutofillOptions);

    // Just like other types of views, mark the data as sensitive, if
    // appropriate.
    boolean sensitive = !contentIsSetFromResources();
    child.setDataIsSensitive(sensitive);
}

當虛擬結構中的元素變更時,您應該執行下列工作來通知架構:

  • 如果子項中的焦點改變,在 AutofillManager 物件上呼叫 notifyViewEntered()notifyViewExited()
  • 如果子項的值改變,在 AutofillManager 物件上呼叫 notifyValueChanged()
  • 如果檢視區塊階層因使用者已完成工作流程中的某個步驟而不再可用 (例如,使用者使用登入表單登入),在 AutofillManager 物件上呼叫 commit()
  • 如果檢視區塊階層因使用者已取消工作流程中的某個步驟而不再有效 (例如,如果使用者點擊清除登入表單的按鈕),在 AutofillManager 物件上呼叫 cancel()

在自動填入事件中使用回呼

如果您的應用程式有專屬的自動完成檢視畫面,您必須利用一種機制讓應用程式能啟用或停用 UI,以回應使用者介面自動填入能供性的改變。自動填入架構會以 AutofillCallback 的形式提供這個機制。

此類別提供 onAutofillEvent(View, int) 方法,應用程式會在與檢視畫面相關的這種方法會在與資料檢視關聯的自動填入狀態改變後,呼叫此方法。此方法還有一個超載版本,其中包含可用於虛擬檢視畫面的 childId 參數。可用狀態在回呼中定義為 常數

您可以使用 AutofillManager 類別的 registerCallback() 方法註冊回呼。以下程式碼範例顯示如何針對自動填入事件宣告回呼:

Kotlin

val afm = context.getSystemService(AutofillManager::class.java)

afm?.registerCallback(object : AutofillManager.AutofillCallback() {
    // For virtual structures, override
    // onAutofillEvent(View view, int childId, int event) instead.
    override fun onAutofillEvent(view: View, event: Int) {
        super.onAutofillEvent(view, event)
        when (event) {
            EVENT_INPUT_HIDDEN -> {
                // The autofill affordance associated with the view was hidden.
            }
            EVENT_INPUT_SHOWN -> {
                // The autofill affordance associated with the view was shown.
            }
            EVENT_INPUT_UNAVAILABLE -> {
                // Autofill isn't available.
            }
        }

    }
})

Java

AutofillManager afm = getContext().getSystemService(AutofillManager.class);

afm.registerCallback(new AutofillManager.AutofillCallback() {
    // For virtual structures, override
    // onAutofillEvent(View view, int childId, int event) instead.
    @Override
    public void onAutofillEvent(@NonNull View view, int event) {
        super.onAutofillEvent(view, event);
        switch (event) {
            case EVENT_INPUT_HIDDEN:
                // The autofill affordance associated with the view was hidden.
                break;
            case EVENT_INPUT_SHOWN:
                // The autofill affordance associated with the view was shown.
                break;
            case EVENT_INPUT_UNAVAILABLE:
                // Autofill isn't available.
                break;
        }
    }
});

需要移除回呼時,請使用 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 系統會啟動服務的驗證活動,做為活動堆疊的一部分。

您不需要更新應用程式以支援驗證,因為驗證會在服務中進行。不過,您必須確保在活動重新啟動後保留活動的檢視畫面結構 (例如,透過在onCreate() 中建立檢視畫面結構,而非在onStart()onResume() 中建立)。

您可以透過使用 AutocompleteFramework 範例中的 HeuristicsService,並將其設為需要填寫回覆驗證,藉此確認應用程式在自動填入功能需要驗證時所執行的行為。您也可以使用 BadViewArchitectureCreationSignInActivity 範例來模擬此問題。

將自動填入 ID 指派至回收檢視畫面

回收檢視畫面的容器 (例如 RecyclerView 類別) 對於需要根據大型資料集顯示元素捲動清單的應用程式非常實用。容器捲動時,系統會重複使用版面配置中的檢視畫面,但該檢視畫面會包含新的內容。如果檢視畫面的初始內容已填寫,自動填入服務會使用其自動填入 ID 保留檢視畫面的邏輯意義。當系統重複使用版面配置中的檢視畫面,而檢視畫面的邏輯 ID 保持不變,導致錯誤的自動填入使用者 資料與自動填入 ID 建立關聯時,就會發生問題。

如要在搭載 Android 9 (API 級別 28) 以上版本的裝置上解決這個問題,您可以使用以下新方法明確管理 RecyclerView 使用的檢視畫面自動填入 ID:

  • getNextAutofillId() 方法可取得對活動而言唯一的新自動填入 ID。
  • setAutofillId() 方法可在活動中設定此檢視畫面唯一、邏輯的自動填入 ID。

解決已知問題

本節介紹自動填入架構中已知問題的解決方法。

Android 8.0、8.1 的自動填入功能導致應用程式當機

在 Android 8.0 (API 級別 26) 和 8.1 (API 級別 27) 中,自動填入功能可能會導致應用程式在某些情境下出現當機情形。為解決潛在問題,請使用 importantForAutofill=no 標記所有不需自動填入的檢視畫面。您也可以使用 importantForAutofill=noExcludeDescendants 標記整個活動。

調整大小後的對話方塊不適用自動填入

在 Android 8.1 (API 等級 27) 以下版本中,如果對對話方塊中已顯示的檢視畫面調整大小,該檢視畫面就不會自動填入。這類檢視畫面不包含在 Android 系統傳送至自動填入服務的 AssistStructure 物件中。因此,該服務無法為檢視畫面填入內容。

如要解決這個問題,請將對話方塊視窗參數的 token 屬性替換為建立對話方塊活動的 token 屬性。確認啟用自動填入功能後,請將視窗參數儲存在繼承自 Dialog 的類別中的 onWindowAttributesChanged() 方法。接著,將已儲存參數的 token 屬性替換為 onAttachedToWindow() 方法中父項活動的 token 屬性。

下列程式碼片段顯示實作解決方法的類別:

Kotlin

class MyDialog(context: Context) : Dialog(context) {

    // Used to store the dialog window parameters.
    private var token: IBinder? = null

    private val isDialogResizedWorkaroundRequired: Boolean
        get() {
            if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O || Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
                return false
            }
            val autofillManager = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                context.getSystemService(AutofillManager::class.java)
            } else {
                null
            }
            return autofillManager?.isEnabled ?: false
        }

    override fun onWindowAttributesChanged(params: WindowManager.LayoutParams) {
        if (params.token == null && token != null) {
            params.token = token
        }

        super.onWindowAttributesChanged(params)
    }

    override fun onAttachedToWindow() {
        if (isDialogResizedWorkaroundRequired) {
            token = ownerActivity!!.window.attributes.token
        }

        super.onAttachedToWindow()
    }

}

Java

public class MyDialog extends Dialog {

    public MyDialog(Context context) {
        super(context);
    }

    // Used to store the dialog window parameters.
    private IBinder token;

    @Override
    public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
        if (params.token == null && token != null) {
            params.token = token;
        }

        super.onWindowAttributesChanged(params);
    }

    @Override
    public void onAttachedToWindow() {
        if (isDialogResizedWorkaroundRequired()) {
            token = getOwnerActivity().getWindow().getAttributes().token;
        }

        super.onAttachedToWindow();
    }

    private boolean isDialogResizedWorkaroundRequired() {
        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O
                || Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
            return false;
        }
        AutofillManager autofillManager =
                null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            autofillManager = getContext().getSystemService(AutofillManager.class);
        }
        return autofillManager != null && autofillManager.isEnabled();
    }

}

為避免不必要的作業,以下程式碼片段說明如何檢查裝置是否支援自動填入功能、是否針對目前的使用者啟用這項功能,以及是否需要此解決方法:

Kotlin

// AutofillExtensions.kt

fun Context.isDialogResizedWorkaroundRequired(): Boolean {
    // After the issue is resolved on Android, you should check if 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 only available on Android 8.0
        // or higher.
        return false
    }

    val afm = getSystemService(AutofillManager::class.java)
    // Return true if autofill is supported by the device and enabled
    // for the current user.
    return afm != null && afm.isEnabled
}

Java

public class AutofillHelper {

    public static boolean isDialogResizedWorkaroundRequired(Context context) {
        // After the issue is resolved on Android, you should check if 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 only available on Android 8.0
            // or higher.
            return false;
        }

        AutofillManager afm = context.getSystemService(AutofillManager.class);
        // Return true if autofill is supported by the device and enabled
        // for the current user.
        return afm != null && afm.isEnabled();
    }
}

透過自動填入功能測試應用程式

大多數應用程式都支援自動填入服務,不需進行任何變更。不過,您可以將應用程式最佳化,以確保其與自動填入服務達成最有效的運作。 對應用程式進行最佳化後,您應進行測試,確保能與自動填入服務正常搭配使用。

您應使用模擬器或搭載 Android 8.0 (API 級別 26) 以上版本的實體裝置測試您的應用程式。如需進一步瞭解如何建立模擬器,請參閱建立及管理虛擬裝置

安裝自動填入服務

您必須先安裝其他提供自動填入服務的應用程式,才能使用自動填入功能測試應用程式。您可以使用第三方應用程式來達成此目的,但使用範例自動填入服務的做法較為簡單,這樣您就不必註冊任何第三方服務。

您可以使用 Android 自動填入架構範例 Java | Kotlin 使用自動填入服務測試應用程式。範例應用程式提供自動填入服務和用戶端 Activity 類別,您可利用它們測試工作流程,然後再與您的應用程式搭配使用。本頁以 android-AutoFillFramework 範例應用程式為參考。

安裝應用程式後,請在系統設定中啟用自動填入服務。您可依序前往「設定」 > 「系統」 > 「語言與輸入設定」 > 「進階」 > 「輸入協助」 > 「自動填入服務」 來啟用設定。

分析資料需求

如要使用自動填入服務測試應用程式,服務需要有可用來填寫至應用程式的資料。此服務也需要瞭解應用程式檢視畫面所需的資料類型。例如,如果應用程式的檢視畫面需要使用者名稱,則服務應有一個包含使用者名稱的資料集,以及知道檢視畫面需要這類資料的機制。

您應透過設定 android:autofillHints 屬性,讓服務知道檢視畫面所需的資料類型。某些服務會使用複雜的經驗法則來判斷資料類型,但其他服務 (例如範例應用程式) 則仰賴開發人員提供這項資訊。如果您在與自動填入功能相關的檢視畫面中設定 android:autofillHints 屬性,您的應用程式就能更好地與自動填入服務搭配使用。

執行測試

分析資料要求後,您可以執行測試,包括將測試資料儲存在自動填入服務,並在應用程式中觸發自動填入功能。

在服務中儲存資料

下列步驟說明如何將資料儲存在目前使用中的自動填入服務:

  1. 開啟包含一個特定檢視畫面的應用程式,該檢視畫面需要您想在測試期間使用的資料類型。android-AutoFillFramework 範例應用程式會為使用者介面提供需要多種資料類型 (例如信用卡號碼和使用者名稱) 的檢視畫面。
  2. 輕觸包含您所需資料類型的檢視畫面。
  3. 在檢視畫面中輸入值。
  4. 輕觸確認按鈕,例如「登入」「提交」

    通常必須先提交表單,服務才能嘗試儲存資料。

  5. 系統會顯示對話方塊,要求您授予儲存資料的權限。對話方塊會顯示目前使用的服務名稱。

    確認這是您要在測試中使用的服務,然後輕觸 「儲存」

如果 Android 未顯示權限對話方塊,或是該服務不是您要在測試中使用的服務,請在系統設定中檢查該服務目前是否正在使用。

觸發應用程式的自動填入功能

下列步驟將說明如何觸發應用程式中的自動填入功能:

  1. 開啟應用程式,然後前往具有您想要測試檢視畫面的活動。
  2. 輕觸應填寫的檢視畫面。
  3. 系統應會顯示自動填入 UI,其中包含可填入檢視畫面的資料集,如圖 1 所示。
  4. 輕觸包含您要使用資料的資料集。檢視畫面應會顯示先前儲存在服務中的資料。
顯示「dataset-2」為可用資料集的自動填入 UI
圖 1. 顯示可用資料集的自動填入 UI。

如果 Android 未顯示自動填入 UI,可以嘗試下列疑難排解選項:

  • 檢查應用程式中的檢視畫面是否使用 android:autofillHints 屬性中正確的值。如需屬性可能的清單,請參閱 View 類別中前面加上 AUTOFILL_HINT 的常數。
  • 檢查 android:importantForAutofill 屬性是否設為應填寫值 (檢視畫面上的 no) 以外的其他值,或設為檢視畫面上 noExcludeDescendants 或其父項值以外的值。