본문 바로가기

안드로이드 Android

Accessibility Service 정리

안녕하세요 LONER 입니다. 오늘은 접근성 서비스를 공부하는겸 정리를 진행하려고 합니다. 제 누추한 설명보다 공식문서가 훨씬 아름답고 자세하게 상세히 나와있으니 참고하시면 좋을겁니다. 현재 영문 개발문서 읽기에 도전하고 있어서 Accessibility Service에 관한 이야기를 영문으로 읽고 한글로 정리하는 일에 도전하고 있습니다.
developer.android.com/guide/topics/ui/accessibility/service?hl=ko#create

 

나만의 접근성 서비스 만들기  |  Android 개발자  |  Android Developers

접근성 서비스는 장애를 가진 사용자 또는 일시적으로 기기와 완벽하게 상호작용할 수 없는 사용자를 지원하기 위해 사용자 인터페이스를 향상하는 애플리케이션입니다. 예를 들어 운전 중이

developer.android.com

0. Accessibility Service (접근성 서비스) 란 무엇인가?

안드로이드 개발문서의 설명!


장애를 앓고 있거나 혹은 비장애인이라도 디바이스와 완벽히 상호작용하기 힘든 사람을 위한 기능입니다. 비장애인 인경우 예를 들어 아이를 돌보고 있거나 운전중이거나 시끄러운 파티에 왔거나 등등의 상황처럼 비장애인이라도 기기를 다루기 힘든 상태일 때 안드로이드 사용을 수월하게 사용할 수 있도록 지원하기 위한 기능입니다.

의미가 있는 접근성 서비스


그리고 기본적으로 Accessibility Service는 음성안내 지원 서비스가 됩니다. 그리고 개발자가 원하는 형태로 Accessibility Service 기능을 커스텀 할 수 있습니다. 위 공식문서 내용에서는 나만의 접근성 서비스 만들기 라는 주제로 기본적으로 접근서 서비스를 어떻게 시작하고 어떻게 사용하는지 설명부터 자세히 나와있습니다. 

Accessibility Service는 과거 안드로이드 1.6에서 부터 도입이 되었고, 안드로이드 4.0 릴리즈 부터 크게 개선했었다고 합니다. 그리고 안드로이드 4.0에 도입된 고급 접근성을 개발 할것을 권장합니다.


1. Accessibility Service 만들기

package com.example.android.apis.accessibility

import android.accessibilityservice.AccessibilityService
import android.view.accessibility.AccessibilityEvent

class MyAccessibilityService : AccessibilityService() {
...
    override fun onInterrupt() {}

    override fun onAccessibilityEvent(event: AccessibilityEvent?) {}
...
}

기본적으로 프로젝트 내에서 클래스에 AccssibilityService()를 상속 받아 사용 하고 두 개의 함수를 재정의 합니다.  onInterrupt() 사용자가 다른 컨트롤로 포커스를 옮기는 등 서비스가 제공 중인 피드백을 중단하려는 경우 호출되는 메서드입니다. 이 함수는 사용자가 사용하다보면 여러번 호출 될 수 있다고 합니다. 

수퍼 클래스에서 추상 함수로 정의되어 있기 때문에 필수로 사용해야 합니다. 


접근성 피드백을 중단하기 위한 콜백함수고,  onAccessibilityEvent() 함수는 AccessibilityEvent를 감지하면 다시 호출됩니다. 예를 들어 접근성 서비스이 진행중인 상황에서 어떠한 버튼을 사용자가 버튼을 클릭했을 때 이 메서드가 호출됩니다. 이 함수도 사용자가 사용하다보면 여러번 호출 되는 경우가 많다고 합니다.

이 메서드 또한 추상함수 이기 때문에 꼭 필수로 사용하라고 지정한 함수입니다.

onInterrupt()이나 혹은 onAccessibilityEvent() 함수를 클래스를 상속받아 반드시 필수로 재정의 해줘야하고 이 두 함수 말고도 필요하면 불러와 재정의 할 수 있는 함수가 몇가지 있습니다. 항상 선택 사항은 개발자의 센스껏 가져와 사용하면 좋을 것 같습니다. 

하지만 Accessibility Service Class 를 상속받아 사용하기전에 반드시 체크 할것이 있습니다. 

 

1-2. Accessibility Service 만들기 - Manifest 선언 

서비스를 상속받는다.

Accessibility Service도 엄연히 서비스를 상속 받아 만들어졌기 때문에 Manifest에 AccessibilityService를 상속받은 클래스를 등록해야 사용 할 수 있습니다. (액티비티, 서비스, 브로드 캐스트 리시버, 컨텐츠 프로바이더 4대컴포넌트는 매니 패스트에 등록해야 사용 가능합니다.)

매니페스트 서비스 선언 


그래서 Service 요소로 해당 클래스명의 이름을 정해줍니다. android 4.1 이상과 호환이 되기 위해 시스템에서만 서비스를 연결 하도록 BIND_ACCESSIBILITY_SERVICE 권한을 추가해야 하고 인텐트 필터도 추가를 해야합니다. 위 같은 선언들은 안드로이드 4.1 이상 부터 반드시 설정 해야합니다. 

**저 위에 Accessibility Service 클래스가 언급된 김에 이야기를 하자면 접근성 서비스는 기본적으로 서비스의 생명주기를 따라갑니다. 그래서 재정의 할 선택 함수로 onServiceConnected()가 존재합니다. 기본적으로 직접 서비스를 끄거나 전화가 왔을 때만 중지됩니다.**



1-3. Accessibility Service 만들기 - 접근성 서비스 구성 설정

셋팅

접근성 서비스는 서비스가 처리하는 접근성 이벤트의 유형을 지정하는 구성 및 서비스에 관한 추가 정보도 제공 할 수 있습니다. 접근성 서비스의 구성은 기본적으로 AccessibilityServiceInfo 클래스에 포함되어 있습니다. 이 클래스의 인스턴스와 setServiceInfo()를 사용해서 구성을 구축 할 수 있습니다.

<service android:name=".MyAccessibilityService">
  ...
  <meta-data
    android:name="android.accessibilityservice"
    android:resource="@xml/accessibility_service_config" />
</service>

앞서 설정 했던 Service 요소안에 접근성 서비스의 모든 옵션을 <meta-data>를 이용하여 참조할 수 있는 요소를 포함 시킬 수 있습니다. android:resource = "@xml/accessibility_service_config" 리소스로 설정한 accessibility_service_config xml 파일을 살펴보자면 예를 들어 이런식으로 옵션 설정이 가능합니다.

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:packageNames="com.example.android.apis"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>

위의 옵션들이 어떤 기능을 하는지 알고 싶다면 공식문서 AccessibilityServiceInfo를 참고하시길 바랍니다. 링크 들어가서 상수 설명란에 자세히 기술되어 있습니다.

 

AccessibilityServiceInfo  |  Android 개발자  |  Android Developers

 

developer.android.com

1-4. Accessibility Service 만들기 - 접근성 서비스 구성 >변수로 설정 

override fun onServiceConnected() {
    info.apply {
        eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED or AccessibilityEvent.TYPE_VIEW_FOCUSED
        packageNames = arrayOf("com.example.android.myFirstApp", "com.example.android.mySecondApp")
        feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN
        // flags = AccessibilityServiceInfo.DEFAULT;
        notificationTimeout = 100
    }

    this.serviceInfo = info

}

Accessibility Service를 상속받고 있는 클래스 onServiceConneted() 메서드 안에 info 객체의 속성들을 다시 설정하고 this.serviceInfo = info 를 구성을 설정할 수도 있습니다. 접근성 서비스의 구성은 위에 설정한 xml 뿐만 아니라 이런식으로 코드로 사용이 가능합니다. 
1~4번을 통해 사용하고 싶은 옵션 설정과 함께 같이 셋팅하면 됩니다.

 


2. Accessibility Service 상황에 따라 호출되는 함수 


다시 AccessibilityService Class를 상속받은 클래스에 대해 얘기해보
도록 하겠습니다. 실제 접근성 서비스에 대한 사용자 컨트롤 피드 및 여러 상황들을 이 클래스 안에서 호출되는 함수를 통해 컨트롤 할 수 있습니다. AccessibilityService 안에서 흐름에 따라 호출되는 함수 순서를 살펴보면 크게 4가지가 있습니다.


(서비스 시작 될때)onServiceConnected()  ->

    (실행 동안 반응 대기) onInterrupt() , onAccessibilityEvent() ->


                      (서비스가 종료될때) onUnbind() 으로 진행이 됩니다. 

여기서 onServiceConnected() onUnbind() 는 반드시 꼭 재정의해야할 함수가 아니고 상황에 맞게만 한번씩 호출됩니다. 반면 onInterrupt() , onAccessibilityEvent()는 반드시 재정의해서 사용해야하고 항상 반응을 대기하는 콜백 함수입니다.

그리고 onAccessibilityEvent() 함수에 AccessibilityEvent 패러미터가 존재합니다. 저 패러미터를 이용해서 분기처리를 통해 각각 이벤트에 맞는 다양한 상황 처리를 할 수 잇습니다.

분기처리 예시 사진 

 


3. Accessibility Service 이벤트 등록 

이벤트 등록하는법

접근성 서비스 구성의 가장 중요한 기능 중 하나는 서비승에서 처리 할 이벤트 유형을 지정할 수가 있다는 점 입니다.
크게 2가지 이벤트 필터링이 존재합니다.

패키지 이름 -서비스에서 처리 할 접근성 이벤트가있는 애플리케이션의 패키지 이름을 지정합니다. 
xml로 접근성 서비스의 구성 설정 할 때 android:pakcgeNames 속성을 사용하면 됩니다. 혹은 변수를 통해서 설정할때 AccessibilityServiceInfo.packageNames 멤버를 사용하여 설정 가능합니다. 

이벤트 유형 -서비스에서 처리 할 수있는 접근성 이벤트의 유형을 지정합니다. xml로 접근성 서비스의 구성 설정 할 때 android:accessibilityEventTypes 속성을 사용하면 됩니다. 혹은 변수를 통해서 설정할 때 AccessibilityServiceInfo.eventTypes 멤버를 사용하여 설정 가능합니다. 

 

4. 설명 마무리 

마무리

AccessibilityService를 상속받는 클래스를 만들고 매니페스트 설정과 구성까지 설정하고 난 후 onServiceConnected() , onInterrupt() ,onAccessibilityEvent(), onUnbind() 함수의 흐름안에서 다양한 이벤트를 처리할 수 있습니다. 접근성 서비스의 구체적인 기능들을 구현할때 위 4가지 함수의 범위 혹은 구성 설정에서 크게 벗어나는 경우는 거의 없어보입니다.

이렇게 셋팅만 잘 기억해둔다면 디테일하게 필요한 부분은 그때 안드로이드 문서를 살펴보거나 구글링해서 찾아도 충분히 잘 이용할 거라 생각이 듭니다. 이 포스팅은 접근성 서비스의 중요한 부분을 위주로 영문서 버전으로 안드로이드 공식문서를 읽은 것을 정리해봤습니다. 앞으로 더 이어서 문서 마무리까지 다 포스팅을 이어가보도록 하겠습니다.