다른 앱으로 간단한 데이터 전송

Android는 인텐트와 관련 추가 항목을 사용하여 사용자가 좋아하는 앱을 사용하여 빠르고 쉽게 정보를 공유할 수 있도록 합니다.

Android에서는 사용자가 두 가지 방식으로 앱 간에 데이터를 공유할 수 있습니다.

  • Android Sharesheet는 주로 앱 외부 또는 다른 사용자에게 직접 콘텐츠를 전송하기 위해 설계되었습니다. 예를 들어, 친구와 URL을 공유합니다.
  • Android 인텐트 리졸버는 데이터를 잘 정의된 작업의 다음 단계로 전달하는 데 가장 적합합니다. 예를 들어 앱에서 PDF를 열고 사용자가 원하는 뷰어를 선택하도록 할 수 있습니다.

인텐트를 구성할 때 인텐트가 수행할 작업을 지정합니다. Android는 ACTION_SEND 작업을 사용하여 프로세스 경계를 넘어 한 활동에서 다른 활동으로 데이터를 전송합니다. 데이터와 데이터의 유형을 지정해야 합니다. 시스템은 데이터를 수신할 수 있는 호환되는 활동을 자동으로 식별하여 사용자에게 표시합니다. 인텐트 리졸버의 경우 하나의 활동만 인텐트를 처리할 수 있는 경우 이 활동은 즉시 시작됩니다.

Android Sharesheet를 사용하는 이유

앱 간에 사용자를 위한 일관성을 유지하려면 Android Sharesheet를 사용하는 것이 좋습니다. 앱의 자체 공유 타겟 목록을 표시하거나 자체 Sharesheet 변형을 만들지 마세요.

Android Sharesheet를 사용하면 사용자가 탭 한 번으로 관련 앱 제안을 통해 적절한 사람과 정보를 공유할 수 있습니다. Sharesheet는 맞춤 솔루션에 사용할 수 없는 타겟을 제안하고 일관된 순위를 사용할 수 있습니다. 이는 Sharesheet가 시스템에서만 사용할 수 있는 앱 및 사용자 활동에 관한 정보를 고려할 수 있기 때문입니다.

또한 Android Sharesheet에는 개발자를 위한 여러 가지 편리한 기능이 있습니다. 예를 들어 다음을 수행할 수 있습니다.

Android Sharesheet 사용

모든 유형의 공유에 대해 인텐트를 만들고 작업을 Intent.ACTION_SEND로 설정합니다. Android Sharesheet를 표시하려면 Intent.createChooser()를 호출하여 Intent 객체에 전달합니다. 항상 Android Sharesheet를 표시하는 인텐트 버전을 반환합니다.

텍스트 콘텐츠 전송

Android Sharesheet의 가장 간단하고 일반적인 용도는 한 활동에서 다른 활동으로 텍스트 콘텐츠를 보내는 것입니다. 예를 들어 대부분의 브라우저는 현재 표시된 페이지의 URL을 다른 앱과 텍스트로 공유할 수 있습니다. 이 기능은 이메일 또는 소셜 네트워크를 통해 친구와 기사나 웹사이트를 공유할 때 유용합니다. 다음은 그 방법을 보여주는 예입니다.

Kotlin

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) 등의 추가 정보를 포함하는 extra를 추가할 수 있습니다.

참고: Gmail과 같은 일부 이메일 앱에서는 EXTRA_EMAILEXTRA_CC와 같은 추가 항목에 String[]이 필요합니다. putExtra(String, String[])를 사용하여 인텐트에 추가합니다.

바이너리 콘텐츠 전송

ACTION_SEND 작업을 사용하여 바이너리 데이터를 공유할 수 있습니다. 다음 예와 같이 적절한 MIME 유형을 설정하고 추가 EXTRA_STREAM에 데이터의 URI를 배치합니다. 이는 일반적으로 이미지를 공유하는 데 사용되지만 모든 유형의 바이너리 콘텐츠를 공유하는 데 사용될 수도 있습니다.

Kotlin

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별 권한을 사용하는 것입니다. URI별 권한은 일시적이며 수신 애플리케이션에만 액세스를 부여합니다. 이러한 ContentProvider를 만드는 쉬운 방법은 FileProvider 도우미 클래스를 사용하는 것입니다.
  • MediaStore 시스템을 사용합니다. MediaStore는 주로 동영상, 오디오, 이미지 MIME 유형에 사용됩니다. 그러나 Android 3.0 (API 수준 11)부터는 미디어가 아닌 유형도 저장할 수 있습니다. 자세한 내용은 MediaStore.Files를 참고하세요. 파일은 scanFile()를 사용하여 MediaStore에 삽입할 수 있으며, 그 후에 공유에 적합한 content:// 스타일 Uri가 제공된 onScanCompleted() 콜백에 전달됩니다. 시스템 MediaStore에 추가되면 기기의 모든 앱에서 콘텐츠에 액세스할 수 있습니다.

올바른 MIME 유형 사용

전송 중인 데이터에 사용할 수 있는 가장 구체적인 MIME 유형을 제공합니다. 예를 들어 일반 텍스트를 공유할 때는 text/plain를 사용합니다. 다음은 Android에서 단순 데이터를 보낼 때의 몇 가지 일반적인 MIME 유형입니다.

수신기는 발신자는
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 유형에 따라 콘텐츠 미리보기를 표시할 수 있습니다. 일부 미리보기 기능은 특정 유형에만 사용할 수 있습니다.

여러 콘텐츠 공유

여러 콘텐츠를 공유하려면 콘텐츠를 가리키는 URI 목록과 함께 ACTION_SEND_MULTIPLE 작업을 사용합니다. MIME 유형은 공유하는 콘텐츠의 조합에 따라 다릅니다. 예를 들어 세 개의 JPEG 이미지를 공유하는 경우 "image/jpg" 유형을 사용합니다. 이미지 유형이 혼합된 경우 "image/*"를 사용하여 모든 유형의 이미지를 처리하는 활동과 일치시킵니다. 혼합된 유형을 공유할 수도 있지만 전송할 대상을 수신자가 명확하지 않으므로 사용하지 않는 것이 좋습니다. 여러 유형을 전송해야 하는 경우 "*/*"를 사용하세요. 데이터를 파싱하고 처리하는 것은 수신 애플리케이션에 달려 있습니다. 예를 들면 다음과 같습니다.

Kotlin

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 Sharesheet에 공유 중인 텍스트의 미리보기가 표시됩니다. 경우에 따라 공유 중인 텍스트를 이해하기 어려울 수 있습니다. https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4와 같이 복잡한 URL을 공유하는 것이 좋습니다. 더 풍부한 미리보기를 통해 사용자에게 공유 중인 정보를 다시 확인할 수 있습니다.

텍스트를 미리 본다면 제목이나 미리보기 이미지 또는 둘 다를 설정할 수 있습니다. Intent.createChooser()를 호출하기 전에 Intent.EXTRA_TITLE에 설명을 추가하고 ClipData를 사용하여 관련 썸네일을 추가합니다.

참고: 이미지 콘텐츠 URI는 일반적으로 구성된 <cache-path>에서 FileProvider에서 제공됩니다. 자세한 내용은 파일 공유를 참고하세요. 미리보기 이미지로 사용할 이미지를 읽을 수 있는 올바른 권한을 Sharesheet에 부여해야 합니다. 자세한 내용은 Intent.FLAG_GRANT_READ_URI_PERMISSION를 참고하세요.

예를 들면 다음과 같습니다.

Kotlin

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

미리보기는 다음과 같습니다.

Sharesheet에 맞춤 작업 추가

Android Sharesheet의 맞춤 작업 스크린샷

Android 14 (API 수준 34) 이상에서는 앱이 Android Sharesheet에 맞춤 작업을 추가할 수 있습니다. 맞춤 작업은 Android Sharesheet 상단에 작은 작업 아이콘으로 표시되며 앱은 아이콘을 클릭할 때 호출되는 작업으로 Intent를 지정할 수 있습니다.

Android Sharesheet에 맞춤 작업을 추가하려면 먼저 ChooserAction.Builder를 사용하여 ChooserAction를 만듭니다. PendingIntent을 아이콘을 클릭하면 호출되는 작업으로 지정할 수 있습니다. 모든 맞춤 작업을 포함하는 배열을 만들고 이를 공유 IntentEXTRA_CHOOSER_CUSTOM_ACTIONS로 지정합니다.

Kotlin

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를 사용하면 ChooserTargetServices에서 로드된 공유 바로가기와 선택기 타겟 앞에 표시되는 ChooserTarget 객체를 최대 두 개까지 지정할 수 있습니다. 앱 추천 앞에 나열된 활동을 가리키는 인텐트를 최대 2개까지 지정할 수도 있습니다.

Intent.createChooser()를 호출한 후에 공유 인텐트에 Intent.EXTRA_CHOOSER_TARGETSIntent.EXTRA_INITIAL_INTENTS를 추가합니다.

Kotlin

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

이 기능은 주의해서 사용하세요. 맞춤 IntentChooserTarget를 추가할 때마다 시스템 제안 수가 감소합니다. 일반적으로 맞춤 타겟을 추가하지 않는 것이 좋습니다. Intent.EXTRA_INITIAL_INTENTS 추가의 일반적인 적절한 예는 사용자가 공유 콘텐츠에 관해 할 수 있는 추가 작업을 제공하는 것입니다. 예를 들어 사용자가 이미지를 공유하고 Intent.EXTRA_INITIAL_INTENTS를 사용하여 사용자가 대신 링크를 보낼 수 있습니다. Intent.EXTRA_CHOOSER_TARGETS를 추가하는 적절한 일반적인 예는 앱에서 제공하는 관련 사용자 또는 기기를 표시하는 것입니다.

구성요소별로 특정 타겟 제외

Intent.EXTRA_EXCLUDE_COMPONENTS를 제공하여 특정 타겟을 제외할 수 있습니다. 내가 제어할 수 있는 타겟을 삭제하려는 경우에만 이를 수행하세요. 일반적인 사용 사례는 사용자의 인텐트가 앱 외부에서 공유될 가능성이 높기 때문에 사용자가 앱 내에서 공유할 때 앱의 공유 타겟을 숨기는 것입니다.

Intent.createChooser()를 호출한 후 인텐트에 Intent.EXTRA_EXCLUDE_COMPONENTS를 추가합니다.

Kotlin

  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를 사용하면 IntentSender를 사용하여 사용자가 선택한 타겟의 ComponentName를 제공하여 이 정보를 가져올 수 있습니다.

먼저 BroadcastReceiverPendingIntent를 만들고 Intent.createChooser()에서 IntentSender를 제공합니다.

Kotlin

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_CHOSEN_COMPONENT를 확인합니다.

Kotlin

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

Java

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

Sharesheet에 맞춤 작업 추가

Android 14 (API 수준 34) 이상에서는 앱이 Android Sharesheet에 맞춤 작업을 추가할 수 있습니다. ChooserAction.Builder를 사용하여 ChooserAction를 만듭니다. PendingIntent을 아이콘을 클릭하면 호출되는 작업으로 지정할 수 있습니다. 모든 맞춤 작업을 포함하는 배열을 만들고 이를 공유 IntentEXTRA_CHOOSER_CUSTOM_ACTIONS로 지정합니다.

Kotlin

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 Sharesheet를 호출할 때와 같이 인텐트를 만들고 extra를 추가합니다. 하지만 Intent.createChooser()를 호출하면 안 됩니다.

ACTION_SEND 및 MIME 유형과 일치하는 필터와 일치하는 필터가 설치된 애플리케이션이 여러 개 있는 경우 시스템은 사용자가 공유할 타겟을 선택할 수 있는 인텐트 리졸버라는 명확성 대화상자를 표시합니다. 단일 애플리케이션이 일치하면 실행됩니다.

다음은 Android 인텐트 리졸버를 사용하여 텍스트를 보내는 방법의 예입니다.

Kotlin

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

자세히 알아보기

데이터 전송에 관한 자세한 내용은 인텐트 및 인텐트 필터를 참조하세요.