Autofill Framework
사용자는 기기에서 자동 완성(autofill)을 사용하여 양식을 작성하는 시간을 절약할 수 있습니다. Android O는 Autofill Framework 의 도입으로 계정 및 신용 카드 양식 등과 같은 양식을 보다 쉽게 작성합니다. Autofill Framework는 앱과 autofill service 간의 통신을 관리합니다.
Benefits
양식을 작성하는 것은 시간 소모적이며 오류가 발생하기 쉬운 작업입니다. Autofill Framework는 다음과 같은 이점을 제공하여 사용자 환경을 개선합니다.
필드 채우기에 소요되는 시간 단축
- Autofill은 정보를 다시 타이핑하는 시간을 절약합니다.
사용자 입력 오류 최소화
- 입력 오류는 특히 모바일 장치에서 발생하기 쉽습니다.
- 정보를 입력해야하는 필요성을 없앰으로써 오류도 제거됩니다.
Prerequisites
- 앱이 Autofill Framework를 작동하려면 시스템 설정에서 autofill service를 활성화해야 합니다.
- 사용자는 Settings > System > Languages & input > Advanced > Input assistance > Autofill service 에서 autofill service 활성 또는 비활성화 할 수 있습니다.
- 앱은 자동 완성 데이터를 관리하고 다른 앱의 필드를 채우는 autofill service의 역할을 할 수 있습니다.
- autofill service는 자동 완성 데이터를 사용하여 앱의 필드를 완성하기 전에 사용자에게 인증하도록 요구할 수 있습니다.
- 이 인증은 서비스에서 발생하기 때문에 인증 시나리오를 처리하기 위해 앱을 업데이트할 필요가 없습니다.
Optimizing your app for autofill
표준 views를 사용하는 앱은 Autofill Framework를 즉시 사용할 수 있습니다. 하지만, 앱이 프레임워크에서 동작하는 방식을 최적화하기 위해 몇가지 조치를 취할 수 있다.
Ensuring data is available
일부 특수한 경우, 데이터를 Autofill Framework에 저장할 수 있도록 추가 단계를 수행해야 합니다. 예를 들면, Activity는 표준 text views를 사용하여 레이아웃을 제공할 수 있지만 레이아웃을 파괴하고 GLSurfaceView와 같은 자식 views가 없는 레이아웃으로 대체합니다.
이 경우 원래 레이아웃의 데이터는 프레임워크에서 사용할 수 없습니다. 프레임워크에서 데이터를 사용할 수 있게 하려면 원래 레이아웃을 바꾸기 전에 AutofillManager 객체에서 commit() 을 호출해야합니다.
Providing hints for autofill
앱은 autofill service가 username 그리고 passwords 를 나태내는 views와 같은 자동 완성 될 수 있는 각 view의 의미를 제공하여 데이터를 올바르게 분류하도록 도와줍니다.
일반적으로 view에 자동완성은 한가지 방법이 있지만 두가지 유형의 정보를 허용하는 경우 여러 방법이 있을 수 있습니다. 예를 들어 사용자를 식별하는데 사용되는 view는 사용자 이름 또는 전자 메일 주소를 수락할 수 있습니다. 이러한 힌트는 android:autofillHints 속성 또는 setAutofillHints() 메소드를 사용하여 설정할 수 있습니다.
Autofill Framework는 힌트의 유효성을 검사하지 않고, autofil service에 그대로 전달됩니다. 따라서 어떤 값이든 가질 수 있지만 사용자 이름에 AUTOFILL_HINT_USERNAME, 신용카드 번호에 AUTOFILL_HINT_CREDIT_CARD_NUMBER 와 같은 미리 정의된 값을 사용하는 것이 좋습니다.
Mark fields as important for autofill
앱의 개별 필드가 자동 완성을 위한 view 구조에 포함되어야 하는지 여부를 시스템에 알릴 수 있습니다. setImportantForAutofill() 메소드를 사용하여 뷰가 자동 완성에 중요한지 여부를 결정할 수 있습니다. 기본적으로 뷰는 IMPORTANT_FOR_AUTOFILL_AUTO 모드를 사용합니다. 안드로이드는 휴리스틱 방법으로 뷰가 autofill 에 중요한지 여부를 결정합니다.
- 휴리스틱 : 시간이나 정보가 불충분하여 합리적인 판단을 할 수 없거나, 굳이 체계적이고 합리적인 판단을 할 필요가 없는 상황에서 신속하게 사용하는 어림짐작의 기술
뷰, 뷰 구조 또는 전체 activity가 autofill에 있어서 중요하지 않은 경우가 있습니다.
-
로그인 activity의 보안 문자 필드는 자동완성에 있어 중요하지 않습니다. 이와 같은 경우 뷰를 IMPORANT_FOR_AUTOFILL_NO로 표시할 수 있습니다.
-
사용자가 텍스트 또는 스프레드 시트와 같은 컨텐츠를 생성하는 뷰에서 전체 뷰 구조는 일반적으로 자동 완성에 있어서 중요하지 않습니다. 이와 같은 경우 뷰를 IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS로 표시하여 모든 하위 항목이 자동 완성에 중요하지 않은 것으로 표시할 수 있습니다.
-
게임 플레이를 표시하는 것과 같은 게임 앱 내의 일부 activities 에서는 자동 완성을 위해 해당 activities 안의 뷰는 중요하지 않습니다. 루트 뷰를 IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS로 표시하여 activity의 모든 뷰가 자동완성에 중요하지 않음으로 표시할 수 있습니다.
Force an autofill request (자동 완성 요청 강제 실행)
때로는 사용자 작업에 대한 응답으로 자동 완성 요청을 수행해야 할 수도 있습니다. 예를 들어, TextView는 사용자가 뷰를 길게 누르면 자동 완성 메뉴 항목을 제공합니다.
다음 코드 예제에서는 자동 채우기 요청을 강제로 적용하는 방법을 보여줍니다.
public void eventHandler(View view) {
AutofillManager afm = context.getSystemService(AutofillManager.class);
if (afm != null) {
afm.requestAutofill();
}
}
Determine if autofill is enabled (자동 완성 사용 여부 결정)
사용자가 자동 완성을 사용할 수 있는 경우 앱에 추가 자동 완성 기능을 구현할 수 있습니다. 예를 들어, 자동 완성 기능이 사용자에게 사용될 경우 TextView는 overflow menu에 자동 완성 항목을 보여줍니다. 사용자에 대해 자동 완성 기능이 사용 가능한지 확인하려면 AutofillManager 객체의 isEnabled()메서드를 호출합니다.
Support for custom views (사용자 정의 뷰 지원)
사용자 정의 뷰는 자동완성 API를 사용하여 Autofill Framework에 노출되는 메타 데이터를 지정할 수 있습니다. 일부 뷰는 OpenGL 렌더링 된 UI가 포함된 뷰와 같은 가상 children의 컨테이너 역할을 합니다. 이러한 뷰는 Autofill Framework로 작업하기 전에 API를 사용하여 앱에서 사용되는 정보의 구조를 지정해야 합니다.
앱이 커스텀 뷰를 사용하는 경우 다음 시나리오를 고려해야 합니다.
- 커스텀 뷰는 기본적으로 표준 뷰 구조라고 하는 부르는 뷰 구조를 제공합니다.
- 커스텀 뷰는 Autofill Framework에서 사용할 수 없는 뷰 구조를 가지고 있습니다. 이러한 유형의 뷰 구조를 가상 구조라고 합니다.
Custom views with standard view structure (표준 뷰 구조로 된 커스텀 뷰)
커스텀 뷰는 자동완성이 작동하는데 필요한 메타데이터를 정의할 수 있습니다. 커스텀 뷰가 Autofill Framework에서 동작하도록 메타데이터를 적절하게 관리하는지 확인해야 합니다. 커스텀 뷰는 다음 조치를 취해야 합니다.
- 프레임워크가 앱에 보내지는 자동 완성 값을 처리합니다.
- 프레임워크에 자동 완성 유형 및 값을 제공하십시요
자동완성이 실행되면 Autofill Framework는 뷰에서 autofill()을 호출하고 뷰에서 사용해야하는 값들을 보냅니다. 커스텀 뷰에서 자동완성 값을 처리하는 방법을 지정하려면 autofill()을 구현해야 합니다.
뷰는 getAutofillType()과 getAutofillValue() 메서드를 오버라이딩하여 자동완성 유형과 값을 지정해야 합니다. 이 코드를 추가하면 적절한 자동완성 유형과 값을 프레임워크게 제공할 수 있습니다.
마지막으로, 사용자가 현재 상태에서 뷰에 대한 값을 제공할 수 없는 경우 (예: 뷰가 disabled된 경우) 자동완성은 뷰를 채우지 않아야 합니다. 이 경우 getAutofillType() 및 getAutofillValue()는 null을 반환하고 autofill()은 아무것도 수행하지 않아야 합니다. 다음과 같은 경우 프레임워크 내에서 올바르게 작동하려면 추가 단계가 필요합니다.
- 커스텀 뷰를 편집할 수 있습니다.
- 커스텀 뷰에 중요한 데이터가 포함되어 있습니다.
The custom view is editable
뷰를 편집할 수 있는 경우 AutofillManager 객체에서 notifyValueChanged()를 호출하여 변경 사항을 Autofill Framework에 알려야 합니다.
The custom view contains sensitive data
뷰에 전자 메일 주소, 신용 카드 번호 및 패스워드와 같은 개인 식별 정보(PII)가 포함되어 있는 경우 뷰에 표시해야 합니다. 일반적으로 정적 리소스에서 가져온 컨텐트의 뷰에는 중요한 데이터가 없지만 동적으로 설정된 컨텐트에는 중요한 데이터가 포함될 수 있습니다. 뷰에 중요한 데이터가 포함되어 있는지 여부를 표시하려면 onProvideAutofillStructure()를 구현하고 ViewStructure 객체에서 setDetalsSensitive()를 호출합니다.
다음 코드 예제에서는 뷰 구조의 데이터를 중요한 것으로 표시하는 방법을 보여줍니다.
@Override
public void onProvideAutofillStructure(ViewStructure structure, int flags) {
super.onProvideAutofillStructure(structure, flags);
// Content that comes from static resources is generally not sensitive
boolean sensitive = !contentIsSetFromResources();
structure.setDataIsSensitive(sensitive);
}
만약, 뷰가 미리 정의된 값만 허용한다면 이 뷰를 자동완성하는데 사용할 수 있는 옵션을 설정하는 setAutofilOptions() 메소드를 사용할 수 있습니다. 특히, 자동완성 유형이 AUTOFILL_TYPE_LIST인 뷰는 뷰를 채울 수 있는 옵션을 알고 있을 경우 자동완성 서비스가 더 나은 작업을 수행할 수 있기 때문에 이 메소드를 사용해야 합니다.
Spinner와 같은 어댑터를 사용하는 뷰가 비슷한 경우입니다. 예를 들어, 신용카드 만료 필드에서 동적으로 생성된 연도를 제공하는 spinner는 연도 목록을 제공하기 위한 Adapter interface의 getAutofillOptions() 메소드를 구현해야 합니다.
ArrayAdapter를 사용하는 뷰는 값의 목록을 제공할 수 있습니다. ArrayAdapter가 정적 리소스에 대한 자동완성 옵션을 자동으로 설정하더라도 동적으로 값을 제공하면 getAutofillOptions()를 재정의해야 합니다.
Custom views with virtual structure (가상 구조의 사용자 뷰)
Autofill Framework는 앱의 UI에 정보를 편집하고 저장하기 전에 뷰의 구조가 필요합니다. 프레임워크에서 뷰 구조를 사용할 수 없는 몇 가시 상황이 있습니다.
- 앱이 OpenGL과 같은 저수준 렌더링 엔진을 사용하여 UI를 렌더링합니다.
- 앱이 Canvas 인스턴스를 사용하여 UI를 그립니다.
이 경우 onProvideAutofillVirtualStructure()를 구현하고 다음 단계에 따라 뷰 구조를 지정할 수 있습니다.
- addChildCount()를 호출하여 뷰 구조체의 자식 수를 늘리십시요
- newChild()를 호출하여 자식을 추가합니다.
- setAutofillId()를 호출하여 자식에 대한 자동완성 ID를 설정합니다.
- 자동완성 값과 유형과 같은 속성을 설정합니다.
- 가상 자식의 데이터가 중요한 경우, setDataIsSensitive()에 true를 전달하고 그렇지 않으면 false를 전달해야 합니다.
다음 코드 예제에서는 가상 구조에 새 자식을 만드는 방법을 보여줍니다.
@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()을 호출합니다.
Using callbacks on autofill events (자동 완성 이벤트 콜백 사용)
앱은 자체 자동완성(autocomplete) 뷰를 제공할 수 있습니다. 앱이 그렇게 하는 경우 UI 자동완성 기능의 변경에 따라 뷰를 사용 또는 사용중지하도록 앱에 지시하는 메커니즘이 필요합니다.
이 클래스는 뷰와 연결된 자동 완성 상태가 변경된 후에 앱이 호출하는 onAutofillEvent(View, int) 메서드를 제공합니다. 또한 앱에서 가상 뷰와 함께 사용할 수 있는 childId 매개 변수가 포함된 오버로드된 버전의 메소드입니다. 사용 가능한 상태는 콜백의 상수로 정의됩니다.
AutofileManager 클래스의 registerCallback(AutofillCallback) 메서드를 사용하여 콜백을 등록 할 수 있습니다.
다음 코드 예제에서는 자동 채우기 이벤트에 대한 콜백을 선언하는 방법을 보여줍니다.
AutofillManager afm = this.getSystemService(AutofillManager.class);
afm.registerCallback(new AutofillManager.AutofillCallback() {
// For virtual structures, override
// onAutofillEvent(View view, int childId, int event) instead
@Override
public void onAutofillEvent(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 is not available.
break;
}
}
});
콜백을 제거할 시간이되면 unregisterCallback(AutofillCallback) 메서드를 사용합니다.
Android O 변경사항
Android Autofill Framework가 자동 완성 기능을 기본적으로 지원하므로 Android O를 실행하는 기기에 설치된 앱의 경우 WebView 객체와 관련된 다음 메소드가 변경되었습니다.
WebSettings
- getSaveFormData() 메서드는 false를 반환합니다. 이전에는 이 메소드가 true를 반환했습니다.
- setSaveFormData()를 호출해도 더 이상 효과가 없습니다.
WebViewDatabase
- clearFormData()를 호출해도 더 이상 효과가 없습니다.
- hasFormData() 메서드는 false를 반환합니다. 이전에는 양식에 데이터가 포함되어 있으면 true를 반환했습니다.