当你构造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); } }