리치 콘텐츠 받기

그림 1. 특정 UI 메커니즘(예: 길게 누르기 메뉴에서 붙여넣기 또는 드래그 앤 드롭 사용)과 상관없이 수신 콘텐츠를 처리하는 단일 장소를 제공하는 통합 API

사용자는 이미지, 동영상, 기타 생생한 콘텐츠를 좋아하지만 앱에 이러한 콘텐츠를 삽입하고 이동하는 것은 어려울 수 있습니다. 앱에서 리치 콘텐츠를 더 쉽게 수신할 수 있도록 Android 12(API 수준 31)에서는 앱이 클립보드, 키보드 또는 드래그 앤 드롭 등 모든 소스의 콘텐츠를 수락할 수 있는 통합 API를 도입했습니다.

인터페이스 OnReceiveContentListener를 UI 구성요소에 연결하여 콘텐츠가 메커니즘을 통해 삽입될 때 콜백을 받을 수 있습니다. 콜백은 일반 텍스트와 스타일이 지정된 텍스트부터 마크업, 이미지, 동영상, 오디오 파일 등에 이르기까지 코드에서 모든 콘텐츠 수신을 처리하는 단일 장소가 됩니다.

이전 Android 버전과의 호환성을 위해 이 API를 AndroidX(Core 1.5.0-beta1Appcompat 1.3.0-beta-01에서 사용 가능)에서도 사용할 수 있게 했으며 이 기능을 구현할 때 사용하면 좋습니다.

개요

기존 API를 사용하면 길게 누르기 메뉴나 드래그 앤 드롭과 같은 각 UI 메커니즘에 상응하는 자체 API가 있습니다. 즉, 각 API와 별도로 통합하여 콘텐츠를 삽입하는 각 메커니즘에 유사한 코드를 추가해야 합니다.

그림 2. 이전에는 앱에서 콘텐츠 삽입을 위해 각 UI 메커니즘에 다른 API를 구현해야 했음

OnReceiveContentListener API는 구현할 단일 API를 만들어 이러한 다양한 코드 경로를 통합하므로 개발자는 앱별 로직에 집중하고 나머지는 플랫폼에서 처리하도록 할 수 있습니다.

그림 3. 모든 UI 메커니즘을 지원하는 단일 API를 구현할 수 있는 통합 API

이 접근 방식을 사용하면 새로운 콘텐츠 삽입 방법이 플랫폼에 추가될 때 앱에서 지원할 수 있도록 추가로 코드를 변경하지 않아도 됩니다. 앱에서 특정 사용 사례의 전체 맞춤설정을 구현해야 한다면 기존 API를 계속 사용하면 되며 동일한 방식으로 작동합니다.

구현

API는 단일 메서드 OnReceiveContentListener가 있는 리스너 인터페이스입니다. 이전 버전의 Android 플랫폼을 지원하려면 AndroidX Core 라이브러리에서 일치하는 OnReceiveContentListener 인터페이스를 사용하는 것이 좋습니다.

API를 사용하려면 앱에서 처리할 수 있는 콘텐츠 유형을 지정하여 리스너를 구현합니다.

public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
     // ...

앱에서 지원하는 콘텐츠 MIME 유형을 모두 지정한 후 나머지 리스너를 구현합니다.

 public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};

     @Override
     public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
         Pair<ContentInfoCompat, ContentInfoCompat> split = contentInfo.partition(
                 item -> item.getUri() != null);
         ContentInfo uriContent = split.first;
         ContentInfo remaining = split.second;
         if (uriContent != null) {
             ClipData clip = uriContent.getClip();
             for (int i = 0; i < clip.getItemCount(); i++) {
                 Uri uri = clip.getItemAt(i).getUri();
                 // App-specific logic to handle the URI ...
             }
         }
         // Return anything that your app didn't handle. This preserves the default platform
         // behavior for text and anything else that you aren't implementing custom handling for.
         return remaining;
     }
 }

앱에서 이미 인텐트 공유를 지원하면 콘텐츠 URI 처리에 앱별 로직을 재사용할 수 있습니다. 남아 있는 데이터를 반환하여 이 데이터의 처리를 플랫폼에 위임합니다.

리스너를 구현하고 나면 앱의 UI 요소 생성자에서 리스너를 설정합니다.

public class MyActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // ...

         AppCompatEditText myInput = findViewById(R.id.my_input);
         ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
     }
}

키보드 이미지 API와 비교

OnReceiveContentListener API는 기존 키보드 이미지 API의 다음 버전으로 생각할 수 있습니다. 이 통합 API는 키보드 이미지 API의 기능과 일부 추가 기능을 지원합니다. 기기 및 기능 호환성은 Jetpack 라이브러리를 사용하는지 Android SDK의 네이티브 API를 사용하는지에 따라 다릅니다.

지원되는 기능과 API 수준: Jetpack

작업 또는 기능 키보드 이미지 API에서 지원 통합 API에서 지원
키보드에서 삽입 예(API 수준 13 이상) 예(API 수준 13 이상)
길게 누르기 메뉴에서 붙여넣기를 사용하여 삽입 아니요
드래그 앤 드롭을 사용하여 삽입 아니요 예(API 수준 24 이상)

지원되는 기능과 API 수준: 네이티브 API

작업 또는 기능 키보드 이미지 API에서 지원 통합 API에서 지원
키보드에서 삽입 예(API 수준 25 이상) 예(Android 12 이상)
길게 누르기 메뉴에서 붙여넣기를 사용하여 삽입 아니요
드래그 앤 드롭을 사용하여 삽입 아니요