mune diary

Hello, World!

Android Autofill Framework を使ってみる

Autofill Framework is 何?

Autofill Framework とは、Google アカウントに登録されているパスワードやクレジットカードなどのデータをフォームに自動で入力してくれる便利なやつです。簡単に導入することができるのでサクッと紹介していきます。 developer.android.com

完成イメージ

今回はクレジットカードの登録画面を作り、自動入力に対応させていきます。(あんま作ることなさそうだけど…)
f:id:mune0903:20201230195021p:plain:w200
自前のクレカを登録しているので、Gif 等を貼り付けできずスクショになりますがこのように登録されているクレカが表示されます。完成コードは公開しているのでそちらで動作をみてください。
github.com

コード(MainActivity.kt)

.xml には入力フォームがあればOKです👌

class MainActivity : AppCompatActivity() {
    private val binding: ActivityMainBinding by lazy {
        DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            setupAutofill()
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun setupAutofill() {
        binding.apply {
            activityMainCreditcardNumberEditText.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_NUMBER)
            activityMainCreditcardMonthExpire.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH)
            activityMainCreditcardYearExpire.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR)
            activityMainCreditcardSecurityCodeEditText.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE)
        }

        val month = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
        val months = (0..11)
            .map { month[it].toString() }
            .toTypedArray<CharSequence>()

        val year = Calendar.getInstance().get(Calendar.YEAR)
        val years = (0..10)
            .map { (year + it).toString() }
            .toTypedArray<CharSequence>()

        binding.activityMainCreditcardYearExpire.adapter = object : ArrayAdapter<CharSequence?>(this,
            android.R.layout.simple_spinner_item, years) {
            override fun getAutofillOptions() = years
        }

        binding.activityMainCreditcardMonthExpire.adapter = object : ArrayAdapter<CharSequence?>(this,
            android.R.layout.simple_spinner_item, months) {
            override fun getAutofillOptions() = months
        }
    }
}

フォームを自動入力に対応させる

コンポーネントsetAutofillHints()で自動入力に対応させますよと明示してあげるだけです!
クレカ以外にもパスワード・メアド・名前などの情報も自動入力させることができるみたいです。

Spinner への自動入力

クレカの有効期限入力は Spinner であることはよく見かけますが、activityMainCreditcardMonthExpire.setAutofillHints(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH)させるだけでは自動入力されません。Adapter を使う Spinner だと、入力値ではなくその入力値に対応する index を渡してあげないといけないからです。この問題は Adapter インターフェースの getAutofillOptions() メソッドに Autofill が取得してきた値と一致する index を渡してあげるよう override させて実装してあげれば解決できます。

val month = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
        val months = (0..11)
            .map { month[it].toString() }
            .toTypedArray<CharSequence>()

binding.activityMainCreditcardMonthExpire.adapter = object : ArrayAdapter<CharSequence?>(this,
            android.R.layout.simple_spinner_item, months) {
            override fun getAutofillOptions() = months
        }

Android 8.0(API レベル 26)未満だとクラッシュする😇

Build.VERSION.SDK_INTが 26 以上かどうかみてあげましょう。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    setupAutofill()
}