앱은 데이터를 다른 앱으로 보낼 수 있을 뿐 아니라 다른 앱의 데이터를 받을 수도 있습니다. 사용자가 애플리케이션과 상호작용하는 방식 및 다른 애플리케이션에서 받을 데이터 유형을 생각해 보세요. 예를 들어 소셜 네트워크 애플리케이션이라면 다른 앱에서 흥미로운 웹 URL 같은 텍스트 콘텐츠를 받고 싶을 수 있습니다.
사용자는 종종 Android Sharesheet나 인텐트 리졸버를 통해 앱에 데이터를 보냅니다. 모든 받은 데이터는 제공하는 앱에 의해 MIME 유형이 설정되어 있습니다. 앱은 다음 세 가지 방법으로 다른 앱에서 보낸 데이터를 받을 수 있습니다.
- 일치하는
intent-filter
태그가 매니페스트에 있는Activity
ChooserTargetService
에서 반환된 하나 이상의ChooserTarget
객체- 앱에서 게시된 공유 바로가기. 이 바로가기가
ChooserTarget
객체를 대체합니다. 공유 바로가기는 앱에서 Android 10(API 수준 29)을 실행하는 경우에만 사용할 수 있습니다.
공유 바로가기와 ChooserTarget
객체는 앱 내의 특정 Activity
로 연결되는 직접 공유 딥 링크입니다. 어떤 사람을 나타내는 경우가 많으며 Android Sharesheet에 표시됩니다.
예를 들어 메시지 애플리케이션은 어떤 사람과 관련하여 이 사람과 나눈 대화로 직접 딥 링크를 통해 연결되는 공유 바로가기를 제공할 수 있습니다.
MIME 유형 지원
앱은 최대한 다양한 MIME 유형을 받을 수 있어야 합니다. 예를 들어 텍스트, 이미지, 동영상을 보내는 데 사용하는 메시지 앱은 text/*
, image/*
및 video/*
를 받을 수 있어야 합니다. 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 미디어 유형의 IANA 공식 레지스트리를 참조하세요. */*
MIME 유형을 받을 수도 있지만 모든 유형의 수신되는 콘텐츠를 완벽하게 처리할 수 있는 경우가 아니라면 이 유형을 받지 않을 것을 적극적으로 권장합니다.
좋은 공유 타겟 만들기
사용자가 특정 활동과 연결된 공유 타겟을 탭할 때 공유 타겟을 사용하기 전에 공유 콘텐츠를 확인하고 편집할 수 있어야 합니다. 이 기능은 텍스트 데이터의 경우 특히 중요합니다.
사용자가 직접 공유 타겟을 탭하면 작업이 타겟의 주체에 직접 수행될 수 있는 인터페이스로 연결되어야 합니다. 사용자에게 명확성 화면을 표시하지 말고, 사용자가 탭한 타겟과 관련없는 인터페이스로 연결되게 만들지 마세요. 구체적으로 설명하자면, 사용자가 이미 Android Sharesheet에서 타켓을 탭하여 확인 과정을 거친 상황에서 사용자를 연락처 명확성 인터페이스로 연결하여 다시 한 번 확인하고 연락처를 선택하는 절차를 거치게 해서는 안 됩니다. 예를 들어 메시지 앱의 경우 사용자가 직접 공유 타겟을 탭하면 자신이 선택한 사람과의 대화 뷰로 연결되어야 합니다. 키보드가 표시되고 메시지에 공유 데이터가 미리 입력되어 있어야 합니다.
활동이 포함된 데이터 받기
매니페스트 업데이트하기
인텐트 필터는 애플리케이션 구성요소에서 허용되는 인텐트를 시스템에 알립니다.
다른 앱에 단순 데이터 보내기 강의에서 ACTION_SEND
작업으로 인텐트를 구성한 방식과 비슷하게 이 작업을 사용하여 인텐트를 받을 수 있도록 인텐트 필터를 만듭니다. 매니페스트에서 <intent-filter>
요소를 사용하여 인텐트 필터를 정의합니다. 예를 들어 애플리케이션이 텍스트 콘텐츠, 모든 유형의 단일 이미지 또는 모든 유형의 다중 이미지를 받는 작업을 처리하는 경우 매니페스트는 다음과 같습니다.
<activity android:name=".ui.MyActivity" > <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> </activity>
다른 애플리케이션이 인텐트를 구성하고 startActivity()
에 전달하여 이러한 항목 중 하나를 공유하려고 시도하면 내 애플리케이션이 Android Sharesheet나 인텐트 리졸버에 하나의 옵션으로 나열됩니다. 사용자가 내 애플리케이션을 선택하면 해당하는 활동(위의 예에서 .ui.MyActivity
)이 시작됩니다. 그런 다음, 원하는 대로 코드 및 UI 내에서 콘텐츠를 적절하게 처리하면 됩니다.
참고: 인텐트 필터 및 인텐트 확인에 관한 자세한 내용은 인텐트 및 인텐트 필터를 참조하세요.
수신되는 콘텐츠 처리하기
Intent
가 전송한 콘텐츠를 처리하려면 getIntent()
를 호출하여 Intent
객체를 가져옵니다. 이 객체의 콘텐츠를 검사하여 다음에 할 작업을 결정할 수 있습니다. 이 활동을 시스템의 다른 부분(예: 런처)에서 시작할 수 있는 경우에는 인텐트를 검사할 때 이 점을 고려해야 합니다.
수신 데이터를 각별히 주의하여 확인하세요. 다른 애플리케이션에서 어떤 데이터가 들어올지 알 수 없습니다. 예를 들어 잘못된 MIME 유형이 설정되었을 수도 있고 전송 중인 이미지가 아주 클 수도 있습니다. 또한, 기본('UI') 스레드가 아니라 별도의 스레드에서 바이너리 데이터를 처리해야 한다는 점도 기억하세요.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... when { intent?.action == Intent.ACTION_SEND -> { if ("text/plain" == intent.type) { handleSendText(intent) // Handle text being sent } else if (intent.type?.startsWith("image/") == true) { handleSendImage(intent) // Handle single image being sent } } intent?.action == Intent.ACTION_SEND_MULTIPLE && intent.type?.startsWith("image/") == true -> { handleSendMultipleImages(intent) // Handle multiple images being sent } else -> { // Handle other intents, such as being started from the home screen } } ... } private fun handleSendText(intent: Intent) { intent.getStringExtra(Intent.EXTRA_TEXT)?.let { // Update UI to reflect text being shared } } private fun handleSendImage(intent: Intent) { (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let { // Update UI to reflect image being shared } } private fun handleSendMultipleImages(intent: Intent) { intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let { // Update UI to reflect multiple images being shared } }
자바
void onCreate (Bundle savedInstanceState) { ... // Get intent, action and MIME type Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { handleSendText(intent); // Handle text being sent } else if (type.startsWith("image/")) { handleSendImage(intent); // Handle single image being sent } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { if (type.startsWith("image/")) { handleSendMultipleImages(intent); // Handle multiple images being sent } } else { // Handle other intents, such as being started from the home screen } ... } void handleSendText(Intent intent) { String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); if (sharedText != null) { // Update UI to reflect text being shared } } void handleSendImage(Intent intent) { Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); if (imageUri != null) { // Update UI to reflect image being shared } } void handleSendMultipleImages(Intent intent) { ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (imageUris != null) { // Update UI to reflect multiple images being shared } }
데이터를 받은 후 UI를 업데이트하려면 EditText
를 채우기만 하면 됩니다. 재미있는 사진 필터를 이미지에 적용하는 것과 같이 더 복잡한 방법도 있습니다. 어떤 방법을 선택할지는 앱에 따라 다릅니다.
사용자가 앱을 인식하게 만들기
앱은 Android Sharesheet 및 인텐트 리졸버에서 아이콘 및 라벨로 표현됩니다. 아이콘과 라벨은 둘 다 매니페스트에 정의되어 있습니다. 활동 또는 인텐트 필터 라벨을 설정하여 더 자세한 컨텍스트를 제공할 수 있습니다.
Android 10(API 수준 29)부터 Android Sharesheet에서는 매니페스트에서 application
태그에 설정된 아이콘만 사용합니다. intent-filter
및 activity
태그에 설정된 아이콘은 무시합니다.
참고: 가장 좋은 공유 타겟은 관련된 활동이나 인텐트 필터에 라벨 및 아이콘이 필요 없습니다. 수신하는 앱의 이름과 아이콘만으로도 사용자가 공유했을 때 일어날 상황을 충분히 이해할 수 있어야 합니다.
직접 공유 타겟 제공하기
직접 공유는 Android 6.0(API 수준 23)에서 도입되었으며 앱이 ChooserTargetService
를 통해 ChooserTarget
객체를 제공할 수 있도록 합니다. 요구에 따라 사후 대응적으로 결과를 검색하므로 타겟의 로드가 느려지는 현상이 발생했습니다.
Android 10(API 수준 29)에서는 ChooserTargetService
Direct Share API가 새로운 Sharing Shortcuts API로 대체되었습니다. 요구에 따라 사후 대응적으로 결과를 검색하지 않고 Sharing Shortcuts API를 통해 앱에서 직접 공유 타겟을 미리 게시할 수 있습니다.
ChooserTargetService
직접 공유 메커니즘이 계속 작동하지만 이 방식으로 제공되는 타겟은 Sharing Shortcuts API를 사용하는 타겟보다 순위가 낮습니다.
ShortcutManagerCompat는 AndroidX API로, ChooserTargetService
DirectShare API의 이전 버전과 호환되는 공유 바로가기를 제공합니다. 공유 바로가기 및 ChooserTargets
를 둘 다 게시하는 경우 선호되는 방법입니다. 아래에서 안내를 참조하세요.
직접 공유 타겟 게시하기
직접 공유 타겟을 게시하는 유일한 방법은 동적 바로가기를 사용하는 것입니다. 새로운 API를 사용하여 직접 공유 타겟을 게시하려면 다음 단계를 따르세요.
- 앱의 XML 리소스 파일에서 공유 타겟 요소를 선언합니다. 자세한 내용은 아래에서 공유 타겟 선언하기를 참조하세요.
- 선언된 공유 타겟에 일치하는 카테고리와 동적 바로가기를 게시합니다. AndroidX에서 ShortcutManager 또는 ShortcutManagerCompat를 사용하여 바로가기를 추가, 액세스, 업데이트, 삭제할 수 있습니다. 호환성 라이브러리는 이전 Android 버전과의 호환성을 제공하므로 AndroidX에서는 호환성 라이브러리를 사용하는 메서드가 선호됩니다.
Sharing Shortcuts API
ShortcutInfo.Builder
에는 공유 타겟에 대한 추가 정보를 제공하는 새로운 메서드와 향상된 메서드가 포함되어 있습니다.
setCategories()
- 새로운 메서드는 아니지만 이제 공유 인텐트 또는 작업을 처리할 수 있는 바로가기를 필터링하는 데 카테고리도 사용됩니다. 자세한 내용은 공유 타겟 선언하기를 참조하세요. 이 필드는 공유 타겟으로 사용할 바로가기에 필요합니다.
setLongLived()
-
앱에서 동적 바로가기 또는 고정된 바로가기로 게시되지 않았거나 표시되지 않도록 설정된 경우에 바로가기가 유효한지 여부를 지정합니다. 바로가기가 오래 지속되는 경우 다양한 시스템 서비스에서 바로가기를 캐시할 수 있습니다. 이는 동적 바로가기로 게시되지 않은 경우에도 마찬가지입니다.
바로가기가 오래 지속되도록 하면 바로가기의 순위가 향상될 수 있습니다. 자세한 내용은 최고 순위 획득하기를 참조하세요.
-
setPerson()
,setPersons()
-
하나 이상의
Person
객체를 바로가기와 연결합니다. 다양한 앱에서 사용자 행동을 더 잘 이해하고 프레임워크의 잠재적 예측 서비스가 ShareSheet에서 더 나은 제안을 제공하도록 돕기 위해 이를 사용할 수 있습니다. 바로가기에 사람 정보를 추가하는 것은 선택사항이지만 공유 타겟을 사람과 연결할 수 있는 경우 사람 정보를 추가하는 것이 좋습니다. 클라우드와 같은 일부 공유 타겟은 사람과 연결할 수 없습니다.공유 타겟 및 관련 알림에 고유 키가 있는 특정
Person
객체를 포함하면 순위가 향상될 수 있습니다. 자세한 내용은 최고 순위 획득하기를 참조하세요.일반 메시지 앱의 경우 연락처마다 별도의 바로가기를 게시해야 하며
Person
필드에 연락처 정보가 포함되어야 합니다. 타겟을 여러 사람과 연결할 수 있는 경우(예: 그룹 채팅) 단일 공유 타겟에 여러Person
객체를 추가합니다.개인 바로가기를 게시하는 경우
setLongLabel()
에는 전체 이름을,setShortLabel()
에는 닉네임이나 이름 같은 짧은 이름을 포함하세요.
공유 바로가기를 게시하는 예를 보려면 공유 바로가기 샘플 코드를 참조하세요.
최고 순위 획득하기
Android Sharesheet에는 정해진 수의 직접 공유 타겟이 표시됩니다. 여기 제안되는 항목은 순위별로 정렬됩니다. 다음을 수행하여 바로가기의 순위를 향상할 수 있습니다.
- 모든 shortcutId가 고유하고 다른 타겟에 재사용되지 않는지 확인합니다.
setLongLived(true)
를 호출하여 바로가기가 오래 지속되는지 확인합니다.- 학습 데이터가 없을 때 앱의 여러 바로가기를 비교하는 데 사용할 수 있는 순위를 제공합니다.
setRank()
를 참조하세요. 순위가 더 낮으면 바로가기의 중요성이 더 높음을 의미합니다.
더욱 순위를 높이려면 소셜 앱에서 위의 모든 조치를 취한 후 다음 조치를 취하는 것이 좋습니다.
- 바로가기에서 설정된 키가 포함되어 있는 관련된
Person
객체를 제공합니다.setPerson()
,setPersons()
및setKey()
를 참조하세요. - 동일한 사람 한 명 또는 여러 명의 관련 알림에 바로가기를 연결합니다.
setShortcutId().
를 참조하세요. shortcutId는 이전에setLongLived(true)
를 사용하여 게시한 임의의 바로가기에 해당할 수 있습니다.
순위를 최대한 높이려면 소셜 앱에서 위의 모든 사항을 수행한 후 다음을 수행하면 됩니다.
- 제공된
Person
객체에는 기기의 연결된 연락처에 유효한 URI를 제공합니다.setUri()
를 참조하세요.
다음은 순위 향상을 위한 모든 조치를 취한 바로가기의 예입니다.
Kotlin
val person = Person.Builder() ... .setName(fullName) .setKey(staticPersonIdentifier) .setUri("tel:$phoneNumber") // alternatively "mailto:$email" or CONTENT_LOOKUP_URI .build() val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticPersonIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setPerson(person) .setLongLived(true) .setRank(personRank) .build()
자바
Person person = Person.Builder() ... .setName(fullName) .setKey(staticPersonIdentifier) .setUri("tel:"+phoneNumber) // alternatively "mailto:"+email or CONTENT_LOOKUP_URI .build(); ShortcutInfoCompat shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticPersonIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setPerson(person) .setLongLived(true) .setRank(personRank) .build();
Kotlin
val notif = NotificationCompat.Builder(myContext, channelId) ... .setShortcutId(staticPersonIdentifier) .build()
자바
Notification notif = NotificationCompat.Builder(myContext, channelId) ... .setShortcutId(staticPersonIdentifier) .build();
바로가기 이미지 제공하기
공유 바로가기를 만들려면 setIcon()
를 통해 이미지를 추가해야 합니다.
공유 바로가기는 시스템 화면 전체에서 표시할 수 있으며 그 형태를 변경할 수 있습니다. 바로가기가 의도한 대로 표시되는지 확인하려면 IconCompat.createWithAdaptiveBitmap()
를 통해 적응형 비트맵을 제공합니다.
적응형 비트맵은 적응형 아이콘의 가이드라인 및 측정기준 집합을 따라야 합니다. 이를 준수할 수 있는 가장 일반적인 방법은 원하는 정사각형 비트맵을 72x72dp로 확장하고 108x108dp 투명 캔버스의 중앙에 배치하는 것입니다.
특정 도형으로 마스킹된 이미지를 제공하지 마세요. 예를 들어 Android 10(API 수준 29) 이전에는 직접 공유 ChooserTarget
과 관련하여 원으로 마스킹된 사용자 아바타를 제공하는 것이 일반적이었습니다. 이제 Android Sharesheet 및 Android 10의 다른 시스템 화면은 바로가기 이미지의 도형과 테마를 설정합니다. 공유 바로가기를 제공하는 데 선호되는 메서드인 ShortcutManagerCompat를 사용하면 이전 버전과 호환되는 직접 공유 ChooserTarget
의 모양을 원으로 자동 설정합니다.
공유 타겟 선언
정적 바로가기 정의와 마찬가지로 앱의 리소스 파일에서 공유 타겟을 선언해야 합니다.
리소스 파일의 <shortcuts>
루트 요소 내에서 공유 타겟 정의를 다른 정적 바로가기 정의와 함께 추가합니다. 각 <share-targets>
요소에는 공유 데이터 유형, 일치하는 카테고리, 공유 인텐트를 처리하는 타겟 클래스와 관련된 정보가 포함되어 있습니다.
XML 코드는 다음과 비슷합니다.
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity"> <data android:mimeType="text/plain" /> <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" /> </share-target> </shortcuts>
공유 타겟의 데이터 요소는 인텐트 필터의 데이터 사양과 비슷합니다. 각 공유 타겟은 앱의 게시된 바로가기를 해당 공유 타겟 정의와 연결하는 데에만 사용되는 여러 카테고리를 가질 수 있습니다. 카테고리는 임의의 앱 정의 값을 가질 수 있습니다.
사용자가 Android Sharesheet에서 위의 타겟 공유 예와 일치하는 공유 바로가기를 선택하는 경우 앱이 다음과 같은 공유 인텐트를 가져옵니다.
Action: Intent.ACTION_SEND ComponentName: {com.example.android.sharingshortcuts / com.example.android.sharingshortcuts.SendMessageActivity} Data: Uri to the shared content EXTRA_SHORTCUT_ID: <ID of the selected shortcut>
사용자가 런처 바로가기에서 공유 타겟을 연 경우 앱은 ShortcutManagerCompat에 공유 바로가기를 추가할 때 생성된 인텐트를 가져옵니다.
인텐트가 서로 다르므로 Intent.EXTRA_SHORTCUT_ID
를 사용할 수 없으며, ID가 필요한 경우 ID를 수동으로 전달해야 합니다.
AndroidX를 사용하여 공유 바로가기와 ChooserTargets 모두 제공하기
AndroidX 호환성 라이브러리로 작업하려면 앱 매니페스트에 메타데이터 선택기 타겟 서비스와 인텐트 필터 집합이 포함되어 있어야 합니다.
현재 ChooserTargetService
Direct Share API를 참조하세요.
이 서비스는 호환성 라이브러리에 이미 선언되어 있으므로 사용자가 앱 매니페스트에서 서비스를 선언할 필요가 없습니다. 하지만 공유 활동을 서비스에 연결하는 링크를 선택기 타겟 제공자로 고려해야 합니다.
다음 예에서 ChooserTargetService
구현은 AndroidX에 이미 정의되어 있는 androidx.core.content.pm.ChooserTargetServiceCompat
입니다.
<activity android:name=".SendMessageActivity" android:label="@string/app_name" android:theme="@style/SharingShortcutsDialogTheme"> <!-- This activity can respond to Intents of type SEND --> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <!-- Only needed if you import the sharetarget AndroidX library that provides backwards compatibility with the old DirectShare API. The activity that receives the Sharing Shortcut intent needs to be taken into account with this chooser target provider. --> <meta-data android:name="android.service.chooser.chooser_target_service" android:value="androidx.sharetarget.ChooserTargetServiceCompat" /> </activity>
공유 바로가기 FAQ
현재 Sharing Shortcuts API와 이전 ChooserTargetService
Direct Share API의 주요 차이점은 무엇인가요?
Sharing Shortcuts API는 푸시 모델을 사용하는 데 비해, 이전 Direct Share API는 풀 모델을 사용합니다. 따라서 ShareSheet를 준비할 때 직접 공유 타겟을 검색하는 프로세스가 훨씬 더 빨라졌습니다. 앱 개발자의 관점에서 새 API를 사용할 때 앱에서는 직접 공유 타겟 목록을 미리 제공하고 앱의 내부 상태가 변경될 때마다 바로가기 목록이 잠재적으로 업데이트되어야 합니다(예: 메시지 앱에 새 연락처가 추가된 경우).
Sharing Shortcuts API를 사용하도록 이전하지 않으면 어떻게 되나요?
Android 10(API 수준 29) 이상에서 Android Sharesheet는 Sharing Shortcuts API를 사용하여 ShortcutManager를 통해 제공되는 공유 타겟에 더 높은 우선순위를 지정합니다. 따라서 게시한 공유 타겟이 다른 앱의 공유 타겟 아래에 있어 공유할 때 표시되지 않을 수 있습니다.
이전 버전과의 호환성을 위해 ChooserTargetService
및 Sharing Shortcuts DirectShare API를 모두 앱에서 사용할 수 있나요?
그렇지 않습니다. 대신, 제공된 지원 라이브러리 API ShortcutManagerCompat
를 사용하세요.
두 API를 함께 사용하면 공유 타겟을 검색할 때 원치 않는/예기치 않은 동작이 발생할 수 있습니다.
공유 타겟과 관련하여 게시된 바로가기와 런처 바로가기(런처에서 앱 아이콘을 길게 누를 때 사용되는 일반적인 바로가기)의 차이점은 무엇인가요?
'공유 타겟' 용도로 게시되는 모든 바로가기는 런처 바로가기이기도 하며 앱의 아이콘을 길게 누를 때 메뉴에 표시됩니다. 활동별 최대 바로가기 개수 제한이 앱에 게시되는 바로가기 총수에도 적용됩니다(공유 타겟과 기존 런처 바로가기 합산).