Отправляйте простые данные в другие приложения

Android использует намерения и связанные с ними дополнительные возможности, чтобы пользователи могли быстро и легко обмениваться информацией с помощью своих любимых приложений.

Android предоставляет пользователям два способа обмена данными между приложениями:

  • Android Sharesheet в первую очередь предназначен для отправки контента за пределы вашего приложения и/или напрямую другому пользователю. Например, поделившись URL-адресом с другом.
  • Распознаватель намерений Android лучше всего подходит для передачи данных на следующий этап четко определенной задачи. Например, вы можете открыть PDF-файл из вашего приложения и предоставить пользователям возможность выбрать предпочтительное средство просмотра.

Когда вы создаете намерение, вы указываете действие, которое должно выполнить намерение. Android использует действие ACTION_SEND для отправки данных из одного действия в другое, даже через границы процесса. Вам необходимо указать данные и их тип. Система автоматически определяет совместимые действия, которые могут получать данные, и отображает их пользователю. В случае преобразователя намерений, если только одно действие может обработать намерение, оно немедленно запускается.

Зачем использовать Android Sharesheet

Мы настоятельно рекомендуем использовать Android Sharesheet, чтобы обеспечить согласованность действий пользователей в разных приложениях. Не отображайте собственный список целей общего доступа вашего приложения и не создавайте собственные варианты Sharesheet.

Android Sharesheet позволяет пользователям делиться информацией с нужным человеком, предлагая соответствующие приложения, и все это одним касанием. Sharesheet может предлагать цели, недоступные для пользовательских решений, и использует последовательный рейтинг. Это связано с тем, что Sharesheet может учитывать информацию о приложениях и активности пользователей, доступную только системе.

Android Sharesheet также имеет множество удобных функций для разработчиков. Например, вы можете сделать следующее:

Используйте общий список Android

Для всех типов общего доступа создайте намерение и установите для него действие Intent.ACTION_SEND . Чтобы отобразить общий лист Android, вызовите Intent.createChooser() , передав ему свой объект Intent . Он возвращает версию вашего намерения, которая всегда отображает общую таблицу Android.

Отправить текстовый контент

Самый простой и распространенный способ использования Android Sharesheet — пересылка текстового контента из одного действия в другое. Например, большинство браузеров могут передавать URL-адрес отображаемой в данный момент страницы в виде текста другому приложению. Это полезно для обмена статьей или веб-сайтом с друзьями по электронной почте или в социальных сетях. Вот пример того, как это сделать:

Котлин

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}

val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)

Ява

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");

Intent shareIntent = Intent.createChooser(sendIntent, null);
startActivity(shareIntent);

При желании вы можете добавить дополнительную информацию, например получателей электронной почты ( EXTRA_EMAIL , EXTRA_CC , EXTRA_BCC ), тему электронного письма ( EXTRA_SUBJECT ) и т. д.

Примечание. Некоторые почтовые приложения, такие как Gmail, ожидают String[] для дополнительных элементов, таких как EXTRA_EMAIL и EXTRA_CC . Используйте putExtra(String, String[]) чтобы добавить их к вашему намерению.

Отправить двоичный контент

Поделитесь двоичными данными с помощью действия ACTION_SEND . Установите соответствующий тип MIME и поместите URI для данных в дополнительном EXTRA_STREAM , как показано в следующем примере. Обычно это используется для обмена изображениями, но может использоваться для обмена любым типом двоичного контента.

Котлин

val shareIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    // Example: content://com.google.android.apps.photos.contentprovider/...
    putExtra(Intent.EXTRA_STREAM, uriToImage)
    type = "image/jpeg"
}
startActivity(Intent.createChooser(shareIntent, null))

Ява

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
// Example: content://com.google.android.apps.photos.contentprovider/...
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, null));

Принимающему приложению требуется разрешение на доступ к данным, на которые указывает Uri . Есть два рекомендуемых способа сделать это:

  • Сохраните данные в своем собственном ContentProvider , убедившись, что другие приложения имеют правильное разрешение на доступ к вашему провайдеру. Предпочтительным механизмом предоставления доступа является использование разрешений для каждого URI , которые являются временными и предоставляют доступ только принимающему приложению. Простой способ создать такой ContentProvider — использовать вспомогательный класс FileProvider .
  • Используйте систему MediaStore . MediaStore в первую очередь предназначен для типов MIME видео, аудио и изображений. Однако, начиная с Android 3.0 (уровень API 11), он также может хранить немедиа-типы. Дополнительные сведения см. в MediaStore.Files . Файлы можно вставить в MediaStore с помощью scanFile() , после чего Uri в стиле content:// подходящий для совместного использования, передается в предоставленный обратный вызов onScanCompleted() . Обратите внимание, что после добавления в системный MediaStore контент становится доступен любому приложению на устройстве.

Используйте правильный тип MIME

Укажите наиболее конкретный тип MIME, доступный для отправляемых вами данных. Например, используйте text/plain при обмене обычным текстом. Вот несколько распространенных типов MIME при отправке простых данных в Android:

Получатели регистрируются на Отправители отправляют
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
Поддерживаемые расширения файлов application/pdf

Дополнительные сведения о типах MIME см. в официальном реестре типов мультимедиа MIME IANA .

В Android Sharesheet может отображаться предварительный просмотр содержимого, в зависимости от предоставленного типа MIME. Некоторые функции предварительного просмотра доступны только для определенных типов.

Делитесь несколькими частями контента

Чтобы поделиться несколькими фрагментами контента, используйте действие ACTION_SEND_MULTIPLE вместе со списком URI, указывающих на контент. Тип MIME варьируется в зависимости от контента, которым вы делитесь. Например, если вы делитесь тремя изображениями JPEG, вы используете тип "image/jpg" . Для смеси типов изображений используйте "image/*" чтобы соответствовать действию, обрабатывающему любой тип изображения. Хотя можно использовать разные типы сообщений, мы настоятельно не рекомендуем этого делать, поскольку получателю неясно, что именно предполагается отправить. Если необходимо отправить несколько типов, используйте "*/*" . Принимающее приложение должно анализировать и обрабатывать ваши данные. Вот пример:

Котлин

val imageUris: ArrayList<Uri> = arrayListOf(
        // Add your image URIs here
        imageUri1,
        imageUri2
)

val shareIntent = Intent().apply {
    action = Intent.ACTION_SEND_MULTIPLE
    putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris)
    type = "image/*"
}
startActivity(Intent.createChooser(shareIntent, null))

Ява

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, null));

Убедитесь, что предоставленные объекты Uri указывают на данные, к которым может получить доступ принимающее приложение.

Добавьте богатый контент в предварительный просмотр текста

Начиная с Android 10 (уровень API 29), в Android Sharesheet отображается предварительный просмотр публикуемого текста. В некоторых случаях передаваемый текст может быть трудным для понимания. Рассмотрите возможность использования сложного URL-адреса, например https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4 . Более расширенный предварительный просмотр может убедить ваших пользователей в том, чем они делятся.

Если вы просматриваете текст, вы можете установить заголовок, миниатюру изображения или и то, и другое. Добавьте описание в Intent.EXTRA_TITLE перед вызовом Intent.createChooser() и добавьте соответствующую миниатюру с помощью ClipData .

Примечание. URI содержимого изображения предоставляется из FileProvider , обычно из настроенного <cache-path> . Дополнительную информацию см. в разделе Общий доступ к файлам . Обязательно предоставьте Sharesheet необходимые разрешения на чтение любого изображения, которое вы хотите использовать в качестве миниатюры. Дополнительные сведения см. в Intent.FLAG_GRANT_READ_URI_PERMISSION .

Вот пример:

Котлин

 val share = Intent.createChooser(Intent().apply {
      action = Intent.ACTION_SEND
      putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")

      // (Optional) Here you're setting the title of the content
      putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

      // (Optional) Here you're passing a content URI to an image to be displayed
      data = contentUri
      flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
  }, null)
  startActivity(share)

Ява

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/");

// (Optional) Here you're setting the title of the content
sendIntent.putExtra(Intent.EXTRA_TITLE, "Introducing content previews");

// (Optional) Here you're passing a content URI to an image to be displayed
sendIntent.setData(contentUri);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// Show the Sharesheet
startActivity(Intent.createChooser(sendIntent, null));

Предварительный просмотр выглядит примерно так:

Добавление настраиваемых действий в общую таблицу

Снимок экрана с настраиваемыми действиями в общей таблице Android.

В Android 14 (уровень API 34) и более поздних версиях приложения могут добавлять специальные действия в общую таблицу Android. Настраиваемые действия отображаются в виде небольших значков действий в верхней части общей таблицы Android, и приложения могут указать любое Intent в качестве действия, вызываемого при нажатии значка.

Чтобы добавить настраиваемые действия в общую таблицу Android, сначала создайте ChooserAction с помощью ChooserAction.Builder . Вы можете указать PendingIntent в качестве действия, вызываемого при щелчке по значку. Создайте массив, содержащий все ваши пользовательские действия, и укажите его как EXTRA_CHOOSER_CUSTOM_ACTIONS общего ресурса Intent .

Котлин

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Ява

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

Добавить пользовательские цели

Android Sharesheet позволяет указать до двух объектов ChooserTarget , которые отображаются перед ярлыками общего доступа и целями выбора, загруженными из ChooserTargetServices . Вы также можете указать до двух намерений, указывающих на действия, перечисленные перед предложениями приложений:

Добавьте Intent.EXTRA_CHOOSER_TARGETS и Intent.EXTRA_INITIAL_INTENTS к вашему общему намерению после вызова Intent.createChooser() :

Котлин

val share = Intent.createChooser(myShareIntent, null).apply {
    putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray)
    putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray)
}

Ява

Intent shareIntent = Intent.createChooser(sendIntent, null);
share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray);
share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);

Используйте эту функцию с осторожностью. Каждый добавляемый вами пользовательский Intent и ChooserTarget уменьшает число, предлагаемое системой. Обычно мы не рекомендуем добавлять собственные цели. Типичным подходящим примером добавления Intent.EXTRA_INITIAL_INTENTS является предоставление дополнительных действий, которые пользователи могут выполнять с общим контентом. Например, пользователь делится изображениями, а Intent.EXTRA_INITIAL_INTENTS используется, чтобы позволить ему вместо этого отправить ссылку. Распространенным подходящим примером добавления Intent.EXTRA_CHOOSER_TARGETS является отображение соответствующих людей или устройств, которые предоставляет ваше приложение.

Исключение определенных целей по компонентам

Вы можете исключить определенные цели, указав Intent.EXTRA_EXCLUDE_COMPONENTS . Делайте это только для удаления целей, которые вы контролируете. Распространенным вариантом использования является скрытие целей общего доступа вашего приложения, когда ваши пользователи делятся информацией из вашего приложения, поскольку их намерение, скорее всего, будет делиться информацией за пределами вашего приложения.

Добавьте Intent.EXTRA_EXCLUDE_COMPONENTS в свое намерение после вызова Intent.createChooser() :

Котлин

  val share = Intent.createChooser(Intent(), null).apply {
    // Only use for components you have control over
    val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass"))
    putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames)
  }

Ява

  Intent shareIntent = Intent.createChooser(new Intent(), null);
  // Only use for components you have control over
  ComponentName[] excludedComponentNames = {
          new ComponentName("com.example.android", "ExampleClass")
  };
  shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames);

Получить информацию о совместном использовании

Может быть полезно знать, когда ваши пользователи делятся информацией и какую цель они выбирают. Android Sharesheet позволяет вам получить эту информацию, указав ComponentName целевых объектов, выбранных вашими пользователями, с помощью IntentSender .

Сначала создайте PendingIntent для BroadcastReceiver и укажите его IntentSender в Intent.createChooser() :

Котлин

var share = Intent(Intent.ACTION_SEND)
// ...
val pi = PendingIntent.getBroadcast(
    myContext, requestCode,
    Intent(myContext, MyBroadcastReceiver::class.java),
    PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
share = Intent.createChooser(share, null, pi.intentSender)

Ява

Intent share = new Intent(ACTION_SEND);
...
PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode,
        new Intent(myContext, MyBroadcastReceiver.class),
        PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
share = Intent.createChooser(share, null, pi.getIntentSender());

Получите обратный вызов в MyBroadcastReceiver и посмотрите Intent.EXTRA_CHOSEN_COMPONENT :

Котлин

override fun onReceive(context: Context, intent: Intent) {
  ...
  val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Ява

@Override public void onReceive(Context context, Intent intent) {
  ...
  ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Добавление настраиваемых действий в общую таблицу

В Android 14 (уровень API 34) и более поздних версиях приложения могут добавлять специальные действия в общую таблицу Android. Создайте ChooserAction с помощью ChooserAction.Builder . Вы можете указать PendingIntent в качестве действия, вызываемого при щелчке по значку. Создайте массив, содержащий все ваши пользовательские действия, и укажите его как EXTRA_CHOOSER_CUSTOM_ACTIONS общего ресурса Intent .

Котлин

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Ява

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

Используйте преобразователь намерений Android

Снимок экрана преобразователя намерений ACTION_SEND .

Распознаватель намерений Android лучше всего использовать при отправке данных в другое приложение в рамках четко определенного потока задач.

Чтобы использовать преобразователь намерений Android, создайте намерение и добавьте дополнительные элементы, как если бы вы вызывали Android Sharesheet. Однако не вызывайте Intent.createChooser() .

Если установлено несколько приложений с фильтрами, соответствующими ACTION_SEND и типу MIME, система отображает диалоговое окно устранения неоднозначности, называемое преобразователем намерений , которое позволяет пользователю выбрать цель для общего доступа. Если одно приложение соответствует, оно запускается.

Вот пример использования преобразователя намерений Android для отправки текста:

Котлин

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}
startActivity(sendIntent)

Ява

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);

Узнать больше

Дополнительные сведения об отправке данных см. в разделе Намерения и фильтры намерений.