Android 8.0(API 수준 26)부터 Android에서 활동을 PIP 모드로 실행할 수 있습니다. PIP는 주로 동영상 재생에 사용되는 특수한 유형의 멀티 윈도우 모드입니다. 사용자가 기본 화면에서 앱 간에 이동하거나 콘텐츠를 탐색할 때 화면 모서리에 고정된 작은 창에서 동영상을 볼 수 있습니다.
PIP는 Android 7.0에서 사용할 수 있는 멀티 윈도우 API를 활용하여 고정 동영상 오버레이 창을 제공합니다. PIP를 앱에 추가하려면 PIP를 지원하는 활동을 등록하고 필요한 경우 활동을 PIP 모드로 전환하며 활동이 PIP 모드일 때 UI 요소를 숨기고 동영상 재생이 지속되게 해야 합니다.
PIP 창은 화면 맨 윗부분에서 다음에 의해 선택한 모서리에 표시됩니다. 있습니다.
PIP는 다음을 실행하는 호환 Android TV OS 기기에서도 지원됩니다. Android 14 (API 수준 34) 이상 많은 유사점이 있지만 추가적으로 고려해야 할 사항 TV PIP
사용자가 PIP 창과 상호작용하는 방법
사용자는 PIP 창을 다른 위치로 드래그할 수 있습니다. Android 12부터 사용자는 다음 작업도 수행할 수 있습니다.
창을 한 번 탭하여 전체 화면 전환, 닫기 버튼, 설정 버튼 및 앱에서 제공하는 맞춤 작업(예: 재생 컨트롤 기능)을 표시합니다.
창을 두 번 탭하여 현재 PIP 크기와 최대 크기 간에 전환합니다. 또는 최소 PIP 크기(예: 최대화된 창을 두 번 탭) 그 반대의 경우도 마찬가지입니다.
창을 왼쪽 또는 오른쪽 가장자리로 드래그하여 숨길 수 있습니다. 숨겨진 아이템을 숨겨진 창의 보이는 부분을 탭하거나 밖으로 드래그합니다.
손가락으로 모으거나 펼쳐 확대/축소하여 PIP 창 크기를 조절합니다.
앱에서 현재 활동이 PIP 모드로 전환되는 시점을 제어합니다. 다음은 몇 가지 예입니다.
사용자가 홈 버튼을 탭하거나 스와이프하면 활동이 PIP 모드로 전환될 수 있음 집까지. 이것은 Google 지도에서 길찾기를 계속 표시하는 방법입니다. 사용자가 동시에 다른 활동을 실행할 때
사용자가 다시 탐색할 때 앱에서 동영상을 PIP 모드로 전환할 수 있습니다. 다른 콘텐츠를 찾아볼 수 있습니다.
사용자가 콘텐츠 에피소드의 끝을 시청하는 동안 앱에서 동영상을 PIP 모드로 전환할 수 있습니다. 기본 화면에는 시리즈의 다음 에피소드에 관한 홍보 또는 요약 정보가 표시됩니다.
사용자가 동영상을 보는 동안 앱이 추가 콘텐츠를 대기열에 올리는 방법을 제공할 수 있습니다. 기본 컨트롤이 있을 때 동영상이 PIP 모드로 계속 재생됩니다. 콘텐츠 선택 활동이 표시된 화면
PIP 지원 선언
기본적으로 시스템에서는 앱의 PIP를 자동으로 지원하지 않습니다. 원하는 경우
하고, 앱에서 PIP 모드를 지원하려면
android:supportsPictureInPicture
를 true
로 설정합니다. 또한
활동이 레이아웃 구성 변경을 처리하므로
PIP 모드 전환 중에 레이아웃이 변경되면 다시 실행됩니다.
<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"
...
활동을 PIP로 전환
Android 12부터 다음 설정을 통해 활동을 PIP 모드로 전환할 수 있습니다.
setAutoEnterEnabled
플래그를 true
로 설정합니다. 이 설정을 사용하면
명시적으로 전화를 걸지 않아도 필요에 따라 자동으로 PIP 모드로 전환됩니다.
onUserLeaveHint
의 enterPictureInPictureMode()
여기에는
전환이 훨씬 부드러워진다는 장점이 추가되었습니다. 자세한 내용은 만들기
더 원활하게 PIP 모드로 전환할 수 있습니다.
Android 11 이하를 타겟팅하는 경우 활동에서 다음을 호출해야 합니다.
enterPictureInPictureMode()
드림
PIP 모드로 전환합니다. 예를 들어 다음 코드는 활동을
사용자가 앱 UI에서 전용 버튼을 클릭할 때의 PIP 모드:
Kotlin
override fun onActionClicked(action: Action) { if (action.id.toInt() == R.id.lb_control_picture_in_picture) { activity?.enterPictureInPictureMode() return } }
자바
@Override public void onActionClicked(Action action) { if (action.getId() == R.id.lb_control_picture_in_picture) { getActivity().enterPictureInPictureMode(); return; } ... }
대신 활동을 PIP 모드로 전환하는 로직을 포함하는 것이 좋습니다.
매우 중요합니다. 예를 들어 앱에서 탐색하는 동안 사용자가 홈 또는 최근 버튼을 누르면 Google 지도가 PIP 모드로 전환됩니다. onUserLeaveHint()
를 재정의하여 이 케이스를 발견할 수 있습니다.
Kotlin
override fun onUserLeaveHint() { if (iWantToBeInPipModeNow()) { enterPictureInPictureMode() } }
자바
@Override public void onUserLeaveHint () { if (iWantToBeInPipModeNow()) { enterPictureInPictureMode(); } }
권장: 사용자에게 세련된 PIP 전환 환경 제공
Android 12에서는 애니메이션 전환의 외관을 크게 개선했습니다. PIP 모드 창 간에 전환할 수 있습니다. 모든 정책을 해당 변경사항 이렇게 변경하면 변경사항이 자동으로 폴더블 및 태블릿과 같은 대형 화면은 추가 작업이 필요하지 않습니다.
앱에 관련 업데이트가 포함되어 있지 않아도 PIP 전환은 계속 적용됩니다. 애니메이션은 덜 세련됩니다. 예를 들어 전체 화면을 PIP 모드로 전환하면 재생 중에 PIP 창이 사라질 수 있습니다. 다시 표시되도록 할 수 있습니다.
이러한 변경사항에는 다음이 포함됩니다.
- 동작 탐색에서 PIP 모드로 더 원활하게 전환
- PIP 모드 시작 및 종료를 위한 적절한
sourceRectHint
설정 - 동영상이 아닌 콘텐츠의 원활한 크기 조절 사용 중지
자세한 내용은 Android Kotlin PictureInPicture 샘플 을 참고하시기 바랍니다.
동작 탐색에서 PIP 모드로 더 매끄럽게 전환
Android 12부터 setAutoEnterEnabled
플래그는 많은 기능을 제공합니다.
동작을 사용하여 PIP 모드에서 동영상 콘텐츠로 전환하는 더 매끄러운 애니메이션
(예: 전체 화면에서 위로 스와이프하여 홈으로 이동)
변경하려면 다음 단계를 완료하고 이 샘플을 참조:
setAutoEnterEnabled
를 사용하여 구성PictureInPictureParams.Builder
:Kotlin
setPictureInPictureParams(PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) .setAutoEnterEnabled(true) .build())
자바
setPictureInPictureParams(new PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) .setAutoEnterEnabled(true) .build());
최신
PictureInPictureParams
를 사용하여setPictureInPictureParams
를 조기에 호출합니다. 앱은 사용자가onUserLeaveHint
콜백 (Android 11에서와 동일)예를 들어, 매우 가까운 시간에
setPictureInPictureParams
을 첫 번째 재생 및 이후 재생에 대한 정보를 제공할 수 있습니다(가로세로 비율이 변경된 경우).필요한 경우에만
setAutoEnterEnabled(false)
를 호출합니다. 예를 들어 현재 재생이 일시중지된 상태라면 PIP 모드로 전환하고 싶지 않을 수 있습니다. 있습니다.
PIP 모드 시작 및 종료를 위한 적절한 sourceRectHint
설정
Android 8.0에 PIP 모드가 도입되면서, setSourceRectHint
로의 전환 이후에 보이는 활동의 영역을
PIP 모드(예: 동영상 플레이어의 동영상 뷰 경계)
Android 12에서는 시스템이 sourceRectHint
를 사용하여 훨씬 더 원활하게
애니메이션이 표시됩니다.
PIP 모드를 시작하고 종료하기 위해 sourceRectHint
를 올바르게 설정하려면 다음 단계를 따르세요.
PictureInPictureParams
구성sourceRectHint
로 적절한 경계를 사용합니다. 또한 동영상 플레이어에 대한 레이아웃 변경 리스너를 추가합니다.Kotlin
val mOnLayoutChangeListener = OnLayoutChangeListener { v: View?, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int, newLeft: Int, newTop: Int, newRight: Int, newBottom: Int -> val sourceRectHint = Rect() mYourVideoView.getGlobalVisibleRect(sourceRectHint) val builder = PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) setPictureInPictureParams(builder.build()) } mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener)
자바
private final View.OnLayoutChangeListener mOnLayoutChangeListener = (v, oldLeft, oldTop, oldRight, oldBottom, newLeft, newTop, newRight, newBottom) -> { final Rect sourceRectHint = new Rect(); mYourVideoView.getGlobalVisibleRect(sourceRectHint); final PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint); setPictureInPictureParams(builder.build()); }; mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener);
필요한 경우 시스템에서
sourceRectHint
종료 전환 시스템이 PIP 모드를 종료하려고 하면 활동의 뷰 계층 구조가 대상 구성에 배치됩니다 (예: 전체 화면). 앱이 레이아웃 변경 리스너를 루트 뷰에 연결할 수 있음 또는 타겟 보기 (예: 동영상 플레이어 보기)를 사용하여 이벤트를 감지하고 애니메이션이 시작되기 전에sourceRectHint
를 업데이트해야 합니다.Kotlin
// Listener is called immediately after the user exits PiP but before animating. playerView.addOnLayoutChangeListener { _, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) { // The playerView's bounds changed, update the source hint rect to // reflect its new bounds. val sourceRectHint = Rect() playerView.getGlobalVisibleRect(sourceRectHint) setPictureInPictureParams( PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) .build() ) } }
자바
// Listener is called right after the user exits PiP but before // animating. playerView.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) { // The playerView's bounds changed, update the source hint rect to // reflect its new bounds. final Rect sourceRectHint = new Rect(); playerView.getGlobalVisibleRect(sourceRectHint); setPictureInPictureParams( new PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) .build()); } });
동영상이 아닌 콘텐츠의 원활한 크기 조절을 사용 중지
Android 12에서는 setSeamlessResizeEnabled
플래그를 추가하여
PIP에서 동영상이 아닌 콘텐츠의 크기를 조절할 때 더 부드러운 크로스 페이딩 애니메이션
창 이전에는 PIP 창에서 동영상이 아닌 콘텐츠의 크기를 조절하면
시각적 아티팩트를 발생시킵니다.
동영상이 아닌 콘텐츠의 원활한 크기 조절을 사용 중지하려면 다음을 실행하세요.
Kotlin
setPictureInPictureParams(PictureInPictureParams.Builder() .setSeamlessResizeEnabled(false) .build())
자바
setPictureInPictureParams(new PictureInPictureParams.Builder() .setSeamlessResizeEnabled(false) .build());
PIP 중에 UI 처리
활동이 PIP 모드로 전환되거나 PIP 모드가 종료되면 시스템은
Activity.onPictureInPictureModeChanged()
또는
Fragment.onPictureInPictureModeChanged()
활동의 UI 요소를 다시 그리려면 이 콜백을 재정의해야 합니다. PIP 모드에서는 활동이 작은 창에 표시됩니다. 앱이 PIP 모드일 때 사용자가 앱의 UI 요소와 상호작용할 수 없으며 작은 UI 요소의 세부정보는 잘 보이지 않을 수 있습니다. 최소한의 UI가 포함된 동영상 재생 활동에서 최고의 사용자 환경을 제공합니다.
앱에서 PIP용 맞춤 작업을 제공해야 하는 경우 추가 컨트롤을 참조하세요. 활동이 PIP 모드가 되기 전에 다른 UI 요소를 삭제하고, 활동이 전체 화면으로 다시 전환되면 UI 요소를 복원합니다.
Kotlin
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) { if (isInPictureInPictureMode) { // Hide the full-screen UI (controls, etc.) while in PiP mode. } else { // Restore the full-screen UI. } }
자바
@Override public void onPictureInPictureModeChanged (boolean isInPictureInPictureMode, Configuration newConfig) { if (isInPictureInPictureMode) { // Hide the full-screen UI (controls, etc.) while in PiP mode. } else { // Restore the full-screen UI. ... } }
제어 기능 추가
PIP 창에서는 사용자가 휴대기기의 창을 탭하거나 TV 리모컨에서 메뉴를 선택하여 창 메뉴를 열 때 제어 기능을 표시할 수 있습니다.
앱에 활성 미디어가 있는 경우 세션을 시작하고, 이를 재생한 다음, 일시중지, 다음 및 이전 컨트롤이 나타납니다.
또한
PictureInPictureParams
드림
다음 코드로 교체합니다.
PictureInPictureParams.Builder.setActions()
를 사용하고, PIP 모드를 시작할 때
enterPictureInPictureMode(android.app.PictureInPictureParams)
또는
setPictureInPictureParams(android.app.PictureInPictureParams)
.
조심하세요. getMaxNumPictureInPictureActions()
를 초과하여 추가하려고 하면 최대 수에 도달하게 됩니다.
PIP 상태에서 동영상 계속 재생
활동이 PIP로 전환되면 시스템은 활동을 일시중지 상태로 전환합니다.
액티비티의
onPause()
메서드를 사용하여 지도 가장자리에
패딩을 추가할 수 있습니다. 동영상
활동이 일시중지되어서는 안 되며, 활동이 없을 경우 대신 계속 재생되어야
PIP 모드로 전환하는 동안 일시중지되었습니다.
Android 7.0 이상에서는 시스템에서 활동의 onStop()
및 onStart()
를 호출할 때 동영상 재생을 일시중지한 다음 재개해야 합니다. 이렇게 하면
onPause()
에서 앱이 PIP 모드인지 확인하지 않아도 됩니다.
명시적으로 재생을 계속할 수 있습니다.
setAutoEnterEnabled
플래그를 true
로 설정하지 않았으며
onPause()
구현에서 재생을 일시중지하려면 다음을 호출하여 PIP 모드를 확인하세요.
isInPictureInPictureMode()
를 호출하고 재생을 적절하게 처리합니다. 예를 들면 다음과 같습니다.
Kotlin
override fun onPause() { super.onPause() // If called while in PiP mode, do not pause playback if (isInPictureInPictureMode) { // Continue playback } else { // Use existing playback logic for paused Activity behavior. } }
자바
@Override public void onPause() { // If called while in PiP mode, do not pause playback if (isInPictureInPictureMode()) { // Continue playback ... } else { // Use existing playback logic for paused Activity behavior. ... } }
활동이 PIP 모드에서 다시 전체 화면 모드로 전환되면
활동을 재개하고
onResume()
메서드를 사용하여 지도 가장자리에
패딩을 추가할 수 있습니다.
PIP에 단일 재생 활동 사용
사용자가 앱에서 콘텐츠를 탐색할 때 새 동영상을 선택할 수 있습니다. 동영상 재생 활동이 PIP 모드일 때 새 동영상 재생 기존 재생 활동을 실행하는 대신 전체화면 모드로 사용자를 혼란스럽게 할 수 있는 새로운 활동이 있는지 확인하세요.
동영상 재생 요청에 단일 활동이 사용되고
PIP 모드를 시작하거나 해제하는 경우 활동의 android:launchMode
를 다음과 같이 설정합니다.
singleTask
를 매니페스트 파일에 추가합니다.
<activity android:name="VideoActivity"
...
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
...
활동에서 onNewIntent()
를 재정의하고 새 동영상을 처리하며 필요한 경우 기존 동영상 재생을 중지합니다.
권장사항
RAM이 부족한 기기에서는 PIP가 사용 중지될 수 있습니다. 앱에서 PIP를 사용하려면 hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
를 호출하여 PIP를 사용할 수 있는지 확인하세요.
PIP는 전체 화면 동영상을 재생하는 활동에 사용합니다. 활동을 PIP 모드로 전환할 때 동영상 콘텐츠 이외의 콘텐츠는 표시하지 않습니다. 추적 시기 UI 처리의 설명대로 활동이 PIP 모드로 전환되고 UI 요소를 숨깁니다. 재생 중을 참고하세요.
활동이 PIP 모드에 있으면 기본적으로 입력 포커스를 받지 않습니다. PIP 모드에서 입력 이벤트를 받으려면 MediaSession.setCallback()
을 사용합니다.
setCallback()
사용에 관한 자세한 내용은 Now Playing 표시하기를 참고하세요.
카드.
앱이 PIP 모드일 때 PIP 창에서 동영상을 재생하면 오디오가 발생할 수 있습니다. 음악 플레이어 앱이나 음성 검색 앱 등 다른 앱과의 간섭을 방지할 수 있습니다. 이를 방지하려면 동영상 재생을 시작할 때 오디오 포커스를 요청하고 오디오 포커스 변경 알림(오디오 관리 참조) 포커스. 알림을 받는 경우 오디오 포커스 손실 방지, PIP 모드일 때 동영상 재생을 일시중지하거나 중지할 수 있습니다.
앱에서 PIP 모드로 전환하려고 하면 상위 활동만 시작되는지 확인합니다.
PIP 모드입니다. 멀티 윈도우 기기에서와 같은 일부 상황에서는 그 아래에 있는 활동이 PIP 활동과 함께 다시 표시될 수 있습니다. 이러한 케이스는 아래 활동에 onResume()
또는 onPause()
콜백을 가져오게 하는 등 그에 맞게 처리해야 합니다. 또한 사용자가 그 활동과 상호작용할 수도 있습니다. 예를 들어 동영상 목록 활동이 표시되어 있고 PIP 모드에서 재생되는 동영상 활동이 있는 경우 사용자는 목록에서 새 동영상을 선택할 수 있습니다. 그러면 PIP 활동이 그에 따라 업데이트되어야 합니다.
추가 샘플 코드
Kotlin으로 작성된 샘플 앱을 다운로드하려면 Android PIP 모드 샘플을 참조하세요. (Kotlin)을 사용합니다.