本文译自:http://developer.android.com/training/sharing/send.html
在构造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所指向的数据。