연결된 디스플레이 지원

연결된 디스플레이는 데스크톱 창 관리 환경을 표준 휴대전화로 확장하여 사용자가 모바일 기기에서 대형 화면에 액세스할 수 있도록 지원합니다. 이 기능을 통해 앱 상호작용과 사용자 생산성을 위한 새로운 가능성이 열립니다.

데스크톱 창 모드의 모든 고유한 기능은 연결된 디스플레이에 적용됩니다. 휴대전화를 디스플레이에 연결하면 휴대전화의 상태는 변경되지 않고 연결된 디스플레이에서 빈 데스크톱 세션이 시작됩니다. 기기와 디스플레이는 각각의 디스플레이에 특화된 앱이 있는 두 개의 개별 시스템으로 작동합니다.

그림 1. 휴대전화가 외부 디스플레이에 연결되어 있고 디스플레이에 데스크톱 세션이 표시되며 휴대전화는 자체 상태를 유지합니다.

태블릿과 같은 데스크톱 창 모드 지원 기기를 외부 모니터에 연결하면 데스크톱 세션이 두 디스플레이로 확장됩니다. 그러면 두 디스플레이가 하나의 연속 시스템으로 작동합니다. 이 설정을 사용하면 창, 콘텐츠, 커서가 두 디스플레이 사이를 자유롭게 이동할 수 있습니다.

그림 2. 태블릿이 외부 모니터에 연결되어 데스크톱 세션이 두 디스플레이로 확장됩니다.

연결된 디스플레이를 효과적으로 지원하려면 앱의 디자인과 구현의 여러 측면에 주의를 기울여야 합니다. 다음 권장사항을 따르면 원활하고 생산적인 사용자 환경을 보장할 수 있습니다.

동적 디스플레이 변경사항 처리

많은 앱이 앱의 수명 주기 동안 Display 객체와 그 특성이 변경되지 않는다는 가정하에 빌드됩니다. 하지만 사용자가 외부 모니터를 연결하거나 연결 해제하거나 디스플레이 간에 앱 창을 이동하는 경우에도 앱의 컨텍스트 또는 창과 연결된 기본 Display 객체가 변경될 수 있습니다. 크기, 해상도, 화면 재생 빈도, HDR 지원, 밀도와 같은 디스플레이 속성은 모두 다를 수 있습니다. 휴대전화 화면을 기반으로 값을 하드코딩하면 외부 디스플레이에서 레이아웃이 깨질 수 있습니다.

외부 디스플레이의 픽셀 밀도도 크게 다를 수 있습니다. 앱이 밀도 변경에 올바르게 응답하는지 확인해야 합니다. 여기에는 레이아웃에 밀도 독립형 픽셀 (dp)을 사용하고, 밀도별 리소스를 제공하고, UI가 적절하게 확장되도록 하는 작업이 포함됩니다.

디스플레이가 연결 해제될 때 활동이 외부 디스플레이에서 실행 중이면 시스템은 활동을 기본 디스플레이로 이동합니다. 이 이동으로 인해 화면 크기 및 밀도 변경과 같은 구성 변경이 트리거되어 활동이 다시 생성될 수 있습니다. 앱은 데이터 손실이나 혼란스러운 사용자 환경을 방지하기 위해 UI 상태를 저장하고 복원하여 구성 변경을 처리해야 합니다.

올바른 맥락 사용

다중 디스플레이 환경에서는 올바른 컨텍스트를 사용하는 것이 매우 중요합니다. 리소스에 액세스하는 경우 활동 컨텍스트 (표시됨)와 애플리케이션 컨텍스트 (표시되지 않음)가 서로 다릅니다.

활동 컨텍스트는 디스플레이 정보를 포함하며 활동이 표시되는 디스플레이 영역에 맞게 항상 조정됩니다. 이를 통해 앱의 화면 밀도 또는 창 측정항목에 관한 올바른 정보를 얻을 수 있습니다. 현재 창 또는 디스플레이에 관한 정보를 얻으려면 항상 활동 컨텍스트 (또는 다른 UI 기반 컨텍스트)를 사용하세요. 이는 컨텍스트의 정보를 사용하는 일부 시스템 API에도 영향을 미칩니다.

Jetpack Compose에서는 LocalConfiguration.currentLocalDensity.current과 같은 CompositionLocal 객체를 사용하여 디스플레이 관련 정보에 액세스할 수 있습니다. 활동이나 창이 디스플레이 간에 이동하면 기기 구성이 변경되어 새로운 디스플레이 측정항목으로 리컴포지션이 트리거됩니다. CompositionLocal 객체를 사용하면 UI가 원활하게 적응할 수 있습니다.

디스플레이 정보 가져오기

Display 클래스를 사용하여 디스플레이 크기, 밀도, 플래그와 같은 정보를 가져올 수 있습니다. DisplayManager 시스템 서비스를 사용하여 사용 가능한 디스플레이를 가져옵니다. 외부 디스플레이를 식별하려면 일반적으로 내장 휴대전화 또는 태블릿 화면인 Display.DEFAULT_DISPLAY를 필터링합니다.

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }

활동 시작 및 구성 관리

연결된 디스플레이를 사용하면 앱이 실행될 때 또는 다른 활동을 만들 때 앱이 실행될 디스플레이를 지정할 수 있습니다. 이 동작은 매니페스트 파일에 정의된 활동 시작 모드와 활동을 실행하는 항목에 설정된 인텐트 플래그 및 옵션에 따라 달라집니다.

활동이 보조 디스플레이로 이동하면 앱에서 컨텍스트 업데이트, 창 크기 조절, 구성 및 리소스 변경이 발생할 수 있습니다. 활동이 구성 변경을 처리하면 onConfigurationChanged()로 알림을 받습니다. 그렇지 않으면 활동이 다시 실행됩니다.

활동에 선택된 시작 모드에서 다중 인스턴스가 허용되는 경우 보조 화면에서 활동을 실행하면 새 활동 인스턴스가 만들어질 수 있습니다. 두 활동이 동시에 재개되므로 특정 멀티태스킹 시나리오에 유용할 수 있습니다.

ActivityOptions을 사용하여 특정 디스플레이에서 활동을 실행할 수 있습니다. launchDisplayId에는 Android 8 (API 수준 26) 이상이 필요합니다.

// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
    .firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
    ?.displayId

// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
    val intent = Intent(this, MySecondaryActivity::class.java)
    val options = ActivityOptions.makeBasic()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        options.launchDisplayId = externalDisplayId
    }
    startActivity(intent, options.toBundle())
} else {
    // Optionally, handle the case where no external display is connected.
}

기기 허용 목록 피하기

앱은 허용 목록을 통해 또는 BUILD.MODEL 및 내장 디스플레이 크기를 확인하여 일부 기기로 대형 화면 UI와 기능을 제한하는 경우가 있습니다. 이 접근 방식은 연결된 디스플레이에는 효과적이지 않습니다. 거의 모든 기기를 대형 화면에 연결할 수 있고 외부 디스플레이가 연결될 때 기기 모델이 변경되지 않기 때문입니다.

허용 목록을 사용하거나 BUILD.MODEL 및 내장 디스플레이 크기를 확인하는 대신 런타임에 창 측정항목 또는 기기 기능을 확인하여 UI를 결정하세요. Jetpack WindowManager API 또는 창 크기 클래스를 사용하여 다양한 화면 크기와 밀도에 맞게 반응형 및 적응형 레이아웃을 빌드합니다.

외부 주변기기 지원

사용자가 외부 디스플레이에 연결하면 데스크톱과 유사한 환경을 만드는 경우가 많습니다. 이러한 작업에는 외부 키보드, 마우스, 트랙패드, 웹캠, 마이크, 스피커를 사용하는 경우가 많습니다. 앱이 이러한 주변기기와 원활하게 작동하는지 확인해야 합니다. 여기에는 단축키 처리, 마우스 포인터 상호작용 관리, 외부 카메라 또는 마이크 올바르게 지원, 오디오 출력 라우팅 준수가 포함됩니다. 자세한 내용은 대형 화면에서의 입력 호환성을 참고하세요.

사용자 생산성 향상

연결된 디스플레이는 사용자 생산성을 개선할 수 있는 중요한 기회를 제공합니다. 이제 데스크톱 애플리케이션과 비교할 만한 환경을 제공하는 모바일 앱을 빌드할 수 있습니다. 다음 기능을 구현하여 사용자 생산성을 높이세요.

  • 사용자가 동일한 앱의 여러 인스턴스를 열 수 있습니다. 이는 문서 비교, 여러 대화 관리, 여러 파일 동시 보기와 같은 작업에 매우 유용합니다.
  • 사용자가 드래그 앤 드롭을 사용하여 앱 안팎으로 다양한 데이터를 공유할 수 있도록 지원합니다.
  • 강력한 상태 관리 시스템을 구현하여 사용자가 구성 변경 시 워크플로를 유지하도록 지원하세요.

이 가이드라인을 따르고 제공된 코드 예시를 활용하면 연결된 디스플레이에 원활하게 적응하는 앱을 만들어 사용자에게 더 풍부하고 생산적인 환경을 제공할 수 있습니다.