前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(一百七十六)借助FileProvider发送彩信

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

作者头像
aqi00
发布2022-01-05 14:19:00
6330
发布2022-01-05 14:19:00
举报
文章被收录于专栏:老欧说安卓老欧说安卓

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

代码语言:javascript
复制
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}; // 文件路径

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

代码语言:javascript
复制
// 加载图片列表
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文件填入以下内容,表示定义几个外部文件目录:

代码语言:javascript
复制
<paths>
    <external-path path="Android/data/com.example.chapter07/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

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

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

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

代码语言:javascript
复制
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开发笔记的完整目录

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-10-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档