闭门造车姚师傅

[意译] Android-分享一些简单的数据

字数统计: 1.1k阅读时长: 4 min
2016/10/22 Share

原文地址:Sending Simple Data to Other Apps

​ 当你建立一个Intent的时候,你必须指定这个Intent可以触发的Action。Android定义了一些Action,包括ACTION_SEND,就像它的字面意思,这个Intent是从当前Activity发送数据到另一个Activity,甚至是别的进程的里的Activity。如果想在Activity之间传送数据的话,你需要做的仅仅是指定数据以及它的类型。系统就会寻找可以接收的Activity,并且直接启动这个Activity,如果有很多个Activity都被认为可以处理这些数据,系统则显示一个包含这些Activity的列表。同样,你也可以在manifest文件中声明你的Activity可以从其他应用中接收什么数据。

名词解释:

MIME :: Multipurpose Internet Mail Extensions

URI :: Uniform Resource Identifier

1. 发送文本内容

1
2
3
4
5
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); //隐式Intent

​ 通常我们通过显式指定一个Intent的Action来做一些精确的逻辑传递,比如通过传入SomeActivity.class来启动一个应用。但是分享的时候,应该由用户决定分享给谁,所以在Intent中只是模糊的把描述了一下即将发生的动作。比如在上面的代码中,Action就是发送类型为文本的数据。如果只有一个程序声明为可以处理这种情况的话,这个程序中相关的Activity会直接被启动。当然更多情况下我们看到是包含了许多项的列表。

​ 同样可以使用Intent .createChooser() 来传递你的Intent对象。这会在任何时候都弹出一个选择框,即使用户之前对这种情况进行了默认设置。比如输入法之类的软件引导用户将自己设置为默认应该就是这种套路。

采用这种传递方式,如果没有应用可以启动,Android会显示一个系统消息给用户。而且,你可以通过该方法的第二个元素来指定选择对话框的标题。

1
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));//第二个元素用来指定选择框的标题

2. 发送二进制内容

​ 通常这种方法用于分享图片,但是任何类型的二进制文件也都是可以通过这种方式分享的。通过给ACTION_SEND设置适当的MIME type并且把URI以EXTRA_STREAM来传递二进制数据。

1
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
  • Intent的接收方应该有URI指向位置的访问权限,不然会发生些不好的事情。这里给出了一些比较好的解决方案。
    • 在自己拥有的ContentProvider中存放要分享的数据,并且为接收方设定provider的访问权限。可以通过per-URI permission 机制给予接收方暂时的特异性的访问权限。一种比较简单的方法是使用FileProvider帮助类来穿件ContentProvider。
    • 使用系统的 MediaStore。MediaStore主要针对视频、音频、图片这些类型,在Android3.0之后,它还可以存储非媒体类的数据。先将一个合适的content://格式的URI传入onScanCompleted() 回调,然后使用scanFile() 方法将文件插入 MediaStore。

3. 一次性发送多条数据

使用ACTION_SEND_MULTIPLE,如果多个数据都是同一数据类型的话,比如三个JPEG文件,那么MIME仍然应该为 image/jpeg。如果传递的是同一大类型中的多种不同格式的数据的话,比如JEPG和PNG一起,应该使用image/* 作为MIME。只有传输的数据包含很多类型的时候,你才应该使用*/*,不然会一定程度上影响分享的精准度,返回一个很大的选择项列表给用户,而且传送过去的数据还很可能得不到很好的处理。

下面是一个简单的示例。

1
2
3
4
5
6
7
8
9
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的访问权限。


[意译],解释一下吧,就是用自己阅读原文的理解来表达基本的意思。原文 内容一般是一些官方文档或者很经典的博客。部分内容是原文的翻译,一部分是我自己的理解和补充。

就把这个当作第一个系列吧,orz

CATALOG
  1. 1. 1. 发送文本内容
  2. 2. 2. 发送二进制内容
  3. 3. 3. 一次性发送多条数据