分享简单的数据 Share Simple Data 翻译自developer.android.com

来源:互联网 发布:长春网络营销软件价格 编辑:程序博客网 时间:2024/06/05 06:02

android应用程序的一个强大功能就是彼此的沟通和融合。当你的应用在已经准备好和另一个应用交互的时候,为什么不不在你的app中添加这个核心功能呢?

这节中讲了一下在应用之间分享数据的常用方法,比如使用Intent API或者 ActionProvider API来发送和接受数据。


向其他应用发送简单的数据


当你构造一个intent,你需要指定intent会触发什么。android定义了几种动作,包括ACTION_SEND, 你可以猜到这个动作是从一个activity到另一个activity传递数据的,尽管可能跨越进程。向另一个activity传递数据,你需要做的 就是声明数据和数据的类型,系统会选取与之相匹配的接收activity,如果有多个选项就会显示给用户,如果只有一个选项就会直接开启activity。你可以在你的activity manifest里面声明你的activit想要接收的数据类型。

使用intent在应用之间传递数据是分享社交内容十分常用的一种方式。Intent允许用户可以快捷和容易地使用它们的应用来分享。
注意:在ActionBar上添加一个shareAction的最好的办法是实用ShareActionProvider,他在APIlevel14 以上可以使用。SahreActionProvider在Adding an Easy Share Action里面有介绍。

发送文字内容

使用ACTION_SEND的最直接和常用的办法就是从一个activity到另一个activity之间传递文本。例如,内置的浏览器可以给正处在浏览的网页的URL分享给其他的应用程序。在使用邮件或者社交网络分享一篇文章或者内容的时候就十分有用。下面就是实现这种类型分享的代码。

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);

如果已经安装的应用中有ACTION_SEND和MIME类型为text/plain类型的过滤器,android系统就会运行它。如果有超过一个应用匹配,系统就会弹出一个选择对话框来让用户选择使用哪一个app。

然而,如果你调用Intent.creatChooser(),传入这个Intent对象,就会返回一个一定会出现选择对话框的intent。这有一些优点:

- 尽管用户之前已经选择了默认的应用,这个选择框还是会弹出来。
-如果没有应用可以匹配,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(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
结果对话框如图1所示:


你也可以选择下面的标准的extra,如EXTRA_EMAIL,EXTREA_CC,EXTRA_SUBJECT。如果接受应用没有设计用来使用这些,就会忽略。

提示:
一些邮件的应用比如Gmail会期待接受一个包含extras的String数组,比如说EXTRA_EMAIL,EXTRA_CC,使用putExtra(String,String())来把这些添加到intent中。

发送二进制内容

分享二进制数据需要使用ACTION_SEND,结合一个MIME类型设置,并且在extra中的EXTRA_STAREAM指定URI。这种方法经常被用来分享照片,但是分享其他的二进制内容也是可以的。

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)));

注意下面几点:
- 你可以使用“*/*”的MIME类型,但是这只可以匹配设置了处理泛型数据流的activity。
- 接受的app需要拥有访问Uri指向资源的访问权。推荐使用下面的做法:
* 使用ContentProvider来存储你的app的数据,确保其他的应用对于你的provider有正确的访问权限。好的提供访问的一种机制就是使用per-URI许可,它是短期的,并且赋予接受app访问权。创建这样的ContentProvider的简单方法就是使用FileProvider的帮助类。

* 使用系统媒体库MediaStore。MediaStore的基本目的就是针对于视频,音频和图片这些MIME类型,但是从android3.0开始也支持了非媒体类型(可见MediaStore.Files的更多信息)。向MediaStore插入数据的时候,我们使用scanFile方法,在这个方法后,一个content://类型的 ,用来分享的uri就会被传递到onScanCompleted()回调方法中。需要注意到一旦加入到系统媒体库,就可以被设备上面的任何app进行访问了。

发送多部分的内容

分享多部分的内容,可以使用ACTION_SEND_MULTIPLE 的action,并传入一串指向内容的uri。MIME类型根据你混合的内容不同而类型各不相同。例如,如果你分享3个JPEG图像,那么类型仍然是“image/jpeg”。对于混合图片类型,类型表示就该是"image/*”。如果你分享了一个很宽广的类型,那么你只能使用 “*/*”标志。 基于以上,接下来就到了接受app解析和处理数据的时候了,下面是一个例子:


ArrayList<Uri> imageUris = new ArrayList<Uri>();imageUris.add(imageUri1); // Add your image URIs hereimageUris.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.."));

上面这种情况的话,你要确保接受app的可以访问这些uri。



第二节 从其他的app中接受简单的数据

正如你的应用可以向其他应用发送数据一样,你的应用也可以接受其他的应用发送过来的数据。思考你的应用想要怎样与用户进行交互,以及你的应用要接受何种类型的数据。例如一个社交app就会经常接受文本内容,比如从其他app来的网页url。一个android应用,Google+就可以接受文本,同时一个或者多个图片。使用这个app,用户可以轻易滴使用Adrnoid相册app来创建一个新的Google+的相片分享。

更新你的Manifest

Intent Fileter会通知系统应用组件想要接受那种类型的Intent。类似你在Sending Simple Data to Other Apps一节中的,你构造的带有action ACTION_SEND的intent,你创建这样的fileter来接受这样的动作的intent。在manifest中使用<intent-filter>来创建。例如,如果你的app想要接受一个文本内容,一个任何格式的图片或者任何几个图片,就可以如下面这样写:

<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>

提示:更多的关于intentFilter和intent solution的内容请参见 Intents and Itent Filters。
当另一个应用创建一个intent并将其传递给startAcitivity来分享这些内容的时候,你的应用会被列举在选择列表上,如果用户选择了你的activity,对应的activity就会被启动,比如本例中的就是(.ui.MyActivity)。接下来就是你的代码怎样处理数据和显示ui的问题了。



处理接受的内容

要处理通过Intent传递过来的内容,调用getInent()方法来获取一个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    }}


警告:你需要另外注意接收到的数据,因为你无法知道其他的应用会给你发送什么。例如,传递了错的的MIME类型,或者传递的图片过于庞大。另外记得,对于二进制数据的处理要放在子线程当中,而不是UI线程当中。

更新UI可能同向EditText中填充内容一样简单,也可能如同为一个相片应用兴趣相片过滤器。下面发生什么完全取决于你的代码。


第三节 添加简易分享动作  Adding an Easy Share Action

使用Android4.0中的ActionProvider可以更加容易的创建高效的,用户友好的 ActionBar中的share动作。ActionProvider一旦在actionbar中附着到了菜单项目中,就可以负责管理这个item的外观和行为。如果使用ShareActionProvider,你提供share intent,他就会为你做其他的事情。 

注意:ShareActionProvider在API level 14以上是可用的。

更新目录的声明

要使用ShareActionProviders,定义android:actionProviderClass 属性, 在你的menu resourse 文件中的<item>标签下:

<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>

这个托管负责item的外观和他的行为。但是你需要告诉provider你想要分享什么。


设置分享Intent

要使用ShareActionProvider的方法,你必须要提供share intent。你的share intent应该和Sending Data to Other Apps一课中的表述的一样,拥有action ACTION_SEND和通过extra设定的EXTRA_TEXT和EXTRA_STREAM。要指派一个share intent,首先在activity或者fragement中填充你的 目录资源的时候找到对应的MenuItem。接下来,调用Menu.getActionProvider()来检索一个ShareActionProvider的实例。使用setShareIntent()来更新和action item相关联的shareIntent。下面是一个例子。

private ShareActionProvider mShareActionProvider;...@Overridepublic 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 intentprivate void setShareIntent(Intent shareIntent) {    if (mShareActionProvider != null) {        mShareActionProvider.setShareIntent(shareIntent);    }}


你只需要在你的菜单创建的时候设置一次 share intent 。或者你可能想设置它并在ui更新的时候更新他。例如,当你的照片在相册应用中全屏的时候,在你滑动切换照片的时候,sharing intent 就是改变的。

等多的关于ShareActionProvider的对象的讨论,参见Action Views 和 Action Providers。






















0 0