Android获取本地相册中图片视频

2023-11-07

权限:

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

1、android本地图片都是通过相册数据库获取对应数据

 private static final String[] IMAGES = {
            MediaStore.Images.Media.DATA,
            MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
            MediaStore.Images.Media.MIME_TYPE,
            MediaStore.Images.Media.DATE_ADDED,
            MediaStore.Images.Media.LATITUDE,
            MediaStore.Images.Media.LONGITUDE,
            MediaStore.Images.Media.SIZE,
            MediaStore.Images.Media._ID
    };

 @WorkerThread
    public void scanImageFile(Map<String, AlbumFolder> albumFolderMap, AlbumFolder allFileFolder) {
        ContentResolver contentResolver = mContext.getContentResolver();
        Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                IMAGES,
                null,
                null,
                null);

        if (cursor != null) {
            while (cursor.moveToNext()) {
                String path = cursor.getString(0);
                String folderName = cursor.getString(1);
                String mimeType = cursor.getString(2);
                long addDate = cursor.getLong(3);
                float latitude = cursor.getFloat(4);
                float longitude = cursor.getFloat(5);
                long size = cursor.getLong(6);
                String imageId = cursor.getString(7);
                //添加方法判断文件是否存在,如果不存在则不需要add
                if (path != null && new File(path).exists()) {
                    AlbumFile imageFile = new AlbumFile();
                    imageFile.setMediaType(AlbumFile.TYPE_IMAGE);
                    imageFile.setPath(path);
                    imageFile.setFolderName(folderName);
                    imageFile.setMimeType(mimeType);
                    imageFile.setAddDate(addDate);
                    imageFile.setLatitude(latitude);
                    imageFile.setLongitude(longitude);
                    imageFile.setSize(size);

//通过数据id,获取的图片对应uri   
imageFile.setUri(Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageId));

                    allFileFolder.addAlbumFile(imageFile);
                    AlbumFolder albumFolder = albumFolderMap.get(folderName);

                    if (albumFolder != null)
                        albumFolder.addAlbumFile(imageFile);
                    else {
                        albumFolder = new AlbumFolder();
                        albumFolder.setName(folderName);
                        albumFolder.addAlbumFile(imageFile);
                        albumFolderMap.put(folderName, albumFolder);
                    }
                }
            }
            cursor.close();
        }
    }

这里,我们需要注意,因为android10以后版本不能通过File来获取图片文件,所以我们需要通过Uri来讲图片文件转到沙箱文件中,来压缩等操作。

    /**
     * uri 转 File 兼容Android Q
     *
     * @param context
     * @param uri
     * @return
     */
    public static File fileByUri(Context context, Uri uri) {
        File file = null;
        if (androidQ()) {
            file = saveFileFromInputByAndroidBox(context, uri, fileSuffixName(filePathByUri(context, uri)));
        } else {
            file = new File(filePathByUri(context, uri));
        }
        return file;
    }

  /**
     * Android Q 保存uri文件到沙箱内
     *
     * @param context
     * @param uri
     * @param suffixName
     * @return
     */
    public static File saveFileFromInputByAndroidBox(Context context, Uri uri, String suffixName) {
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        File file = null;
        try {
            InputStream inputStream = context.getContentResolver().openInputStream(uri);
            file = createFilePathByBox(context, "file", randomName() + suffixName);
            bis = new BufferedInputStream(inputStream);
            fos = new FileOutputStream(file);
            if (fos != null) {
                bos = new BufferedOutputStream(fos);
                byte[] buf = new byte[BYTE];
                int bytes = bis.read(buf);
                while (bytes >= 0) {
                    bos.write(buf, 0, bytes);
                    bos.flush();
                    bytes = bis.read(buf);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeSilently(bis);
            closeSilently(bos);
            closeSilently(fos);
        }
        return file;
    }




    /**
     * 通过uri 获取文件真实路径 (AndroidQ以下版本)
     *
     * @param context
     * @param uri
     * @return
     */
    public static String filePathByUri(Context context, Uri uri) {
        String imagePath = null;
        if (context != null && uri != null) {
            String[] proj = {MediaStore.Images.Media.DATA};
            Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
            if (cursor.moveToFirst()) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                imagePath = cursor.getString(column_index);
            }
            cursor.close();
        }
        return imagePath;
    }

如果是AndroidQ一下,其实我们再获取图片封装对象里面,就已经得到Path,可以直接使用。

2、视频   其实,视频跟图片获取逻辑也是一样,主要查询字段不一样来区分,获取视频还是图片
 

 /**
     * 视频
     */
    private static final String[] VIDEOS = {
            MediaStore.Video.Media.DATA,
            MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
            MediaStore.Video.Media.MIME_TYPE,
            MediaStore.Video.Media.DATE_ADDED,
            MediaStore.Video.Media.LATITUDE,
            MediaStore.Video.Media.LONGITUDE,
            MediaStore.Video.Media.SIZE,
            MediaStore.Video.Media.DURATION,
            MediaStore.Video.Media._ID
    };

 /**
     * 获取视频数据(按照全部、文件夹区分)
     *
     * @param albumFolderMap 所有文件夹
     * @param allFileFolder  全部内容单独文件夹
     */
  @WorkerThread
    private void scanVideoFile(Map<String, AlbumFolder> albumFolderMap, AlbumFolder allFileFolder) {
        ContentResolver contentResolver = mContext.getContentResolver();
        Cursor cursor = contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                VIDEOS,
                null,
                null,
                null);

        if (cursor != null) {
            while (cursor.moveToNext()) {
                String path = cursor.getString(0);
                String folderName = cursor.getString(1);
                String mimeType = cursor.getString(2);
                long addDate = cursor.getLong(3);
                float latitude = cursor.getFloat(4);
                float longitude = cursor.getFloat(5);
                long size = cursor.getLong(6);
                long duration = cursor.getLong(7);
                long videoId = cursor.getLong(8);
                if (duration <= 0) {
                    continue;
                }


                AlbumFile videoFile = new AlbumFile();
                videoFile.setMediaType(AlbumFile.TYPE_VIDEO);
                videoFile.setPath(path);
                videoFile.setFolderName(folderName);
                videoFile.setMimeType(mimeType);
                videoFile.setAddDate(addDate);
                videoFile.setLatitude(latitude);
                videoFile.setLongitude(longitude);
                videoFile.setSize(size);
                videoFile.setDuration(duration);
                videoFile.setDurationStr(AlbumUtils.convertDuration(duration));

                videoFile.setUri(Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoId + ""));

               
                allFileFolder.addAlbumFile(videoFile);
                AlbumFolder albumFolder = albumFolderMap.get(folderName);

                if (albumFolder != null)
                    albumFolder.addAlbumFile(videoFile);
                else {
                    albumFolder = new AlbumFolder();
                    albumFolder.setName(folderName);
                    albumFolder.addAlbumFile(videoFile);

                    albumFolderMap.put(folderName, albumFolder);
                }
            }
            cursor.close();
        }
    }

其实视频,我们会涉及到一个问题,就是封面展示的问题。

第一种:直接通过Gilde做展示

 Glide.with(getContext()).load(uri).into(imageView);

第二种:获取视频文件第一帧,作为封面(需要保存图片封面到本地)

第三种:获取数据库中视频的封面。

3.拍照

Uri uri = FileUtils.getImageUriByMediaStore(activity);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);  //uri传递户自己生成
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
activity.startActivityForResult(intent, requestCode);

4.录像

Uri uri = FileUtils.getVideoUriByMediaStore(activity);
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // MediaStore.EXTRA_VIDEO_QUALITY 表示录制视频的质量,从 0-1,越大表示质量越好,同时视频也越大
//允许记录的最长时间(以 秒 为单位) 例如:限制为60S
//intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 60);
//允许的最大大小(以 B 为单位) 例如:限制大小为100M
//intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024L * 1024 * 100);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
activity.startActivityForResult(intent, requestCode);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android获取本地相册中图片视频 的相关文章

  • Android 中所有活动的单套接字 IO 连接

    我已经为 SocketIOClient 参考创建了 Singleton 类here https stackoverflow com questions 13709783 android socket io switch activities
  • 使用 gradle-retrolambda 和 Lightweight-Stream-API 过滤 Android 中的对象列表

    我正在尝试在我的 Android 应用程序中过滤 Java 中的对象列表 为此我遵循这个答案 https stackoverflow com a 13140130 3546389 Java 8建议 但由于Android SDK不支持Lamb
  • Android 上的多处理

    我一直在 Android 上执行一些测试 以验证并行化算法 如 FFT 的性能可以提高多少 我通过使用带有 JNI FFTW 的 pthread 和 Java 线程 来自 JTransforms 来实现这些算法 我没有像预期那样通过使用线程
  • 如何在flutter android插件包中处理android生命周期

    我需要知道 android 插件包中 flutter 应用程序视图的当前状态 现在 我观察颤振视图中的状态https docs flutter io flutter widgets WidgetsBindingObserver class
  • 从ndk中的不同线程调用java方法

    我正在尝试使用 android 的 NDK 从 C 中的独立线程调用 java 静态方法 到目前为止我已经 JNIEnv env AttachJava jclass cls2 env gt FindClass com actvt showd
  • Android 模拟器在 Windows 7 64 位上崩溃

    我是一名 Android 开发新手 到目前为止只在我的 Android 手机上运行了 Hello World 当我尝试在模拟器模式下运行我的应用程序时 我看到带有键盘和接听 挂断按钮的模拟器窗口 但在我的应用程序运行之前我收到一个窗口对话框
  • 将 React Native 应用程序嵌入到现有的 ios/android 应用程序中

    我需要知道是否可以在现有的 ios android 应用程序中 嵌入 一个 React Native 应用程序 而不共享 React Native 应用程序代码 我们目前有一个 React Native 应用程序 它使用一些插件依赖项 并被
  • Android 操作栏 SearchView 作为自动完成功能?

    我在操作栏中使用 SearchView 我想在搜索视图上使用自动完成功能来从数据库中获取结果 这可能吗 或者我是否需要使用自定义文本框 然后添加自动完成功能 所以我只需要对 v7 版本执行此操作 并沮丧地发现我不能简单地使用 ArrayAd
  • 从 Android 函数更新 Textview

    有人可以告诉我如何从函数更新 Android Textview 控件吗 我在互联网上进行了深入搜索 看到很多人都问同样的问题 我测试了线程但无法工作 有人有一个简单的工作示例吗 例如 调用一个函数 在循环中运行多次 并且该函数在 TextV
  • Gradle 构建过程失败

    我的项目正在成功构建 突然我在 Android studio 中收到以下错误 无法找到方法 org gradle api publish maven internal publication MavenPublicationInternal
  • Ionic4 电容器 android livereload?

    是否有可能在带有 livereload 的 Android 设备上运行带有电容器的 ionic 4 应用程序 我已经找了几个小时的答案了 但没有成功 请帮忙 如果使用最新版本 ionic cli 现在有一个命令ionic capacitor
  • Android 中的处理程序到处理程序与 Messenger 到 Messenger 通信

    问题 使用起来是否 更好 更快且开销更少 Handler http developer android com reference android os Handler html与使用 Handler 通信相比信使 http develop
  • Horizo​​ntalScrollView 将 GridView 缩小为小行

    当我将 Horizo ntalScrollView 放在 GridView 周围时 GridView 会被压缩到左侧的一个小列中 Gridview 的垂直滚动条甚至出现在左侧 Horizo ntalScrollView 的宽度设置为 fil
  • 视图随软键盘移动,遮挡其他 UI 对象

    我有一个容器视图 我希望它始终位于视图底部 位于 ScrollView 下方 ScrollView 有一些 UI 对象 其中一个是 EditText 对象 目前 当用户点击 EditText 对象内部时 android softkeyboa
  • android gradle插件-离线安装

    我必须在离线电脑上安装 android gradle 插件 通过谷歌搜索 我了解到我可以通过本地 Maven 存储库来做到这一点 但从不成功的尝试和所有关于这个问题的质量保证中我知道这并不简单 我从来没有和maven一起工作过 有经验的人可
  • Meteor:即使设置了 ANDROID_HOME 也未设置

    操作系统 Ubuntu 14 04 框架 流星1 1 0 2 应用名称 Songofy 这是输出meteor install sdk android meteor install sdk android Found Android bund
  • 通知管理器所需的权限

    我正在尝试使用以下命令将振铃器设置为静音且请勿打扰优先级 AudioManager myAudioMgr AudioManager context getSystemService Context AUDIO SERVICE Notific
  • 什么是版本代码主要?和versionCode有什么区别?

    我刚刚发现PackageInfo versionCode https developer android com reference android content pm PackageInfo html versionCode在 Andr
  • 手动添加带有依赖pom/iml文件的aar

    由于我无法使用私人 Maven 来共享我的库 因此我正在考虑共享 aar 并导入到另一个项目中 当 aar 和 jar 文件不包含任何依赖项时 就会出现问题 因此 一旦我在android studio中手动导入aar 使用Import JA
  • FragmentMap + ActionBar 选项卡

    我一直在尝试插入一个MapView进入一个ActionBar Tab 但我什至无法解决问题 即使谷歌搜索 这是主要活动 Override public void onCreate Bundle savedInstanceState supe

随机推荐

  • IDEA-idea中解决Java程序包不存在问题

    新导入的JavaWeb项目在编译时报出Error 18 33 java 程序包com google common collect不存在的错误 看看这是什么东西 原来是google相关包 这个包的下载地址 https www mvnjar c
  • JavaWeb~网页刷新/前端构造HTTP请求(form表单、ajax异步构造)/同步与异步/封装ajax/jQuery库引入

    文本目录 网页刷新 网页前端构造HTTP请求 form表单构造 ajax构造各种请求 ajax介绍 什么是同步 异步请求 同步异步区别理解 什么情况下使用ajax ajax运行机制 代码举例 封装ajax方法 网页刷新 F5和ctrl f5
  • 最新PMP/PMBOK Guide 6th Edition项目管理知识体系指南中文第六版

    http www hellokittycn com chapter 1262
  • 多技术融合推动,元宇宙应用破局向前

    报告编委 黄勇 爱分析合伙人 首席分析师 文鸿伟 爱分析高级分析师 外部专家 按姓氏拼音排序 唐虓 艾迪普科技 融合创新中心总经理 特别鸣谢 按拼音排序 报告摘要 元宇宙作为下一代互联网的典型代表 很可能将是人类数字化生存的终极形态 将带来
  • RTT下移植LVGL到W601_文件系统移植

    RTT下移植LVGL到W601 显示驱动移植 声明 个人学习笔记 不保证正确 参考资料 移植参考 DFS参考 图片 图片在线转换 环境 win10 keil5 硬件 正点原子w601开发板 步骤流程 1 在显示驱动移植完成的基础上添加tf卡
  • 初次使用vscode配置方法

    从vs换到vscode 花了一天时间终于把各种问题解决 吐血整理 如有疑问 可以在评论区交流 1 安装c c 扩展 安装v1 8 4版 稳定 2 安装code runner 右键即可运行代码 操作简单 3 安装mingw 安装在线版会出现
  • 计算机视觉论文-2021-06-22

    本专栏是计算机视觉方向论文收集积累 时间 2021年6月22日 来源 paper digest 欢迎关注原创公众号 计算机视觉联盟 回复 西瓜书手推笔记 可获取我的机器学习纯手推笔记 直达笔记地址 机器学习手推笔记 GitHub地址 1 T
  • Mysql-DDL(数据定义语言)

    show databases 查看所有数据库 create databse 数据库名 创建数据库 use database 数据库名 使用数据库 删除表格如果存在 drop table if exists mumber1 create TA
  • Angular快速上手--创建Hero类

    0 前言 真实的英雄当然不止一个名字 在 src app 文件夹中为 Hero 类创建一个文件 并添加 id 和 name 属性 1 操作 src app app component ts复制并修改内容 export class Hero
  • ensp设计校园网,期末作业,课程设计报告

    1 实现功能 基本实现如下网络核心功能 1 三层架构设计 本课题按照三层网络结构 接入层 汇聚层 核心层 进行设计和规划 接入层要求提供较多的网络入口 汇聚层实现对接入层网络的互联 核心层完成校园内部和外部数据的交换 并实现路由和安全功能
  • 怎么查看vue源码

    有很多同学和我一样使用一段时间 vue 框架后 对它的源码就有了兴趣 但是不知道在哪里找 vue js 源码 随意创建一个vue项目 或者已有项目 找到根路径平级的 node modules 文件夹 往下拉 拉多一下 在文件夹尾巴一截的地方
  • SpringBoot笔记

    目录 开发准备 导出 常用注解 导出excel到指定位置 导出excel到指定web 导入 将指定位置Excel导入并显示至web 使用ExcelWriter基于模板导出 开发准备 1 导入依赖
  • Bar函数--Matplotlib

    函数Bar 用于绘制柱状图 使用bar绘制柱状图的过程中涉及到中文字体的显示问题 使用动态参数配置方法 指定了中文黑体 import matplotlib as mpl mpl rcParams font sans serif SimHei
  • web端播放m3u8视频流注意事项

    项目上有一个播放实时视频 直播 的需求 后端童鞋直接传过来一个类似 https live m3u8的视频流地址 让我自行播放 拿到地址的我一脸懵逼 下面开始我的探索 baidu 之路 HLS HTTP Live Streaming 介绍 m
  • Meta发布「分割一切」AI 模型,CV或迎来GPT-3时刻

    demo地址 Segment Anything Meta AI Meta 表示 这是第一个致力于图像分割的基础模型 自此 CV 也走上了 做一个统一某个 某些 全部 任务的全能模型 的道路 在此之前 分割作为计算机视觉的核心任务 已经得到广
  • java属性值注解

    查询条件开始时间 DateTimeFormat pattern yyyy MM dd HH mm ss JsonFormat pattern yyyy MM dd HH mm ss timezone GMT 8 private Date t
  • C# VS2010 Winform 查找链表的近邻值

    实现在类似数组中查找最接近目标值的数值 定义链表 定义链表 private List
  • 架构师进阶之路

    选择的范围太广 可以读的书太多 往往容易无所适从 我想就我自己读过的技术书籍中挑选出来一些 按照学习的先后顺序 推荐给大家 特别是那些想不断提高自己技术水平的Java程序员们 一 Java编程入门类 对于没有Java编程经验的程序员要入门
  • 随机森林建模

    在看datacastle的建模大赛 用r写了随机森林的二分类 上次代码用py跑的 这里想用交叉验证 但是跑了一天一夜也木有出来 还是把代码先保留下来吧 希望看到的人指正 rm list ls setwd D competitions dat
  • Android获取本地相册中图片视频

    权限