Android 12 Developer Preview is here! Try it out, and give us your feedback!

OnReceiveContentListener

interface OnReceiveContentListener
androidx.core.view.OnReceiveContentListener

Listener for apps to implement handling for insertion of content. Content may be both text and non-text (plain/styled text, HTML, images, videos, audio files, etc).

This listener can be attached to different types of UI components using ViewCompat#setOnReceiveContentListener.

Here is a sample implementation that handles content URIs and delegates the processing for text and everything else to the platform:

// (1) Define the listener
  public class MyReceiver implements OnReceiveContentListener {
      public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
 
      @Override
      public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat payload) {
          // Split the incoming content into two groups: content URIs and everything else.
          // This way we can implement custom handling for URIs and delegate the rest.
          Pair<ContentInfoCompat, ContentInfoCompat> split = payload.partition(
                  item -> item.getUri() != null);
          ContentInfoCompat uriContent = split.first;
          ContentInfoCompat 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 we didn't handle ourselves. This preserves the default platform
          // behavior for text and anything else for which we are not implementing custom handling.
          return remaining;
      }
  }
 
  // (2) Register the listener
  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());
      }
  }
  

Summary

Public methods
abstract ContentInfoCompat?
onReceiveContent(@NonNull view: View, @NonNull payload: ContentInfoCompat)

Receive the given content.

Public methods

onReceiveContent

@Nullable abstract fun onReceiveContent(
    @NonNull view: View,
    @NonNull payload: ContentInfoCompat
): ContentInfoCompat?

Receive the given content.

Implementations should handle any content items of interest and return all unhandled items to preserve the default platform behavior for content that does not have app-specific handling. For example, an implementation may provide handling for content URIs (to provide support for inserting images, etc) and delegate the processing of text to the platform to preserve the common behavior for inserting text. See the class javadoc for a sample implementation and see ContentInfoCompat#partition for a convenient way to split the passed-in content.

If implementing handling for text: if the view has a selection, the selection should be overwritten by the passed-in content; if there's no selection, the passed-in content should be inserted at the current cursor position.

If implementing handling for non-text content (e.g. images): the content may be inserted inline, or it may be added as an attachment (could potentially be shown in a completely separate view).

Parameters
view View: The view where the content insertion was requested.
payload ContentInfoCompat: The content to insert and related metadata.
Return
ContentInfoCompat? The portion of the passed-in content whose processing should be delegated to the platform. Return null if all content was handled in some way. Actual insertion of the content may be processed asynchronously in the background and may or may not succeed even if this method returns null. For example, an app may end up not inserting an item if it exceeds the app's size limit for that type of content.