當你構造intents的時候,必須先定義你想要intent觸發的action。Android定義了若干action,包括ACTION_SEND,正如你猜到的,這個action被用來在activity之間傳遞數據,甚至在進程之間。爲了向其餘activity傳輸數據,你須要作的僅僅是定義數據和他的類型。系統將識別可接收的activity,而且展現選擇項(若是有多個符合要求的選擇項),或者馬上啓動接收activity(若是隻有一個符合要求的接收activity)。java
activity之間傳遞數據的最簡單、直接的使用ACTION_SEND的方式是傳遞文本。例如,內置的瀏覽器應用將展現頁面的url做爲數據分享給其餘應用。對於經過email或社交軟件分享文章或網址這很是有用。
android
Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.setType("text/plain"); startActivity(sendIntent);
若是一個安裝的app帶了過濾器能夠匹配ACTION_SEND和MIME類型的text/plain,android系統將運行這個app,若是超過一個將會提供選擇。瀏覽器
然而,若是你調用Intent.createChooser(),將你的Intent做爲參數傳遞過去,這將老是返回可選項界面。網絡
Intent sendIntent = new Intent(); 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)));
可選地,你能夠爲intent設置一些標準參數,如:EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC, EXTRA_SUBJECT.若是這個接收的app沒有設置接收這些參數,這個參數將被忽略。app
二進制數據也能夠經過ACTION_SEND分享,一般組合相適應的MIME類型以及將uri的數據放置在EXTRA_STREAM中。這種方法常常被用來分享圖片但也能夠被用來分享其餘二進制數據。
ide
Intent shareIntent = new Intent(); 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)));
有如下幾點須要注意:
ui
你能夠將MIME類型設置爲*/*,但這種類型將只配置能夠處理通常數據流的activity。google
接收app須要讀取uri指向的數據的權限,有以下推薦方式:url
存儲數據在contentProvider中,保證別的應用程序對你的provider有正確的權限, 對於保護權限的優先方案是使用前綴URI權限,這個權限是臨時的或是僅向接收app開放權限。建立一個contentProvider的簡單方式是使用FileProvider幫助類。spa
使用系統MediaStore。Mediastore最初被設計用於video、audio和圖片類型,可是3.0後也被用於存儲非媒體類型。適於分享的content://類型的Uri能夠做爲onScanCompleted()回調方法的參數,這以後文件能夠經過scanFile()方法被插入到MediaStore中。須要注意的是一旦被加入到系統MediaStore中,設備中的全部app均可以操做這個文件。
爲了分享多個內容,你須要指定action爲ACTION_SEND_MULTUPLE,同時傳遞指向具體內容URIs。例如發送一個JPEG圖片時,須要設置成「image/jpeg",可是不一樣的圖片類型時,須要設置成"image/*",若是你想要分享各類類型的內容,須要設置成「*/*」.如前面所述,這些都取決於接收app怎麼解析和處理數據。
ArrayList<Uri> imageUris = new ArrayList<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.."));
此外也要注意,你提供的URIs指向的數據能夠被接收的app操做。
你的app不只能夠發送數據,也能夠接收數據。考慮下用戶怎樣和你的app交互,你想要接收怎樣的數據。例如,社交網絡app可能對接收文本內容,好比網址,感興趣。google+應用能夠接收文本和圖片。經過這個app用戶能夠輕鬆的向google+傳遞照片。
Intent過濾器通知系統應用程序想要接收怎樣的intents。和構造intent類似,須要建立intent過濾器以可以接收肯定action的intent。能夠在mainfest中使用<intent-filers>來建立過濾器。
<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>
當另外一個app想要分享這些內容中的一些時,你的app將被列在可選項中。
爲了處理被intent傳輸的內容,能夠經過getIntent()方法獲取intent對象。一旦你持有這個對象,你能夠檢驗傳輸的內容來決定下一步作什麼,須要注意的是若是一個activity能夠被系統別的部分啓動,好比桌面,須要將檢查intent歸入考慮範圍。
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 } }
當心 : 在當心檢查接收的數據時,因爲你不可能知作別的app發送給你什麼樣的數據,多是錯誤的MIME類型,也多是超大的圖片文件。因此須要記住要在工做線程中處理二進制數據而不是在UI線程。
實現有效、用戶友好的分享操做因爲4.0裏actionProvider的引進變得相對簡單了。actionProvider曾經和菜單項相關聯,用來出來這項的外表和行爲。
爲了使用shareActionProviders,須要在menu資源文件的<item>子項裏定義android:acionProviderClass屬性。
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_item_share" android:showAsAction="ifRoom" android:title="Share" android:actionProviderClass= "android.widget.ShareActionProvider" /> ... </menu>
ShareActionProvider負責這個項的外貌和做用。然而你須要告訴這個provider你想要分享什麼。
爲了使ShareActionProvider起做用,你必須爲它提供一個分享intent。爲了指派分享intent,首先找到這個相應的菜單項,這能夠在activity或fragment加載菜單資源文件時操做,下一步,調用MenuItem.getActionProvider()方法獲取ShareActionProvider實例,使用setShareIntent()更新和操做項相關的分享intent。
private ShareActionProvider mShareActionProvider; ... @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate menu resource file. getMenuInflater().inflate(R.menu.share_menu, menu); // Locate MenuItem with ShareActionProvider MenuItem item = menu.findItem(R.id.menu_item_share); // Fetch and store ShareActionProvider mShareActionProvider = (ShareActionProvider) item.getActionProvider(); // Return true to display menu return true; } // Call to update the share intent private void setShareIntent(Intent shareIntent) { if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(shareIntent); } }