리치 콘텐츠 삽입

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

사용자는 이미지, 동영상, 기타 생생한 콘텐츠를 좋아하지만 앱에 이러한 콘텐츠를 삽입하고 이동하는 것은 어려울 수 있습니다. 앱에서 리치 콘텐츠를 간단히 수신할 수 있도록 클립보드나 키보드, 드래그 앤 드롭 등 모든 소스의 콘텐츠를 수락할 수 있는 새로운 통합 API를 도입했습니다.

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

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

개요

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

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

통합 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와 비교

통합 콘텐츠 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 이상)
길게 누르기 메뉴에서 붙여넣기를 사용하여 삽입 아니요
드래그 앤 드롭을 사용하여 삽입 아니요