通过uri获取文件路径手机适配

Android通过uri 获取文件路径 话不多说,通过uri获取文件路径遇到了很多坑,但也最终解决了,直接上代码。 import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environme 阅读详情

青铜版本

  return contentResolver.query(this, arrayOf(MediaStore.MediaColumns.DATA), null, null).let {
        if (it?.moveToFirst() == true) {
            val columnIndex = it.getColumnIndex(MediaStore.MediaColumns.DATA)
            val path = it.getString(columnIndex)
            it.close()
            return path
        }
        ""
    }

在firebase上发现很多异常奔溃日志,部分手机获取到的 path 是空的,也就是说没有_data字段

其实有的手机通过选择图片或者文件后返回的uri并不一定是媒体uri,也可能是document uri,造成这个时候直接通过 uri查询,找不到_data字段,需要将 document uri中分离出类型和id,在拼凑成新的uri,在通过contentprovider查询,才可以查出 _data字段中真正的路径

//如果是Document类型的URI,需要进行转换
private fun getPathFromDocumentUri(uri: Uri): String? {
    val isDocumentUri = DocumentsContract.isDocumentUri(BaseApplication.instance, uri)
    if (isDocumentUri) {
        val docId = DocumentsContract.getDocumentId(uri)
        val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        val type = split[0] // "image"
        val id = split[1] // "1044024"
        var quaryUri: Uri? = null
        if ("image".equals(type)) {
            quaryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if ("video".equals(type)) {
            quaryUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        } else if ("audio".equals(type)) {
            quaryUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        }

        LogUtils.d("linlian quaryUri=$quaryUri")
        quaryUri?.let {
            val projection = arrayOf(MediaStore.Images.Media.DATA,MediaStore.Images.Media._ID)
            BaseApplication.instance.contentResolver.query(
                quaryUri,
                projection,
                MediaStore.Images.Media._ID + "=?",
                arrayOf<String>(id),
                null
            )?.use {cursor ->

                val columnNames = cursor.columnNames
                LogUtils.d("linlian ", "URI: $uri")
                LogUtils.d("linlian ", "Total columns: ${columnNames.size}")

                // 遍历每一行
                while (cursor.moveToNext()) {
//                    val rowData = StringBuilder()
                    // 遍历每一列
//                    for (columnName in columnNames) {
//                        val columnIndex = cursor.getColumnIndex(columnName)
//                        if (columnIndex == -1) {
//                            rowData.append("$columnName: [COLUMN_NOT_FOUND]\n")
//                            continue
//                        }
//
//                        val value = when (cursor.getType(columnIndex)) {
//                            Cursor.FIELD_TYPE_NULL -> "NULL"
//                            Cursor.FIELD_TYPE_INTEGER -> cursor.getLong(columnIndex)
//                            Cursor.FIELD_TYPE_FLOAT -> cursor.getDouble(columnIndex)
//                            Cursor.FIELD_TYPE_STRING -> cursor.getString(columnIndex)
//                            Cursor.FIELD_TYPE_BLOB -> "BLOB (${cursor.getBlob(columnIndex)?.size ?: 0} bytes)"
//                            else -> "UNKNOWN_TYPE"
//                        }
//                        rowData.append("$columnName: $value\n")
//                    }
//                    LogUtils.d("linlian", "Row ${cursor.position}:\n$rowData")

                    val index= cursor.getColumnIndex(MediaStore.Images.Media.DATA)
                    if(index!=-1){
                        val path = cursor.getString(index)
                        LogUtils.d("linlian", "!!!!!!!!!!$path")
                        return path
                    }
                    LogUtils.d("linlian", "!!!!!!!!!!$index")
                }
                return null
            }

        }

    }
    return null
}

但是根据文档其实Android 10 之后是有新的字段,但是手机厂商众多,实现方式不一,还是找不到path怎么办,官方是说可以从 RELATIVE_PATH获取路径

contentResolver.query(uri, projection, null, null, null).use { cursor ->
                if (cursor != null && cursor.moveToFirst()) {
                    // 获取文件名
                    val nameIndex: Int = cursor.getColumnIndex(
                        if (isImage) MediaStore.Images.Media.DISPLAY_NAME else MediaStore.Video.Media.DISPLAY_NAME
                    )
                    val displayName: String? =
                        if ((nameIndex != -1)) cursor.getString(nameIndex) else null

                    // 获取相对路径(可能为 null)
                    val pathIndex: Int = cursor.getColumnIndex(
                        if (isImage) MediaStore.Images.Media.RELATIVE_PATH else MediaStore.Video.Media.RELATIVE_PATH
                    )
                    val relativePath: String? =
                        if ((pathIndex != -1)) cursor.getString(pathIndex) else null
                    LogUtils.d("linlian getPathFromRelativeColumn displayName=$displayName,relativePath=$relativePath")
                    // 生成最终路径
                    return buildPathForAndroidQ(displayName, relativePath)
                }
            }

如果以上都找不到path 怎么办呢

那最后的方式是,通过uri拷贝一份文件到应用目录,不过用完记得删除

fun copyFileFromUri(context: Context, uri: Uri, destFileName: String): File? {
    return try {
        // 打开输入流
        val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
        if (inputStream == null) {
            return null
        }

        // 目标文件:保存在 app 的 filesDir 目录
        val destFile = File(context.filesDir, destFileName)
        val outputStream: OutputStream = FileOutputStream(destFile)

        // 拷贝数据
        val buffer = ByteArray(4096)
        var bytesRead: Int
        while (inputStream.read(buffer).also { bytesRead = it } != -1) {
            outputStream.write(buffer, 0, bytesRead)
        }

        // 关闭流
        inputStream.close()
        outputStream.close()

        destFile
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}





Android10/11/12/13 Uri与真实路径转换--全适配 /** * 根据Uri获取文件绝对路径,解决Android4.4以上版本Uri转换 * * @param context * @param imageUri */ public static String getFileAbsolutePath(Context context, Uri imageUri) { if (context == null || imageUri == null) { r... 阅读详情

相关推荐

Android文件路径转换:从content URI到真实路径的兼容性实践

在Android开发中,文件访问机制经历了从直接路径到内容URI的演进,这是系统安全沙盒和用户隐私保护的重要体现。其核心原理是通过ContentProvider代理文件访问,将传统的file://路径转换为content:// URI,实现了权限驱动到用户意图驱动的转变。这一技术价值在于平衡了应用功能与系统安全,但给开发者带来了路径转换的兼容性挑战。在实际应用场景中,开发者需要处理来自不同文件管理器、系统版本和厂商定制的URI格式差异,特别是在处理MediaStore和DocumentsProvider两类

weixin_29194693的博客 4204

【Android 11/12】 通过Uri获取绝对路径的方法

原理:通过对不同的Uri进行辨别,提取ID,进入MediaStore.Files表中进行查询_data字段,旧版通过直接查询uri的方法获取_data已经无效.

qq_18571109的博客 5894

安卓获取手机视频和图片

在AndroidManifest.xml中添加代码,获得读取权限但是后来我发现android采用了Runtime permission request, 即在运行时请求权限,而不是在编译的时候,即使在manifest.xml里面添加了权限也要在运行时请求这时可以在运行之后做一下权限判断,如果没有权限则弹出对话框,向用户申请权限,这段代码我写在了刚运行app的第一个activity的oncreate里面,且只需要做一次判断,之后再进入app不需要再开启权限 定义方法chooseVideo,为某个按钮设置监听器

weixin_46563170的博客 3128

Android通过URI获取文件路径

Android通过URI获取文件路径

rjc_lihui的专栏 8728

Android开发中Uri与真实文件路径的转换

的方法,接受一个Context对象和一个真实文件路径作为参数,并返回对应的Uri。的方法,接受一个Context对象和一个Uri作为参数,并返回文件的真实路径。本文将探讨如何在Android开发中进行Uri与真实文件路径之间的转换,并提供相应的源代码示例。相应地,将真实文件路径转换为Uri,则可以方便地进行文件的共享和传递。以上是对于Android开发中Uri与真实文件路径转换的讨论,并提供了相应的源代码示例。除了将Uri转换为真实文件路径,我们还需要将真实文件路径转换为Uri。上述代码定义了一个名为。

TechBurst的博客 1619

STM32F4驱动ES8388音频芯片的I²S时钟与DMA流设计

I²S(Inter-IC Sound)是一种广泛应用于嵌入式音频系统的同步串行总线协议,其核心在于精确的时钟同步与稳定的数据流传输。理解I²S时钟树结构(含MCLK、SCLK、WS生成逻辑)和分频机制,是保障CD级音质(如44.1kHz/16bit)的基础;而DMA双缓冲技术则解决了实时音频播放中数据供给连续性的关键工程问题。在STM32F4等Cortex-M4平台中,需协同配置PLLI2S锁相环、I²S预分频寄存器(I2SxPR)及DMA循环模式,同时兼顾ES8388等Codec芯片的I²C初始化时序与寄

weixin_35390379的博客 245

android 小米手机不能正确获取图片uri的问题

今天做项目的时候,公司测试反馈小米手机不能正确选择图片,经过网上查找,解决办法如下: public Uri geturi(android.content.Intent intent) { Uri uri = intent.getData(); String type = intent.getType(); if (uri.getScheme().equals(

悲伤的时光机的博客 4710

Python实现支付宝转账接口

由于工作需要使用python开发一个自动转账接口,记录一下开发过程。 首先需要在蚂蚁金服上申请开通开发者账户,有了开发者账户就可以使用沙箱进行开发了。 在开发之前我们需要在沙箱应用中填写密钥,密钥的获取可以使用阿里提供的工具包自动生成。 前期准备工作完成了,接下来是编写代码部分。主要用到了python-alipay-sdk库,使用pip安装即可,如果安装的过程中遇到问题推荐使用Anaconda...

FanMLei的博客 8516

Android uri转真实路径。

在华为手机上选择图片的时候。拿到一个这样的路径:(华为手机进打开图库-》下载内容-》browser-》图片收藏-》选择图片) content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/browser/图片收藏/200832810200350_2.jpg emmm....

androidzmm的博客 23万+

《阵列信号处理及MATLAB实现》阵列响应矩阵(均匀线阵、均匀圆阵、L型阵列、平面阵列和任意阵列)

《阵列信号处理及MATLAB实现》内容总结,如需阅读更详细内容请购买正版书籍。

APPLECHARLOTTE的博客 1万+

史上最全的Logisim存储系统实验教程(基于华中科技大学计算机组成原理实验)内赋源码下载

本博客是最全的最好的解释的华中科技大学计算机组成实验存储系统实验,本博客给出了电路实现,也给出了使用电路的原因有利于新手学习十分详细。并且内赋源码下载。

qq_62325622的博客 2万+

Android通过URI获取文件路径(1)

首先是一个知识清单:(对于现在的Android及移动互联网来说,我们需要掌握的技术)泛型原理丶反射原理丶Java虚拟机原理丶线程池原理丶注解原理丶注解原理丶序列化Activity知识体系(Activity的生命周期丶Activity的任务栈丶Activity的启动模式丶View源码丶Fragment内核相关丶service原理等)代码框架结构优化(数据结构丶排序算法丶设计模式)APP性能优化(用户体验优化丶适配丶代码调优)热修复丶热升级丶Hook技术丶IOC架构设计。

2401_84121603的博客 3387

lammps模拟技巧:高熵合金势函数设置三种方法

大家好,我是小马老师。 本文继续介绍lammps模拟中的势函数设置方法。 在前面的文章中,介绍过高熵合金的建模:高熵合金建模 高熵合金包含的原子数较多,势函数的设置相对复杂,在平时一对一的咨询中,这种问题也相对较多。 下面介绍三种高熵合金势函数设置方法。 1.下载专用势函数 下面的网站包含了大多数原子的势函数: https://www.ctcms.nist.gov/potentials/ 如需下载包含Fe原子的势函数,直接点Fe: 出现势函数列表: 比如Al-Co-Cr-Fe-Ni就是高熵合金AlCoC

lammps_jiayou的博客 8962

Android通过URI获取文件路径(1),2024最新腾讯Android高级面试题总结

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。下面是部分资料截图,诚意满满:特别适合有开发经验的Android程序员们学习。不论遇到什么困难,都不应该成为我们放弃的理由!如果你看到了这里,觉得文章写得不错就给个赞呗?《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》

2401_84152825的博客 6669

OpenClaw + Antigravity + 飞书完整部署教程

在 Linux 服务器上部署 OpenClaw,使用 Antigravity 本地代理 AI 模型,并接入飞书实现 24 小时在线 AI 助手。

Maynor的博客 1788

代谢组数据分析(一):生成代谢组数据SummarizedExperiment对象

本文介绍了基于Zeybel 2022年发布的多组学数据集的分析脚本,该数据集包含微生物组、宿主人体学指标、临床学指标、血浆代谢组和免疫因子等多维度数据,涵盖56位患者的横截面数据和22位患者的纵向时间序列数据。脚本旨在生成适用于下游分析的数据对象,主要包括phyloseq和SummarizedExperiment两类。phyloseq对象用于整合微生物群落数据,支持多数据整合、可视化、丰富分析功能和便捷的数据处理;SummarizedExperiment对象则广泛应用于基因组学和转录组学研究,便于数据整合、

专注生信领域 2997

android根据拍摄url获取格式,Android如何通过URI获取文件路径示例代码

前言最近在工作的过程中,遇到不同 Android 版本下 URI 采用不同方式来获取文件路径的问题。因为需求的原因,要求拍照上传或者从相册中选择图片上传,而且图片是需要经过压缩的,大小不能超过2M。很快,拍照的这部分就搞定了。那么相册中选择图片的也是一样的道理,应该也是轻松解决了。至于选择图片的代码,如下所示:intent = new Intent(Intent.ACTION_GET_CONTEN...

weixin_42316319的博客 749

AI漫剧全套万能提示词合集

今天给大家整理一套已经跑通爆款漫剧的万能提示词库!覆盖:豆包剧本人设词 + 分镜生成词 + 即梦绘图词 + 动态优化词 + 防翻车固定词直接复制粘贴,新手也能做出稳定、高清、统一、有质感的AI漫剧!你是资深短视频漫剧编剧,擅长制作60秒竖屏爆款AI漫剧,请为我创作一集完整漫剧内容。要求:开头3秒高能抓眼,中段有冲突转折,结尾留强悬念钩子,节奏紧凑、适合短视频流量。首先生成固定统一人物人设:包含脸型、五官、发色、发型、穿搭、身材、气质、画风、光影细节,要求足够精细,保证全程角色不变脸。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 1961

android+7.0获取uri,适配android7.0获取文件的Uri的方法

前言#Android 7.0已经发布很久了,虽然市场份额还不是很高,但是流行起来都是早晚的事,所以适配Android 7.0刻不容缓。Android 7.0 对系统进行了很多的优化:例如文件访问权限,省电,网络,后台等等,其中最突出的就是应用外的Uri访问。什么时候会用到Uri的应用外访问呢?举一个简单的例子,下载apk更新,这个时候会调用系统功能来安装这个apk,这就是应用外访问文件,需要传入文...

weixin_42518981的博客 544

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

适配android7.0:获取文件的Uri

前言Android 7.0已经发布很久了,虽然市场份额还不是很高,但是流行起来都是早晚的事,所以适配Android 7.0刻不容缓。Android 7.0 对系统进行了很多的优化:例如文件访问权限,省电,网络,后台等等,其中最突出的就是应用外的Uri访问。什么时候会用到Uri的应用外访问呢?举一个简单的例子,下载apk更新,这个时候会调用系统功能来安装这个apk,这就是应用外访问文件,需要传入文件的

珠穆朗玛小王子的博客 2万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Android根据图片Uri获取图片path绝对路径

在Android 编程中经常会用到Uri转化为文件路径,如我们从相册选择图片上传至服务器,一般上传前需要对图片进行压缩,这时候就要用到图片的绝对路径。 下面对我开发中uri转path路径遇到的问题进行总结,其中涉及到Android不同api下对于uri的处理,还有对于Google相册图片该如何获取其图片路径。 1. 从相册获取图片 我们从相册获取的图片的代码如下: // 激活系统图...

smileiam的专栏 3万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Android根据图片Uri获取图片path绝对路径的几种方法【转】

在Android 编程中经常会用到Uri转化为文件路径,如我们从相册选择图片上传至服务器,一般上传前需要对图片进行压缩,这时候就要用到图片的绝对路径。下面对我开发中uri转path路径遇到的问题进行总结,其中涉及到Android不同api下对于uri的处理,还有对于Google相册图片该如何获取其图片路径。 1. 从相册获取图片 我们从相册获取的图片的代码如下: 1 // 激...

anjimo7409的博客 2105

android 手机内存uri_Android | 作用域存储适配

前言Android 10 已经发布了很长一段时间了,并且 Android 11 已经有很大一部分人在使用了,那么你的程序对他做了适配吗?在 10.0 中,作用域存储变得非常重要,这个新的功能颠覆了我们一直惯用外置存储的方式,因此大量的 app 都面临着代码的适配本篇文章对作用域存储,以及如何进行适配,做了比较详细的介绍在 7.0 以前我们访问内存卡中的文件时可以通过 Uri.fromFile ,将...

weixin_39712969的博客 306

Android根据图片Uri获取绝对路径

在Android 编程中经常会用到Uri转化为文件路径,如我们从相册选择图片上传至服务器,一般上传前需要对图片进行压缩,这时候就要用到图片的绝对路径。 下面对我开发中uri转path路径遇到的问题进行总结,其中涉及到Android不同api下对于uri的处理,还有对于Google相册图片该如何获取其图片路径。 1.跳转到相册并获取图片Uri 代码如下 //从相册选择 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); inte

qq_43404873的博客 2505
上一篇: 关于遗留项目重构反复看
下一篇: 上传文件worker
lynn8570_blog
博客等级 码龄10年 254粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值