原文地址:http://android.xsoftlab.net/training/beam-files/receive-files.html

Android Beam文件传输系统会将文件拷贝到接收设备的指定目录中。它还会使用Android媒体扫描器扫描被拷贝的文件,并会将媒体文件的入口信息添加到MediaStore提供者中去。

响应展示数据的请求

当Android Beam文件传输系统结束了文件拷贝,它会发送通知,这个通知会包含一个Intent对象,这个Intent对象的行为为ACTION_VIEW,以及被传送的第一个文件的MIME类型,以及指向第一个文件的URI地址。当用户点击了通知,这个Intent会被广播到系统中。为了使APP可以响应这个意图,需要在清单文件中的响应Activity的< activity>元素下添加元素,并在其中添加如下子元素:

<action android:name="android.intent.action.VIEW" />
  • 匹配由通知发送来的ACTION_VIEW意图。
<category android:name="android.intent.category.CATEGORY_DEFAULT" />
  • 匹配没有明确类别的意图。
<data android:mimeType="mime-type" />
  • 匹配一种MIME类型。这里的mime-type类型应为APP可以处理的类型。

举个例子,下面这段代码展示了如何在被触发的Activity com.example.android.nfctransfer.ViewActivity的清单文件中添加意图过滤器:

    <activity
        android:name="com.example.android.nfctransfer.ViewActivity"android:label="Android Beam Viewer" >...<intent-filter><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/>...</intent-filter></activity>

**Note:**Android Beam文件传输系统并不是ACTION_VIEW意图的唯一来源,接收设备上的其它APP也可以发送含有这个行为的意图。Get the directory from a content URI这节会讨论如何处理这种情况。

请求文件权限

为了可以读取Android Beam文件传输系统拷贝到设备的文件,需要请求READ_EXTERNAL_STORAGE权限:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

如果你想要将被拷贝的文件拷贝到自己的存储器上,这里应该使用权限WRITE_EXTERNAL_STORAGE。WRITE_EXTERNAL_STORAGE权限包含了READ_EXTERNAL_STORAGE权限。

Note:在Android 4.2.2上,READ_EXTERNAL_STORAGE权限会在用户需要的时候强制执行。未来的版本可能在各种情况下都需要该权限,所以为了确保向后兼容,请在它要求以前就给它添加上。

因为你的APP对其内部存储器有操作的权利,所以在拷贝文件到内部存储器上时不需要请求写入权限。

获取被拷贝文件的目录

Android Beam文件传输系统会通过一个单一的传输通道将所有的文件拷贝到接收设备上一个目录中。Android Beam文件传输系统的通知会将内容Intent中的URI指向到第一个已被传送的文件上。然而,APP可能还需要对传输系统上的其它ACTION_VIEW意图来源进行接收。为了判断应该如何处理发送过来的Intent,你需要检查它的计划(scheme)与权力(authority)。

为了可以从URI上获取计划,需要调用Uri.getScheme()方法。下面这段代码展示了如何检查计划以及如何处理URI的访问:

public class MainActivity extends Activity {...// A File object containing the path to the transferred filesprivate File mParentPath;// Incoming Intentprivate Intent mIntent;.../** Called from onNewIntent() for a SINGLE_TOP Activity* or onCreate() for a new Activity. For onNewIntent(),* remember to call setIntent() to store the most* current Intent**/private void handleViewIntent() {...// Get the Intent actionmIntent = getIntent();String action = mIntent.getAction();/** For ACTION_VIEW, the Activity is being asked to display data.* Get the URI.*/if (TextUtils.equals(action, Intent.ACTION_VIEW)) {// Get the URI from the IntentUri beamUri = mIntent.getData();/** Test for the type of URI, by getting its scheme value*/if (TextUtils.equals(beamUri.getScheme(), "file")) {mParentPath = handleFileUri(beamUri);} else if (TextUtils.equals(beamUri.getScheme(), "content")) {mParentPath = handleContentUri(beamUri);}}...}...
}

从文件URI获取目录

如果接收到的Intent包含一个文件URI,那么URI会包含文件的绝对文件名,包括全目录路径以及文件的名字。对Android Beam文件传输系统来说,如果有的话,这个目录路径指向了其它被传送文件的位置。为了获取目录路径,获取URI的路径部分,路径部分包含了除了前缀file:之外的所有URI。从路径部分创建一个File对象,然后该文件对象的上级目录:

    ...public String handleFileUri(Uri beamUri) {// Get the path part of the URIString fileName = beamUri.getPath();// Create a File object for this filenameFile copiedFile = new File(fileName);// Get a string containing the file's parent directoryreturn copiedFile.getParent();}...

从内容URI获取目录

如果接收到的Intent包含一个内容URI,那这个URI可能会指向在MediaStore内容提供者中存储的文件的路径和名称。你可以通过测试URI的权限值来判断是否是MediaStore的内容URI。MediaStore的内容URI可能来自Android Beam文件传输系统或者其它APP,但是无论什么情况你都可以从内容URI中接收一个目录以及文件的名称。

你也可以接收包含了不同于MediaStore的内容URI的ACTION_VIEW意图。在这种情况下,这内容URI不包含 ACTION_VIEW的权限值,以及内容URI通常不会执行一个目录。

Note: 对于Android Beam文件传输系统来说,你可以接收含有内容URI的ACTION_VIEW意图,如果第一个接到的文件含有”audio/*”, “image/*”, 或者”video/*”之类的MIME类型。这意味着它是和媒体有关的。Android Beam文件传输系统会索引媒体文件,它会通过运行媒体扫描器扫描存储有被传送文件的目录来传送文件。媒体扫描器会将扫描结果写入到MediaStore内容提供者中,然后它会传第一个文件的内容URI给Android Beam文件传输系统。这个内容URI是在通知意图中的接收到的那个。给了获取第一个文件的目录,需要使用内容URI从MediaStore中接收它。

判断内容提供者

为了判断是否可以从内容URI中接收文件的目录,通过调用Uri.getAuthority()来获取URI的权限来判断与内容提供者相关联的URI。它的值可能有两种情况:

MediaStore.AUTHORITY

这个URI是可以被MediaStore追踪到的单个文件或者多个文件。MediaStore中可以接收全路径名称,以及可以从文件名中获取它的目录。

其它任意的权限值

从其它内容提供者而来的内容URI。展示了与内容URI相关的数据,但是不能够获取文件的目录。

为了可以从MediaStore内容URI中获取文件目录,需要进行查询,查询需要指定Uri参数为接收到的内容URI,projection参数为列MediaColumns.DATA,它返回的Cursor对象包含了URI所代表的文件的全路径名称。这个路径还包含Android Beam文件传输系统刚刚拷贝到设备上的其它所有文件。

下面这段代码展示了如何测试内容URI的权限以及从被传送的文件中接收路径以及文件名:

    ...public String handleContentUri(Uri beamUri) {// Position of the filename in the query Cursorint filenameIndex;// File object for the filenameFile copiedFile;// The filename stored in MediaStoreString fileName;// Test the authority of the URIif (!TextUtils.equals(beamUri.getAuthority(), MediaStore.AUTHORITY)) {/** Handle content URIs for other content providers*/// For a MediaStore content URI} else {// Get the column that contains the file nameString[] projection = { MediaStore.MediaColumns.DATA };Cursor pathCursor =getContentResolver().query(beamUri, projection,null, null, null);// Check for a valid cursorif (pathCursor != null &&pathCursor.moveToFirst()) {// Get the column index in the CursorfilenameIndex = pathCursor.getColumnIndex(MediaStore.MediaColumns.DATA);// Get the full file name including pathfileName = pathCursor.getString(filenameIndex);// Create a File object for the filenamecopiedFile = new File(fileName);// Return the parent directory of the filereturn new File(copiedFile.getParent());} else {// The query didn't work; return nullreturn null;}}}...

如果要学习更多从内容提供者中接收数据的其它知识,请参见章节:Retrieving Data from the Provider.

Android官方开发文档Training系列课程中文版:通过NFC共享文件之从其它设备接收文件相关推荐

  1. Android官方开发文档Training系列课程中文版:目录

    原文地址 : http://android.xsoftlab.net/training/index.html 引言 在翻译了一篇安卓的官方文档之后,我觉得应该做一件事情,就是把安卓的整篇训练课程全部翻 ...

  2. Android官方开发文档Training系列课程中文版:创建自定义View之View的创建

    原文地址:http://android.xsoftlab.net/training/custom-views/index.html 引言 Android框架含有大量的View类,这些类用来显示各式各样 ...

  3. Android官方开发文档Training系列课程中文版:OpenGL绘图之图形绘制

    原文地址:http://android.xsoftlab.net/training/graphics/opengl/draw.html 如果你还不清楚如何定义图形及坐标系统,请移步:Android官方 ...

  4. Android官方开发文档Training系列课程中文版:使用Fragment构建动态UI之Fragment创建

    原文地址:http://android.xsoftlab.net/training/basics/fragments/index.html 导言 为了在Android中创建动态的多面板用户界面,你需要 ...

  5. Android官方开发文档Training系列课程中文版:通过NFC共享文件之发送文件到另一台设备

    原文地址:http://android.xsoftlab.net/training/beam-files/index.html 导言 Android允许你通过Android Beam文件传输特性在两台 ...

  6. Android官方开发文档Training系列课程中文版:打印内容之图像打印

    原文地址:http://android.xsoftlab.net/training/printing/index.html 引言 Android用户会很频繁的浏览设备上的内容,但是有部分情况例外,当屏 ...

  7. Android官方开发文档Training系列课程中文版:网络操作之网络管理

    原文地址:http://android.xsoftlab.net/training/basics/network-ops/managing.html 这节课将会学习如何对网络资源的使用情况拥有更细粒度 ...

  8. Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接

    原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/wifi-direct.html#permissions Wi ...

  9. Android官方开发文档Training系列课程中文版:连接无线设备之网络服务搜索功能

    原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/index.html 引言 Android设备除了可以与服务器 ...

最新文章

  1. Centos 升级MySQL版本或者Yum安装Mysql5.6
  2. 编译FileMon出错
  3. linux下设置opencv环境变量
  4. WSL 1 运行 Ubuntu 20.04 将会出现问题
  5. python 堆栈溢出_内存 - 如何发生“堆栈溢出”,如何防止它?
  6. mysql之select+五种子句的理解
  7. 网易云音乐工程师,亲自揭晓消息队列改造之路! | 技术头条
  8. 10.66道经典的Java基础面试题集锦为何晴空
  9. QA: c# IHttpFactory配置代理或者HttpClient配置代理
  10. NOIP 2005 等价表达式 (TYVJ P1060)
  11. linux md5 大文件慢,【我的Linux,我做主!】浅谈MD5校验文件完整一致性
  12. 厦门大学信息计算机学院,厦门大学信息科学与技术学院计算机科学系导师介绍:刘向荣...
  13. vscode 添加版权信息
  14. 利润表三点式审阅:以御银股份为例
  15. Fluent Mybatis 牛逼
  16. 私域运营第五讲:实体餐饮店如何通过搭建私域流量实现营收增长
  17. c++中关于设置左对齐和右对齐的问题解决方法
  18. 与计算机有关的技能,计算机类
  19. stanford-corenlp 中各词性含义标注
  20. 2019年1-6月网络安全态势分析及建议

热门文章

  1. 我也确实很向往深圳这种拼搏的精神
  2. 我是在这里学到的Linux知识的
  3. LinuxC高级编程——线程
  4. 三、Java 面向对象高级——数据结构、List、Set、Collection
  5. python网络爬虫系列(十一)——JS的解析
  6. LeetCode 2001. 可互换矩形的组数
  7. LeetCode 1974. 使用特殊打字机键入单词的最少时间
  8. LeetCode 483. 最小好进制(二分查找)
  9. LeetCode 926. 将字符串翻转到单调递增(动态规划)
  10. LeetCode 1031. 两个非重叠子数组的最大和(一次遍历,要复习)*