接收其他應用程式傳送的簡單資料

就像應用程式可以傳送資料給其他應用程式一樣,它也可以接收其他應用程式的資料。思考使用者與您的應用程式互動的方式,以及您希望從其他應用程式接收的資料類型。舉例來說,某個社群網路應用程式可能會想要從其他應用程式接收文字內容,例如有趣的網址。

其他應用程式的使用者經常透過 Android Sharesheet 或意圖解析器將資料傳送至您的應用程式。將資料傳送至應用程式的應用程式必須針對該資料設定 MIME 類型。您的應用程式可以透過下列方式接收其他應用程式傳送的資料:

  • 資訊清單中含有相符 intent-filter 標記的 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 媒體類型註冊資料庫。

建立良好的分享目標

當使用者輕觸與特定活動相關聯的共用目標時,他們應能在使用共用內容前確認及編輯內容。這對於文字資料特別重要。

透過活動接收資料

接收活動資料需要更新資訊清單、處理傳入內容,並確保使用者能辨識您的應用程式。

更新資訊清單

意圖篩選器會告知系統應用程式元件接受哪些意圖。與在「將簡單資料傳送至其他應用程式」課程中使用 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
    }
}

在收到資料後更新 UI 非常簡單,也可以填入 EditText,也可以更複雜,例如將有趣的相片濾鏡套用至圖片。應用程式接下來會發生什麼事

確保使用者認出您的應用程式

您的應用程式會在 Android Sharesheet 和意圖解析器中以圖示標籤表示。這兩個屬性都是在資訊清單中定義。您可以設定活動或意圖篩選器標籤來提供更多背景資訊。

自 Android 10 (API 級別 29) 起,Android Sharesheet 只會使用 application 標記上資訊清單設定的圖示。Android 會忽略在 intent-filteractivity 標記上設定的圖示。