23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
디지털 어시스턴트 앱은 사용자의 음성 명령을 통해 디바이스와 자연스럽게 상호작용할 수 있도록 설계된 애플리케이션입니다.
이 앱은 VoiceInteractionService를 기반으로 동작하며, 매니페스트 파일에 해당 서비스를 등록함으로써 구현을 시작할 수 있습니다.
실행 중에는 현재 화면에서 텍스트나 이미지 등의 정보를 수집하여, 사용자에게 필요한 도움을 적시에 제공할 수 있습니다.
또한, 시스템 서비스와 연동되어 동작하기 때문에 기본 애플리케이션만 활성 상태로 유지되며, 디바이스 리소스를 보다 효율적으로 사용할 수 있는 장점이 있습니다.
⚠️ 참고 : Hotword 설정은 @SystemApi 로 본 내용에 다루지 않겠습니다
설정 방법: 설정 → 애플리케이션 → 기본 앱 선택 → 디지털 어시스턴트 앱 → 디바이스 도우미 앱
실행 방법: 대부분의 기기에서는 측면 버튼을 길게 눌렀을 때 활성화됩니다. 기기마다 다를 수 있으니 확인이 필요합니다.
디지털 어시스턴트 앱은 일반 앱과는 다른 라이프사이클을 가집니다.
Android의 VoiceInteractionService, VoiceInteractionSessionService, VoiceInteractionSession 세 컴포넌트가 각 역할을 나누어 수행하며,
주요 흐름은 다음과 같습니다:
서비스 초기화
디바이스 부팅 시 VoiceInteractionService가 바인딩되고 onReady()가 호출됩니다.
이 시점에서 시스템에 어시스턴트가 준비되었음을 알립니다.
음성 인터랙션 트리거
사용자가 디바이스 버튼이나 기타 트리거를 통해 어시스턴트를 호출하면
VoiceInteractionSessionService의 onNewSession()이 호출됩니다.
세션 생성 및 표시
VoiceInteractionSessionService에서 새로운 VoiceInteractionSession 인스턴스를 생성하여 반환합니다.
해당 세션에서는 onCreate()와 onShow() 또는 onHide()가 호출되며, 어시스턴트 UI를 표시하거나 숨깁니다.
종료 처리
디바이스 종료, 사용자의 종료 요청 또는 다른 VIS가 선택되면 onShutdown()이 호출되어 서비스가 중단됩니다.
세션도 함께 onDestroy()를 통해 정리됩니다.
💡 Tip :
onNewSession()→onCreate()→onShow()순으로 이어지는 흐름이 핵심입니다.
VoiceInteractionSession내부에서 UI 구성과 사용자 응답 로직을 중심으로 구현하면 됩니다.
<service
android:name=".VoiceInteractionService"
android:exported="false"
android:permission="android.permission.BIND_VOICE_INTERACTION">
<meta-data
android:name="android.voice_interaction"
android:resource="@xml/interaction_service" />
<intent-filter>
<action android:name="android.service.voice.VoiceInteractionService" />
</intent-filter>
</service>
<service
android:name=".VoiceInteractionSessionService"
android:permission="android.permission.BIND_VOICE_INTERACTION"
android:exported="false">
</service><voice-interaction-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:sessionService="com.example.assistant.VoiceInteractionSessionService"
android:settingsActivity="com.example.assistant.VoiceSettingsActivity"
android:supportsAssist="true"
android:supportsLaunchFromKeyguard="true" />sessionService : 어시스턴트를 호출할 때마다 새로운 세션을 생성하고 관리하는 서비스 클래스의 전체 경로를 지정합니다.
settingsActivity : 어시스턴트 앱의 설정 화면을 담당하는 액티비티의 전체 경로를 지정합니다.
supportsAssist : 현재 화면 컨텍스트 정보(텍스트, 뷰 구조 등)를 수집하여 어시스턴트에 제공할지 여부를 지정합니다.
supportsLaunchFromKeyguard : 잠금 화면 상태에서도 어시스턴트를 실행할 수 있는지 여부를 지정합니다.
VoiceInteractionService는 디지털 어시스턴트의 진입점 역할을 합니다. 시스템이 해당 서비스를 호출하면 onReady()가 실행되며, 어시스턴트 사용 준비가 완료되었음을 나타냅니다.
여기서 로깅, 초기 설정, 또는 백그라운드 초기화 작업 등을 수행할 수 있습니다.
class VoiceInteractionService : VoiceInteractionService() {
override fun onReady() {
// 서비스가 시스템에 등록되고 준비되었을 때 호출
super.onReady()
}
}VoiceInteractionSessionService는 어시스턴트 호출 시마다 VoiceInteractionSession을 생성하고 관리하는 역할을 합니다.
onNewSession()에서는 새로운 CustomVoiceInteractionSession을 반환하고, onDestroy()에서는 세션을 해제하여 리소스를 정리합니다.
세션은 일시적인 객체이므로 상태를 오래 유지하지 않도록 주의해야 합니다.
class VoiceInteractionSessionService : VoiceInteractionSessionService() {
companion object {
private var session: VoiceInteractionSession? = null
}
override fun onNewSession(args: Bundle?): VoiceInteractionSession {
// 새 세션 생성
return CustomVoiceInteractionSession(this).also {
session = it
}
}
override fun onDestroy() {
// 세션 종료
session = null
super.onDestroy()
}
}VoiceInteractionSession은 사용자와의 직접적인 상호작용을 담당하는 세션 클래스입니다.
onPrepareShow()는 UI 표시 직전에 호출되며, UI를 사용할지 여부를 설정합니다.
onShow()는 어시스턴트가 활성화될 때 호출되며, 커스텀 Activity를 띄워 직접적인 인터페이스를 제공합니다.
onHandleScreenshot()에서는 시스템이 전달하는 스크린샷을 받아 이미지 기반 분석을 수행할 수 있고,
onHandleAssist()에서는 Assist 구조 정보(텍스트, 뷰 계층 등)를 활용하여 풍부한 컨텍스트를 기반으로 사용자 지원이 가능합니다.
class CustomVoiceInteractionSession(context: Context) : VoiceInteractionSession(context) {
override fun onPrepareShow(args: Bundle?, showFlags: Int) {
super.onPrepareShow(args, showFlags)
// true 설정시 onCreateContentView() 호출됨
setUiEnabled(false)
}
override fun onShow(args: Bundle?, showFlags: Int) {
// 시스템 다이얼로그 닫기
closeSystemDialogs()
// 커스텀 어시스턴트 Activity 시작
Intent(context, VoiceInteractiveActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TASK or
Intent.FLAG_ACTIVITY_NO_ANIMATION)
}.runCatching {
startAssistantActivity(this)
}.onFailure {
Log.e(TAG, "onShow onFailure:", it)
}
}
override fun onHandleScreenshot(screenshot: Bitmap?) {
super.onHandleScreenshot(screenshot)
// 스크린샷 수신
}
override fun onHandleAssist(data: Bundle?, structure: AssistStructure?, content: AssistContent?) {
super.onHandleAssist(data, structure, content)
// 어시스트 데이터 처리
}
}Voice Interaction Session이 시작되면 시스템은 뷰와 스크린샷을 캡처하고 이 정보를 세션에 전달할 수 있습니다.
애플리케이션은 Activity#onProvideAssistData()와 Activity#onProvideAssistContent()를 구현하여 추가 정보를 어시스턴트 앱으로 전달할 수 있습니다.
앱 개발자는 자신의 앱이 어시스턴트와 효과적으로 상호작용할 수 있도록 다음과 같은 방법으로 최적화할 수 있습니다.
override fun onProvideAssistContent(outContent: AssistContent) {
super.onProvideAssistContent(outContent)
// 구조화된 JSON 데이터 제공
val jsonData = JSONObject().apply {
put("screen_name", "메인 화면")
put("user_action", "검색")
// 기타 관련 정보
}
outContent.structuredData = jsonData.toString()
}VoiceInteractionSession#onHandleAssist()를 통해 AssistStructure 인스턴스로 표시된 텍스트 및 뷰 계층 구조를 수신할 수 있습니다.
이를 통해 현재 화면의 콘텐츠를 분석하고 컨텍스트에 맞는 응답을 제공할 수 있습니다.
override fun onHandleAssist(state: AssistState) {
super.onHandleAssist(state)
// 구조화된 JSON 데이터 수집
state.assistContent?.let {
val text = it.structuredData
Log.d(TAG, "onHandleAssist state text: $text")
}
}VoiceInteractionSession#onHandleScreenshot()을 통해 스크린샷을 수신합니다.
이 스크린샷을 분석하여 시각적 콘텐츠를 이해하고 추가 컨텍스트를 제공할 수 있습니다.
override fun onHandleScreenshot(screenshot: Bitmap?) {
super.onHandleScreenshot(screenshot)
screenshot?.let {
// 이미지 처리 및 분석
val imageAnalyzer = ScreenImageAnalyzer()
val analysisResult = imageAnalyzer.analyze(it)
// 분석 결과를 기반으로 응답 생성
processImageAnalysisResult(analysisResult)
}
}디지털 어시스턴트 앱은 사용자의 음성 명령을 기반으로 디바이스와 상호작용할 수 있는 기능을 제공합니다.
Android의 VoiceInteractionService를 활용하면 디지털 어시스턴트를 손쉽게 구현할 수 있으며, 이를 통해 사용자 경험을 크게 향상시킬 수 있습니다.
또한, 화면 콘텐츠 분석, 스크린샷 처리, 구조화된 데이터 제공 등 다양한 기능을 통해 사용자에게 맞춤형 도움을 제공할 수 있습니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.