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

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

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

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

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

Зачем использовать функцию «Поделиться» в Android?

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

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

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

Воспользуйтесь функцией «Поделиться» в Android.

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

Отправить текстовое содержимое

Наиболее простое и распространенное применение функции «Поделиться» в Android — это отправка текстового контента из одного приложения в другое. Например, большинство браузеров могут передавать 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)

Java

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))

Java

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() , после чего в предоставленный коллбэк onScanCompleted() передается Uri в стиле content:// , подходящий для обмена. Обратите внимание, что после добавления в системное 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 .

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

Делитесь несколькими фрагментами контента

Для отправки нескольких фрагментов контента используйте действие 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))

Java

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 отображается предварительный просмотр текста, которым делятся пользователи. В некоторых случаях текст, которым делятся пользователи, может быть сложным для понимания. Например, можно поделиться сложной ссылкой, такой как 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)

Java

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. Пользовательские действия отображаются в виде небольших значков действий в верхней части меню «Поделиться», и приложения могут указать любой 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)

Java

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 для общего доступа после вызова Intent.createChooser() :

Котлин

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

Java

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, скорее всего, будет отправлять данные за пределы вашего приложения.

Добавьте Intent.EXTRA_EXCLUDE_COMPONENTS в ваш Intent после вызова 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)
  }

Java

  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)

Java

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_CHOOSER_RESULT :

Котлин

override fun onReceive(context: Context, intent: Intent) {
  ...
  val chooserResult: ChooserResult? = IntentCompat.getParcelableExtra(
      intent,
      Intent.EXTRA_CHOOSER_RESULT,
      ChooserResult::class.java,
  )
  chooserResult?.let {
      Log.i(
          TAG,
          "Share callback: isShortcut: ${it.isShortcut}, type: ${typeToString(it.type)}, componentName: ${it.selectedComponent}",
      )
  } ?: Log.i(TAG, "chooserResult is null")
}

Java

@Override public void onReceive(Context context, Intent intent) {
  ...
  ChooserResult chooserResult = intent.getParcelableExtra(EXTRA_CHOOSER_RESULT);
  Log.i(
      TAG,
      "Share callback: isShortcut: "
          + chooserResult.isShortcut()
          + ", type: "
          + chooserResult.getType()
          + ", componentName: "
          + chooserResult.getSelectedComponent()
  );
}
Для получения более подробной информации см. пример использования платформы для обмена данными:

Добавьте пользовательские действия в таблицу «Поделиться».

В 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)

Java

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. Однако не вызывайте 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)

Java

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);

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

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