Kotlin Android10 open failed: EACCES (Permission denied) 解决方法 AndroidQ

本文讲述了在Android 10及以上版本中,如何解决因权限限制导致截图上传失败的问题,涉及手动申请读取权限、使用AndroidManifest.xml配置和图片文件迁移策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

项目中的一个小功能,需要 截图 并且上传截图以file类型传给后端

问题描述:

上传截图数据过程中 后端返回给我 open failed: EACCES (Permission denied)的错误提示

@RequiresApi(Build.VERSION_CODES.M)
    fun cutScreen() {
        //获取view缓存
        this.window.decorView.isDrawingCacheEnabled = true
        val bmp: Bitmap = this.window.decorView.drawingCache
        //这里"IMG"+ Calendar.getInstance().time如果没有可能会出现报错
        val uri = Uri.parse(
            MediaStore.Images.Media.insertImage(
                contentResolver,
                bmp,
                "IMG" + Calendar.getInstance().time,
                null
            )
        )
        val file = Utils.getFileFromUri(uri, this)
        sendMultipart("url", 0, file)
    }

原因分析:

android 10 需要手动申请权限并且只能访问自己目录下的文件

解决方案:

1.手动申请读取权限

   /*申请读取存储的权限*/
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(PERMISSION_WRITE_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(arrayOf(PERMISSION_WRITE_STORAGE), REQUEST_PERMISSION_CODE)
        }
    }

    myService.subscribe(MyService.RESPONSE_TOPIC, 1)
    main()

2.在AndroidManifest.xml的application中添加一句话
android:requestLegacyExternalStorage=“true”

3.将图片拷贝到自己的APP目录下 传给服务器
这个网上有方法 自己去搜

共勉

<think>好的,用户现在遇到了一个错误:`NumberFormatException` 和 `FileNotFoundException`,提示无法打开 `/proc/stat` 文件,权限被拒绝。用户想知道在Android 14上应该获取什么权限来解决这个问题。 首先,我需要分析问题的根源。用户试图访问`/proc/stat`文件,这个文件通常用于获取系统级别的信息,比如CPU使用率。在Android系统中,`/proc`目录下的文件属于系统内核信息,普通应用默认没有权限访问这些文件,尤其是在高版本Android系统中,权限控制更加严格。 接下来,错误信息显示的是`EACCES (Permission denied)`,这说明应用在尝试读取该文件时被系统拒绝了访问权限。虽然用户之前询问过`READ_PHONE_STATE`权限,但现在的问题可能涉及不同的权限或访问限制。 在Android系统中,访问系统文件如`/proc/stat`通常需要更高的权限。普通应用即使声明了`READ_PHONE_STATE`权限,也无法直接访问这些受保护的文件。从Android 10开始,Google加强了隐私保护,限制普通应用访问设备硬件标识符和系统文件。在Android 14中,这种限制可能更加严格。 可能的解决方案包括: 1. **检查是否声明了`READ_PHONE_STATE`权限**:虽然这个权限可能不足以访问`/proc/stat`,但仍然是获取一些设备信息的基础权限,需要确认是否已经在Manifest中声明。 2. **使用系统API替代直接文件访问**:Android系统推荐使用公开的API来获取系统信息,而不是直接读取系统文件。例如,使用`ActivityManager.getProcessMemoryInfo()`或`Debug.getMemoryInfo()`来获取内存信息,而不是读取`/proc/meminfo`。 3. **考虑应用权限的提升**:如果应用需要读取系统文件,可能需要系统级签名或特权权限,这对于普通应用来说是不可行的,可能仅限于系统应用或设备制造商。 此外,用户遇到的`NumberFormatException`可能是因为在尝试解析`/proc/stat`文件内容时,数据格式不符合预期,或者文件未能正确读取导致数据为空或损坏。但根本原因还是权限问题导致文件无法访问,从而引发后续的解析异常。 还需要考虑Android版本差异。在Android 14中,访问`/proc`下的文件可能需要特定的权限或使用新的API。例如,某些系统文件可能需要`READ_PRIVILEGED_PHONE_STATE`权限,但这个权限仅对系统应用有效,普通应用无法获取。 总结下来,正确的解决步骤应该是: - **推荐使用官方API**:引导用户使用Android提供的系统API来获取所需信息,而不是直接访问系统文件。 - **检查权限声明**:确认是否已经正确声明了必要的权限,如`READ_PHONE_STATE`,但需要明确说明这个权限可能不足以访问`/proc/stat`。 - **解释权限限制**:说明普通应用无法获取访问系统文件的权限,可能需要系统级权限,这对于大多数开发场景不适用。 - **错误处理建议**:建议用户在无法访问文件时添加适当的错误处理机制,避免应用崩溃。 需要确保回答清晰,结构合理,逐步引导用户解决问题,同时提供替代方案和解释背后的原因,帮助用户理解问题的本质。</think>### **Android 14 访问 `/proc/stat` 权限问题的解决方案** 你遇到的 `FileNotFoundException: /proc/stat: open failed: EACCES (Permission denied)` 错误,表明应用尝试读取系统文件 `/proc/stat` 时因权限不足被拒绝。以下是针对 Android 14 的完整分析和解决步骤: --- ### **1. 错误原因分析** - **`/proc/stat` 文件的特殊性** `/proc/stat` 是 Linux 内核暴露系统统计信息的虚拟文件,包含 CPU 使用率、中断次数等数据。 - **普通应用默认无权限访问**:从 Android 7.0(API 24)开始,Google 逐步限制了对 `/proc` 目录的直接访问,Android 14 进一步强化了此类限制。 - **安全策略升级**:Android 14 对非系统应用访问敏感系统文件的管控更加严格,即使声明了 `READ_PHONE_STATE` 权限,也无法直接读取 `/proc/stat`。 --- ### **2. 动态权限申请的局限性** - **`READ_PHONE_STATE` 权限的作用** 该权限允许应用获取设备基础信息(如 SIM 卡状态、网络类型等),但**不包含访问 `/proc` 目录的权限**。 - **动态申请无法解决此问题** 即使动态申请了 `READ_PHONE_STATE`,依然会触发 `EACCES` 错误,因为此权限与文件系统访问无关。 --- ### **3. 替代方案:使用 Android 官方 API** 直接读取 `/proc/stat` 是高风险行为,且不符合 Android 安全规范。应使用系统提供的 API 获取 CPU 信息: #### **方案 1:通过 `ActivityManager` 获取进程 CPU 使用率** ```kotlin // Kotlin 示例 val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager val processStats = activityManager.getProcessMemoryInfo(intArrayOf(android.os.Process.myPid())) val cpuUsage = processStats[0].totalPss // 获取内存占用(单位:KB) ``` #### **方案 2:通过 `Debug` 类获取调试信息** ```kotlin // 获取当前进程的 CPU 时间(单位:毫秒) val threadCpuTime = Debug.threadCpuTimeNanos() / 1_000_000 ``` #### **方案 3:使用 `UsageStatsManager`(需权限)** 若需统计全局 CPU 使用情况,可申请 `android.permission.PACKAGE_USAGE_STATS` 权限: ```xml <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/> ``` ```kotlin // 在代码中请求权限 val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS) startActivity(intent) ``` --- ### **4. 高级场景:系统级应用的解决方案** 若你的应用是系统级应用(预装在设备中且有系统签名),可尝试以下方法: #### **步骤 1:声明特权权限** 在 `AndroidManifest.xml` 中添加: ```xml <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> ``` #### **步骤 2:直接读取 `/proc/stat`** ```kotlin try { val file = File("/proc/stat") val reader = BufferedReader(FileReader(file)) val line = reader.readLine() // 读取第一行(总 CPU 使用率) reader.close() } catch (e: IOException) { e.printStackTrace() } ``` --- ### **5. 错误处理建议** 即使你找到绕过权限限制的方法,也需添加健壮的异常处理: ```kotlin try { // 尝试读取文件或调用 API } catch (e: SecurityException) { // 处理权限不足问题 Log.e("TAG", "权限被拒绝: ${e.message}") } catch (e: IOException) { // 处理文件读取错误 Log.e("TAG", "文件访问失败: ${e.message}") } ``` --- ### **总结** - **普通应用无法直接访问 `/proc/stat`**:Android 14 的安全策略禁止此行为。 - **优先使用官方 API**:通过 `ActivityManager`、`Debug` 或 `UsageStatsManager` 获取系统信息。 - **系统应用的特殊权限**:若为系统级应用,需声明特权权限并签名。 - **兼容性设计**:始终适配低版本 Android 的权限模型,避免依赖 `/proc` 文件系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值