通过系统相册固然可以获得照片的路径对象,却无法知晓更多的详细信息,例如图片名称、文件大小、文件路径等等都不知道,也就无法进行个性化的定制开发。为了把更多的文件信息开放出来,Android设计了专门的媒体共享库,允许开发者通过内容组件从中获取更详细的媒体信息。
就图片而言,相册媒体库的路径为MediaStore.Images.Media.EXTERNAL_CONTENT_URI,于是通过内容解析器即可从媒体库依次遍历得到图片列表详情。为便于代码管理,首先要声明如下的对象变量:

private List<ImageInfo> mImageList = new ArrayList<ImageInfo>(); // 图片列表
private Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; // 相册的Uri
private String[] mImageColumn = new String[]{ // 媒体库的字段名称数组MediaStore.Images.Media._ID, // 编号MediaStore.Images.Media.TITLE, // 标题MediaStore.Images.Media.SIZE, // 文件大小MediaStore.Images.Media.DATA}; // 文件路径

然后根据内容解析器查询媒体库的图片信息,简单起见只挑选文件大小最小的前六张图片,列表加载代码示例如下:

// 加载图片列表
private void loadImageList() {mImageList.clear(); // 清空图片列表// 通过内容解析器查询系统的相册,并返回结果集的游标。“_size asc”表示按照文件大小升序排列Cursor cursor = getContentResolver().query(mImageUri, mImageColumn, null, null, "_size asc");if (cursor != null) {// 下面遍历结果集,并逐个添加到图片列表。简单起见只挑选前六张图片for (int i=0; i<6 && cursor.moveToNext(); i++) {ImageInfo image = new ImageInfo(); // 创建一个图片信息对象image.setId(cursor.getLong(0)); // 设置图片编号image.setName(cursor.getString(1)); // 设置图片名称image.setSize(cursor.getLong(2)); // 设置图片的文件大小image.setPath(cursor.getString(3)); // 设置图片的文件路径mImageList.add(image); // 添加至图片列表}cursor.close(); // 关闭数据库游标}
}

注意到以上代码获得了字符串格式的文件路径,而彩信发送应用却要求Uri类型的路径对象,原本可以通过代码“Uri.parse(path)”将字符串转换为Uri对象,但是从Android7.0开始,系统不允许其他应用直接访问老格式的路径,必须使用文件提供器FileProvider才能获取合法的Uri路径,相当于A应用申明共享某个文件,然后B应用方可访问该共享文件。为此需要重头配置FileProvider,详细的配置步骤说明如下。
首先在res目录新建xml文件夹,并在该文件夹中创建file_paths.xml,再往xml文件填入以下内容,表示定义几个外部文件目录:

<paths><external-path path="Android/data/com.example.chapter07/" name="files_root" /><external-path path="." name="external_storage_root" />
</paths>

接着打开AndroidManifest.xml,在application节点末尾添加下面的provider标签,用于声明当前应用的提供器组件,添加的标签配置示例如下:

<!-- 兼容Android7.0,把访问文件的Uri方式改为FileProvider -->
<providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.example.chapter07.fileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" />
</provider>

上面的provider有两处地方是可变的,一处是authorities属性,它规定了授权字符串,这是每个提供器的唯一标识;另一处是元数据的resource属性,它指明了文件提供器的路径资源,也就是刚才定义的file_paths.xml。
回到页面的活动源码,在发送彩信之前添加下述代码,目的是根据字符串路径构建Uri对象,注意针对Android7.0以上的兼容处理。

Uri uri = Uri.parse(path); // 根据指定路径创建一个Uri对象
// 兼容Android7.0,把访问文件的Uri方式改为FileProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 通过FileProvider获得文件的Uri访问方式uri = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID + ".fileProvider", new File(path));
}

由以上代码可见,Android7.0开始调用FileProvider的getUriForFile方法获得Uri对象,该方法的第二个参数为文件提供器的授权字符串(BuildConfig.APPLICATION_ID值为当前应用的包名),第三个参数为File类型的文件对象。
之后运行App,测试页面会自动加载从媒体库中找到的六张图片,填好各项信息的界面效果如下图所示。

最后点击某张图片,表示选中该图片作为彩信附件,界面下方弹出如下图所示的应用选择窗口。

选中信息图标再点击仅此一次按钮,即可跳到如下图所示的系统彩信发送页面了。

点此查看Android开发笔记的完整目录

Android开发笔记(一百七十六)借助FileProvider发送彩信相关推荐

  1. Android开发笔记(八十六)几个特殊的类

    接口interface interface是一些功能的集合,但它只定义了对象必须实现的成员,而不包含成员的实现代码,成员的具体代码由实现接口的类提供.Android对接口的使用场景主要有三类:事件监听 ...

  2. Android开发笔记(七十九)资源与权限校验

    硬件资源 因为移动设备的硬件配置各不相同,为了防止使用了不存在的设备资源,所以要对设备的硬件情况进行检查.一般情况下,前置摄像头.部分传感器在低端手机上是没有的,像SD卡也可能因为用户没插卡使得找不到 ...

  3. Android开发笔记(七十五)内存泄漏的处理

    内存泄漏的原因 一直以来以为只有C/C++才存在内存泄漏的问题,没想到拥有内存回收机制的Java也可能出现内存泄漏.C/C++存在指针的概念,程序中需要使用指针变量时,就从内存中开辟一块区域,并把该区 ...

  4. Android开发笔记(七十四)布局文件优化

    include/merge 布局优化中常常用到include/merge标签,include的含义类似C代码中的include,意思是直接把指定布局片段包含进当前的布局文件.include适用于多个布 ...

  5. Android开发笔记(七十二)数据加密算法

    编码算法 URL编码 URL编码其实并非加解密算法,只是对特殊字符进行字符转义,从而方便在URL中传输参数.URL编码有两种方式,一种是狭义的URL编码,另一种是广义的URL编码. 狭义的URL编码指 ...

  6. Android开发笔记(五十六)摄像头拍照

    相机Camera Camera是直接操作摄像头硬件的工具类.常用的方法如下: getNumberOfCameras : 获取本机的摄像头数目 open : 打开摄像头,默认打开后置摄像头.如果有多个摄 ...

  7. Android开发笔记(七十八)异常容错处理

    Exception Java的异常分两类,运行时异常RuntimeException和非运行时异常. 运行时异常包括空指针异常NullPointerException.数组越界异常IndexOutOf ...

  8. Android开发笔记(七十)反编译初步

    查看平台源码 查看内核源码 Android的内核源码很大,有几个G,仔细找找网上有许多下载的地方.作为普通开发者,一般不需要阅读内核源码,但一点都不了解好像也不行,因为实际开发中有时候就得会那么一点点 ...

  9. Android开发笔记(四十六)手机相关事件

    手机定位 有一类事件必须依赖于手机信号方能触发,如果把设备中的sim卡拔出,或者该设备本身不支持sim卡(如ipad),那么这类事件将永远不会被触发.在Android中,这类事件包括定位事件和手机信号 ...

  10. Android开发笔记(三十六)展示类控件

    View/ViewGroup View是单个视图,所有的控件类都是从它派生出来:而ViewGroup是个视图组织,所有的布局视图类都是从它派生出来.由于View和ViewGroup是基类,因此很少会直 ...

最新文章

  1. 树根c语言,03-树1 树的同构 (C语言链表实现)
  2. Java-工具类之发送邮件
  3. 简单的XML和JSON数据的处理
  4. C提高_day03_作业第三题
  5. webpack 修改title_Webpack漫谈
  6. maven 简单实用教程
  7. eclipse配置文件
  8. 全网首发:VS编译的文件不在指定位置,怎么办
  9. 傲腾服务器系统,服务器装傲腾内存
  10. textView 属性总结
  11. LAMMPS分子动力学模拟技术与应用 第一性原理计算方法及应用
  12. 自定义通用信号处理核心板CMB-2C6657-1K7
  13. 计算机辅助设计表现的发展给设计带来的影响,计算机辅助设计对艺术设计的影响.doc...
  14. java 实验4 字体对话框_文字字体设计窗体 实验!求大神
  15. Vue3动态绑定组件警告处理
  16. Map阶段环形缓冲区详细分析
  17. Latex公式换行但不加序号
  18. Windows部署Apache服务器步骤
  19. github创建tag
  20. 案例分享:Qt政务标签设计器,标签排版软件定制与打印

热门文章

  1. android:id = @+id 用法,@+id/android:list和@android:id/list的写法
  2. 二分归并排序算法_02 算法推送归并排序
  3. linux 中断 c语言程序,linux驱动之中断处理过程C程序部分
  4. Echarts.js+jquery.js+china.js实现中国疫情地图
  5. css html 语法,CSS基础语法
  6. java的多态代码例子_java 多态实例代码
  7. java addall 不能传null_null 之AddAll、Add和Boolean
  8. mysql mac版_MAMP Pro—PHP/MySQL开发环境
  9. 使用python开发网页游戏_四大游戏编程网站,边玩游戏,边学Python,拒绝枯燥快乐编程...
  10. jq 直接调用php文件_PHP性能分析工具,你在用哪一个?