就像應用程式可以傳送資料給其他應用程式一樣,它也可以接收其他應用程式的資料。思考使用者與應用程式互動的方式,以及您預期從其他應用程式接收的資料類型。例如,社交網路應用程式可能會想接收來自其他應用程式的文字內容,例如有趣的網址。
其他應用程式的使用者經常透過 Android Sharesheet 或意圖解析器,將資料傳送至您的應用程式。將資料傳送至應用程式的應用程式必須設定該資料的 MIME 類型。應用程式可透過下列方式接收其他應用程式傳送的資料:
- 在資訊清單中有相符
intent-filter
標記的Activity
- 分享應用程式發布的捷徑。
直接分享目標是導向應用程式中特定活動的深層連結。這類目標通常代表個人或群組,而 Android Sharesheet 會顯示這些目標。 舉例來說,訊息應用程式可提供直接分享目標,讓使用者透過深層連結直接加入對話。如需詳細操作說明,請參閱「提供直接分享目標」。
支援 MIME 類型
在理想情況下,應用程式必須能夠接收最廣泛的 MIME 類型範圍。舉例來說,專門用於傳送簡訊、圖片和影片的訊息應用程式,最好支援接收 text/*
、image/*
和 video/*
。以下列舉幾種在 Android 中傳送及接收簡易資料的常見 MIME 類型。
收款人註冊 | 寄件者傳送 |
---|---|
text/* |
|
`image/*` |
|
video/* |
|
支援的副檔名 | application/pdf |
請參閱 IANA 正式登錄的 MIME 媒體類型。
設定最佳的分享目標
當使用者輕觸與特定活動相關聯的共用目標時,應先確認及編輯共用內容,然後再使用該內容。這對於文字資料而言特別重要。
透過活動接收資料
使用活動接收資料包括更新資訊清單、處理傳入內容,以及確保使用者識別您的應用程式。
更新資訊清單
意圖篩選器會告知系統應用程式元件接受的意圖。與在將簡單資料傳送至其他應用程式課程中的 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 } }
Java
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 } }
收到資料後更新使用者介面可以和填入 EditText
一樣簡單,也可能更複雜,例如為圖片套用有趣的相片濾鏡。一切都取決於應用程式接下來的情況
確保使用者認得您的應用程式
您的應用程式會在 Android Sharesheet 和意圖解析器中以圖示和標籤表示。這兩者都是在資訊清單中定義。您可以設定活動或意圖篩選器標籤來提供更多背景資訊。
自 Android 10 (API 級別 29) 起,Android Sharesheet 只會使用 application
標記在資訊清單中設定的圖示。Android 會忽略 intent-filter
和 activity
標記上設定的圖示。