在構造Intent對象時,你必須要指定打算要觸發的操作。Android系統定義了幾個操作,其中包括ACTION_SEND,就像你猜測的一樣,這個操作指明了Intent對象要一個Activity向另外一個Activity發送資料,即使是跨進程邊界。要把資料發送給另外的Activity,就需要指定資料和對應資料的類型,然後,系統會識別相應的接收該Intent對象的Activity,並把它們顯示給使用者(如果有多個Activity可選的情況),或者是直接啟動相應的Activity(只有一個Activity可選的情況下)。類似的,你可以通過你的應用程式的資訊清單檔來指定你的Activity所能接收的來自其他應用程式的資料類型。
用Intent對象在應用程式之間來發送和接收資料,常用於社交類應用之間的內容共用。Intent允許使用者快速而簡單的共用資訊,以便使用他們所喜愛的應用程式。
注意:添加共用操作的最好方式是使用ShareActionProvider類把共用操作項添加到一個ActionBar中,ShareActionProvider在API Level 14中有效。
發送常值內容
最直接並且最常使用的是ACTION_SEND操作,它會把常值內容從一個Activity發送給其他的Activity。例如,內建的Browser應用能夠當前顯示頁的URL作為文本共用給其他任意應用程式。這對通過電子郵件或社交網路來跟朋友共用文章或網站是有好處的。以下樣本就實現了這種類型的共用:
Intent sendIntent =newIntent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
如果系統安裝了擁有ACTION_SEND操作和text/plain的MIME類型的過濾器,那麼Android系統就會運行對應的應用程式;如果有多個應用程式跟這個請求匹配,系統就會顯示一個選擇對話方塊,在該對話方塊中允許使用者選擇一個能夠接收該請求的應用程式。如果你調用的是Intent.createChooser()方法,那麼Android系統就始終會顯示該選擇對話方塊。這樣做的好處如下:
1. 即使使用者之前針對該Intent選擇了預設的操作,該選擇對話依然會被顯示;
2. 如果沒有與之匹配的應用程式,Android系統會顯示一個系統訊息;
3. 你可以給選擇對話方塊指定一個標題。
以下是對上述代碼的更新:
Intent sendIntent =newIntent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
顯示的結果對話方塊1所示。
圖1.在手持功能上,ACTION_SEND操作所顯示的對話方塊。
可選的,你可以針對該Intent設定一些標準的附加資訊:EXTRA_EMAIL、EXTRA_CC、EXTRA_BCC、EXTRA_SUBJECT。但是,如果接收應用程式沒有被設計成要使用這些資訊,那麼就不會發生任何事情。你也可以使用定製的附加資訊,但是除非接收應用程式能夠理解它們,否則不會有任何影響。典型的,你應該使用接收應用程式自己定義的定製化附加資訊。
注意:某些電子郵件應用程式,如Gmail,它會期望一個像EXTRA_EMAIL和EXTRA_CC這樣的String[]類型的附加資訊,你可以使用putExtra(String, String[])方法把它添加到你的Intent對象中。
發送二進位內容
使用ACTION_SEND操作,同時結合設定適當的MIME類型。並把指向資料的URL放置到名叫EXTRA_STREAM的附加欄位中,就可以共用位元據。這種方法常用於共用圖片,但它可以被用於任何類型的二進位內容:
Intent shareIntent =newIntent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
注意下列事項:
1. 你可以使用“*/*”的MIME類型,但是這樣只會跟能夠處理一般的資料流的Activity相匹配。
2. 接收端應用程式需要授權才能訪問Uri所指向的資料。有很多方法來處理這件事:
A. 把資料寫入外部/共用儲存空間(如SD卡)上的檔案中,這樣所有的應用程式都可以讀取該檔案。使用Uri.fromFile()方法來建立一個能夠傳遞給共用Intent的Uri對象。但是。要記住不是所有的應用程式都能夠處理file://樣式的Uri對象
B. 把資料寫入你自己應用程式目錄中的一個檔案,該檔案要使用帶有MODE_WORLD_READABLE模式的openFIleOutput()方法來建立,然後就可以使用getFileStreamPath()方法來返回對應的File對象。與A選項的方法一樣,使用Uri.fromFile()方法給共用的Intent對象建立一個file://樣式的Uri對象。
C. 像圖片、視頻和音頻等能夠被掃描,且被添加到系統媒體庫(MediaStore)中的多媒體檔案,可以使用scanFile()方法來檢查檔案是否存在,onScanCompleted()回調方法會返回一個用於共用Intent對象中所包含的content://樣式的Uri對象。
D. 使用insertImage()方法可以把圖片插入到系統的MediaStore(媒體庫)中,該方法會返回一個用於共用Intent對象中所包含的content://樣式的Uri對象。
E. 用你自己的ContentProvider對象來儲存資料,確保其他的應用程式擷取正確的授權,就可以訪問你的內容提供器了。
發送多條內容
要共用多條內容,就要使用ACTION_SEND_MULTIPLE操作,以及跟該操作一起的指向內容的URI列表。MIME類型會根據共用的內容而不同。例如,如果你共用了3張JPEG圖片,那麼MIME類型應該是“image/jpeg”。對於多種圖片類型,它應該是“image/*”,這樣處理任何類型圖片的Activity都可以跟它匹配。如果你要共用各種類型的資料,那麼應該值使用“*/*”。如前所述,接收應用程式會解析和處理你的資料。例如:
ArrayList<Uri> imageUris =newArrayList<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, "Share images to.."));
要確保接收應用程式能夠訪問URI所指向的資料。