Android APP间共享文本数据和二进制数据

2016-08-29 · 🙈Lei · 0条 · 455次

>_ Sending Simple Data to Other APPs

当你构建意图,必须指明意图要触发的操作(action)。

在应用间发送和接收数据最多的使用场景是用于内容的社会化分享。意图使得用户可以简单快速地用他们最喜欢的应用分享信息。

Note: 在ActionBar添加分享操作项的最好方式是使用 ShareActionProvider,在API 14之后可用。

Send Text Content

使用ACTION_SEND操作最直接、最常用的方式是从一个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);

如果存在已经安装的应用的filter满足ACTION_SEND和MIME类型text/plain,Android系统会运行这个软件。如果多于一个应用满足条件,系统会显示一个选择器,用户可以从中选择一款软件来运行。

如果你调用了Intent.createChooser(),并且给它传递了你的Intent 对象,就总会显示选择器。这样有几个好处:

·即使用户已经选择了默认的操作,选择器仍然会显示。

·如果没有应用匹配,Android会显示一条系统消息。

·你可以为选择器对话框指定一个title。

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

另外一些标准extras: EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC, EXTRA_SUBJECT。如果接收应用不能使用这些extras,就会忽略这些意图。

Note: Some e-mail applications, such as Gmail, expect a String[] for extras like EXTRA_EMAIL and EXTRA_CC, use putExtra(String, String[]) to add these to your intent。

Send Binary Content

使用ACTION_SEND分享二进制数据,需要结合设置合适的MIME类型,以及在名为EXTRA_STREAM的extra中设置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)));

Note:

·可以使用”*/*”的MIME类型,但是这只会匹配可以处理通用数据流的activities。

·接收意图的应用需要具有访问Uri指向的数据的权限。推荐的操作方式:

~将数据存储在自己的ContentProvider中,确保其他应用对你的provider有正确的访问权限。更好的机制是使用 per-URI permissions ,这是暂时的,仅仅授予接收意图的应用访问的权限。创建ContentProvider的一个简单方式是使用 FileProvider 帮助类。

~使用系统的 MediaStore . MediaStore主要指video,audio和image MIME类型。但是从API 11(Android 3.0)开始,也可以存储non-media类型。文件(Files)可以使用scanFile()插入MediaStore中,在这之后一个content://样式的Uri会传递给 onScanCompleted() 这个回调。一旦内容被键入系统的MediaStore,就可以被设备上的所有APP访问。

Send Multiple Pieces of Content

要分享多个内容,使用 ACTION_SEND_MULTIPLE这个action,同时提供指向内容的一个URI列表。MIME类型根据混合分享内容而变化,例如分析3张JPEG图片,使用“image/jpeg”,如果分享不同类型的图片,使用“image/*”。如果分享多个包含多种类型(wide variety)的内容,应该使用“*/*”。就像前面说的,解析和处理数据就取决于接收意图的应用。

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

就像前面所说,确保提供的URI指向的数据可以被接收意图的应用访问。

>_ Receiving Simple Data from Other Apps

Update the Manifest

意图过滤器(Intent Filter)告知系统一个应用的组件期望接收何种意图。创建意图过滤器目的是为了接收带有指定action的意图。在清单文件中使用 <intent-filter> 元素来定义过滤器。如果你应用中的某个activity可以处理文本内容、单个图片类型、或者多个图片类型,可以像如下声明:

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

Note:For more information on intent filters and intent resolution, please read Intents and Intent Filters

Handle the Incoming Content

为了能够处理意图传递的内容,调用getIntent()方法来获取Intent对象。一旦获取到对象,就可以测试它的内容进而决定接下来要做什么 。记住:如果这个activity可以从系统的其他地方启动,例如启动器(launcher),在你测试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
}
}

Caution: 特别注意要检查来源数据,你从来都不会知道其他应用会发给你什么鬼东西。例如,可能会设置错误的MIME类型,或者图片可能极其大。同时,记住在一个单独的线程中处理二进制数据,而不是在主线程(“UI“进程)中。

更新UI可能只是填写一个EditText这么简单,也有可能想给一张图片添加一个有意思的滤镜一样复杂。很明确接下来你的应用会发生什么。正因为要明确,所以要判断好到底来的是什么鬼东西。

>_ Adding an Easy Share Action

使用在android4.0中提供的ActionProvider使得在ActionBar中实现一个有效的、用户友好的分析操作更加容易。只要在action bar的menu项中添加一个分享操作,就可以为其自动提供外观和行为。得益于ShareActionProvider,你只需提供一个分享的意图,其他的事情它自己已经做好。

Note: ShareActionProvider 只在API 14以及更高的版本中可用。

Update Mnu Declarations

要使用ShareActionProvider ,需要在menu资源文件中对应的<item>里定义android:actionProviderClass 属性。

<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的外观以及功能,你只需要提供要分享的内容。

Set the Share Intent

To assign a share intent, first find the corresponding MenuItem while inflating your menu resource in your Activity or Fragment. Next, call MenuItem.getActionProvider() to retrieve an instance of ShareActionProvider. Use setShareIntent() to update the share intent associated with that action item.

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

可以在创建menus的时候就设置好分享意图,也可以在UI改变的时候设置并改变它。例如,但你在相册APP中全屏浏览图片,当你切换图片的时候意图也会改变。

For further discussion about the ShareActionProvider object, see Action Views and Action Providers.(这个我还没看№)


  0