다른 앱에서 데이터 수신

앱이 다른 앱에 데이터를 전송할 수 있는 것처럼 다른 앱에서 데이터를 수신할 수도 있습니다. 사용자가 애플리케이션과 상호작용하는 방식과 다른 애플리케이션에서 수신하려는 데이터 유형을 생각해 보세요. 예를 들어 소셜 네트워킹 애플리케이션은 다른 앱에서 흥미로운 웹 URL과 같은 텍스트 콘텐츠를 수신하는 데 관심이 있을 수 있습니다.

Compose 탐색을 사용하는 앱에서 다른 앱이 전송한 데이터를 수신하는 것은 3단계 프로세스입니다.

  1. 매니페스트에서 <intent-filter> 선언: AndroidManifest.xml 파일의 활동에 인텐트 필터를 추가해야 합니다. 이렇게 하면 애플리케이션이 특정 작업(ACTION_SEND와 같은)과 MIME 유형 (text/plain과 같은)을 수신할 수 있다고 Android OS에 알립니다.

  2. Compose 탐색 그래프에서 navDeepLink 정의: 작업 및 MIME 유형과 일치하는 navDeepLink를 콘텐츠를 표시해야 하는 컴포저블 대상에 직접 연결합니다. NavController는 수신 인텐트를 자동으로 가로채고 사용자를 해당 화면으로 직접 라우팅합니다.

  3. 수신 데이터 페이로드 추출: 대상 화면에서 인텐트 추가 항목 (EXTRA_TEXT 또는 EXTRA_STREAM과 같은)에 액세스하여 공유 콘텐츠를 가져오고 UI 상태를 업데이트합니다.

직접 공유 대상은 앱 내의 특정 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

IANA MIME 미디어 유형 공식 레지스트리를 참고하세요.

훌륭한 공유 대상 만들기

사용자가 특정 활동과 연결된 공유 대상을 탭하면 앱에서 공유 대상을 사용하기 전에 공유 콘텐츠를 확인하고 수정할 수 있도록 합니다. 이는 텍스트 데이터에 특히 중요합니다.

앱에서 데이터 수신

Compose를 사용하는 앱에서 공유 데이터를 수신하려면 매니페스트에서 인텐트 필터를 선언하고, 딥 링크를 사용하여 수신 인텐트를 적절한 화면으로 라우팅하고, 인텐트에서 페이로드를 추출하여 UI를 업데이트해야 합니다.

매니페스트 업데이트하기

인텐트 필터는 앱 구성요소가 수락하는 인텐트를 시스템에 알립니다. 다른 앱에 데이터 전송 수업에서 ACTION_SEND 작업으로 인텐트를 구성한 방식과 마찬가지 로 이 작업으로 인텐트를 수신하는 인텐트 필터를 만듭니다. <intent-filter> 요소를 사용하여 매니페스트에서 인텐트 필터를 정의합니다. 예를 들어 앱에서 텍스트 콘텐츠 수신을 처리하는 경우 모든 유형의 이미지를 하나 이상 포함하는 매니페스트는 다음 스니펫과 같습니다.

<activity android:name=".ui.MyActivity" android:exported="true">
    <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 내에서 콘텐츠를 적절하게 처리하는 것은 개발자의 몫입니다.

Compose 탐색에서 콘텐츠를 표시해야 하는 컴포저블 대상에 navDeepLink를 직접 연결합니다. 다른 앱이 인텐트 필터와 일치하는 공유 데이터를 공유하면 Compose 탐색은 사용자를 이 대상으로 직접 라우팅합니다.

navDeepLink는 수신 인텐트의 작업 및 MIME 유형과 일치하여 올바른 대상 화면으로 이동합니다. 대상에 도달하면 핸들러가 인텐트를 검사하여 수신된 페이로드 (예: 단일 이미지와 여러 이미지)를 확인하고 해당하는 추가 항목을 추출합니다.

수신되는 콘텐츠 처리하기

Intent에서 제공하는 콘텐츠를 가져오려면 컴포저블 내의 LocalActivity.current에서 현재 활동을 읽은 다음 인텐트를 검사하여 다음에 수행할 작업을 결정합니다. 이 활동을 시스템의 다른 부분 (예: 런처)에서 시작할 수 있는 경우 인텐트를 검사할 때 이를 고려하세요.

수신 데이터를 확인하는 데 특히 주의하세요. 잘못된 MIME 유형이 설정되거나 전송되는 이미지가 매우 클 수 있습니다. 기본 UI 스레드에서가 아니라 코루틴 (Dispatchers.IO와 같은)을 사용하여 바이너리 데이터 또는 I/O 집약적 작업 (예: 대용량 이미지 디코딩 또는 파일 쓰기)을 비동기식으로 처리합니다.

@Composable
fun SharesheetHandler() {
    val activity = LocalActivity.current
    val intent = activity?.intent

    when (intent?.action) {
        Intent.ACTION_SEND -> {
            if (intent.type == "text/plain") {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }

        Intent.ACTION_SEND_MULTIPLE -> {
            if (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 state with the shared text
    }
}

private fun handleSendImage(intent: Intent) {
    val imageUri = IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java)
    imageUri?.let {
        // Update UI state with the shared image
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    val imageUris =
        IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri::class.java)
    imageUris?.let {
        // Update UI state with the shared images
    }
}

인텐트 추가 항목 (예: EXTRA_STREAM)에서 바이너리 데이터 또는 URI를 추출할 때는 이전 handleSendImage 및 handleSendMultipleImages 함수에 표시된 대로 AndroidX Core 라이브러리의 IntentCompat.getParcelableExtra() 또는 IntentCompat.getParcelableArrayListExtra()를 사용합니다. Android 13 (API 수준 33)에서는 예상되는 클래스 유형을 사용하는 유형 안전 메서드를 위해 매개변수가 없는 Intent.getParcelableExtra(String) 메서드를 지원 중단합니다.

데이터를 수신한 후 UI를 업데이트하는 것은 상태를 업데이트하여 TextField를 채우는 것만큼 간단하거나 이미지에 필터를 적용하는 것만큼 복잡할 수 있습니다. 다음에 발생하는 작업은 앱에 달려 있습니다.

스크린샷 URL 공유

스크린샷을 찍을 때 스크린샷과 연결된 URL을 공유할 수 있습니다. 이렇게 하면 사용자 환경이 더 풍부해집니다. URL을 수신할 때는 다음 예와 같이 인텐트에서 EXTRA_TEXT 필드를 가져와야 합니다.

IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let {
    // Handle the EXTRA_TEXT as well
    val extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT)
    // Update UI state with the shared image and the EXTRA_TEXT if available
}

사용자가 앱을 인식하게 만들기

앱은 Android Sharesheet 및 인텐트 확인 도구에서 아이콘과 라벨로 표시됩니다. 이 두 가지는 모두 매니페스트에 정의되어 있습니다. 활동 또는 인텐트 필터 라벨을 설정하여 더 많은 컨텍스트를 제공할 수 있습니다.

Android 10 (API 수준 29)부터 Android Sharesheet는 application 태그의 매니페스트에 설정된 아이콘만 사용합니다. Android는 intent-filter 및 activity 태그에 설정된 아이콘을 무시합니다.

리치 콘텐츠 받기

ACTION_SEND 인텐트를 사용하면 활동 또는 탐색 수준에서 Android Sharesheet 및 인텐트 확인 도구에서 데이터를 수신할 수 있지만 앱은 직접 UI 상호작용을 통해 리치 콘텐츠 (예: 이미지, 동영상, 오디오 파일, 스타일이 지정된 텍스트)를 수신할 수도 있습니다. 이러한 메커니즘에는 다음이 포함됩니다.

  • 클립보드에서 붙여넣기 (길게 터치 메뉴)
  • 스티커 또는 GIF와 같은 소프트웨어 키보드 (IME)에서 직접 미디어 삽입
  • 멀티 윈도우 또는 화면 분할 모드에서 다른 앱의 콘텐츠 드래그 앤 드롭

뷰 기반 UI에서 Android 12 (API 수준 31) 및 AndroidX Core 1.7은 통합된 OnReceiveContentListener API를 도입합니다. 이 리스너는 클립보드, 키보드, 드래그 앤 드롭의 콘텐츠 처리를 단일 콜백으로 통합합니다. 뷰에서 이를 구현하는 방법에 관한 자세한 안내는 리치 콘텐츠 수신을 참고하세요.

Jetpack Compose에서는 텍스트 필드와 같은 UI 구성요소에 삽입된 리치 콘텐츠 수신을 처리할 수 있습니다. Modifier.contentReceiver 수정자 또는 드래그 앤 드롭 수정자를 사용하여