You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flet安卓应用读取SD卡文件时遭遇Permission Denied (Error 13)错误求助

Flet安卓应用读取SD卡文件时遭遇Permission Denied (Error 13)错误求助

嘿,我来帮你搞定这个权限被拒的问题~ 安卓系统对外部存储的管控一直挺严格的,尤其是从Android 6.0开始,危险权限得动态申请,再加上高版本的分区存储机制,直接硬编码路径访问文件很容易踩坑。结合你给出的代码片段,我给你梳理几个解决步骤:

1. 补全并修正权限申请的代码

你代码里的ft.Permissi应该是打错了,Flet对应的权限处理是调用页面的权限接口。你得先主动申请读取外部存储的权限,不能默认系统会自动授权。修改后的代码大概是这样:

import flet as ft
import os

FILE_PATH = "/sdcard/Documents/personnel_utf8.txt"

def main(page: ft.Page):
    page.scroll = ft.ScrollMode.ADAPTIVE
    page.appbar = ft.AppBar(title=ft.Text("PermissionHandler Tests"))
    
    # 定义需要申请的存储读取权限
    read_storage_perm = ft.Permission.READ_EXTERNAL_STORAGE

    async def check_and_request_permission(e):
        # 先检查权限状态
        status = await page.permissions.get_status(read_storage_perm)
        if status != ft.PermissionStatus.GRANTED:
            # 权限没拿到,主动申请
            result = await page.permissions.request_async([read_storage_perm])
            if result[read_storage_perm] == ft.PermissionStatus.GRANTED:
                page.add(ft.Text("权限申请成功,尝试读取文件..."))
                read_file()
            else:
                page.add(ft.Text("读取存储权限被拒绝,无法访问文件!"))
        else:
            # 已经有权限,直接读文件
            read_file()

    def read_file():
        try:
            with open(FILE_PATH, "r", encoding="utf-8") as f:
                content = f.read()
                page.add(ft.Text("文件内容:"))
                page.add(ft.Text(content))
        except Exception as e:
            page.add(ft.Text(f"读取失败:{str(e)}"))

    # 加个按钮触发权限检查和读取操作
    page.add(ft.ElevatedButton("读取文件", on_click=check_and_request_permission))
    page.update()

ft.app(main)

2. 配置AndroidManifest.xml的权限声明

光靠代码申请还不够,得先在安卓的清单文件里声明权限。你可以找到Flet项目编译后生成的Android项目中的AndroidManifest.xml,添加以下内容:

<!-- 声明读取外部存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- 如果适配Android 10(API 29)及以上,添加这个过渡属性,临时绕过分区存储限制 -->
<application
    android:requestLegacyExternalStorage="true"
    ... <!-- 保留原有其他属性 -->
>

3. 调整上传文件的权限

你用adb push上传的文件,默认权限可能只有root用户能访问,普通应用没权限读取。可以在电脑上执行这个adb命令修改文件权限:

adb shell chmod 666 /sdcard/Documents/personnel_utf8.txt

这个命令会让所有用户都能读写该文件,确保你的应用能正常访问。

4. 长期适配建议(Android 11+)

如果你的目标是Android 11及以上系统,官方推荐用分区存储(Scoped Storage),硬编码路径访问会越来越受限。你可以用Flet的FilePicker组件让用户手动选择文件,既符合系统规范,也能避免权限问题,代码示例:

import flet as ft

def main(page: ft.Page):
    page.scroll = ft.ScrollMode.ADAPTIVE
    page.appbar = ft.AppBar(title=ft.Text("文件读取测试"))

    async def pick_and_read_file(e):
        # 调用文件选择器
        result = await page.file_picker.pick_files(allow_multiple=False)
        if result:
            selected_file = result.files[0]
            try:
                with open(selected_file.path, "r", encoding="utf-8") as f:
                    content = f.read()
                    page.add(ft.Text(f"读取到文件内容:"))
                    page.add(ft.Text(content))
            except Exception as e:
                page.add(ft.Text(f"读取失败:{str(e)}"))

    # 初始化文件选择器并添加到页面
    page.file_picker = ft.FilePicker()
    page.add(ft.ElevatedButton("选择文件并读取", on_click=pick_and_read_file))
    page.update()

ft.app(main)

你可以先试前三个步骤快速解决当前问题;如果要做长期适配,再考虑FilePicker的方案~

备注:内容来源于stack exchange,提问作者leobip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 16:30:29