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

Android11下KivyMD应用存储权限异常,无法获取文件访问权限求助

解决Android 11上存储权限拒绝问题

问题根源

Android 11(API 30)及以上版本重构了存储权限机制:

  • WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE仅能访问媒体文件(图片、视频、音频),无法创建或读写非媒体类型文件(比如你要保存的site.html)。
  • 要获取完整的文件系统访问权限(即你提到的「照片、媒体和文件」权限),必须申请MANAGE_EXTERNAL_STORAGE权限。

解决方案

1. 更新buildozer.spec权限配置

在buildozer.spec文件中添加MANAGE_EXTERNAL_STORAGE权限:

android.permissions = WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE, MANAGE_EXTERNAL_STORAGE

2. 修改代码适配权限逻辑

完整代码修改:

from kivymd.app import MDApp
from kivy.base import Builder
from kivymd.toast import toast
from android.permissions import request_permissions, Permission, check_permission
from jnius import autoclass, cast
from android import mActivity
import os
import requests

# 导入Android设置相关类
Intent = autoclass('android.content.Intent')
Settings = autoclass('android.provider.Settings')
Uri = autoclass('android.net.Uri')

# 权限列表
PERMISSIONS = [
    Permission.WRITE_EXTERNAL_STORAGE,
    Permission.READ_EXTERNAL_STORAGE,
    Permission.MANAGE_EXTERNAL_STORAGE
]

# 存储路径
storage_path = os.path.join(os.environ['EXTERNAL_STORAGE'], 'Download')

KV='''
# 你的布局代码
'''

class MainApp(MDApp):
    def build(self):
        # 启动时请求权限
        request_permissions(PERMISSIONS, self.permission_callback)
        return Builder.load_string(KV)    

    def permission_callback(self, permissions, grants):
        # 检查核心权限是否授予
        if not check_permission(Permission.MANAGE_EXTERNAL_STORAGE):
            toast("需要授予完整文件访问权限才能保存文件")
            self.open_storage_settings()

    def open_storage_settings(self):
        # 跳转到应用存储权限设置页
        intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
        uri = Uri.fromParts("package", mActivity.getPackageName(), None)
        intent.setData(uri)
        mActivity.startActivity(intent)

    def download_site(self):
        # 先校验权限
        if not check_permission(Permission.MANAGE_EXTERNAL_STORAGE):
            toast("请先授予文件访问权限")
            self.open_storage_settings()
            return

        try:
            url = self.root.ids.site_link.text
            response = requests.get(url, verify=False)
            if response.status_code == 200:
                filename = os.path.join(storage_path, 'site.html')
                with open(filename, 'w', encoding='utf-8') as file:
                    file.write(response.text)
                toast("网页源码已保存")
            else:
                toast("保存网页源码失败")
        except Exception as e:
            toast("请检查网络连接")
            print(str(e))

MainApp().run()

关键修改点:

  • 加入MANAGE_EXTERNAL_STORAGE权限到请求列表
  • 添加权限回调函数,检查核心权限是否授予,未授予则引导用户跳转到设置页手动开启(该权限无法通过常规弹窗请求)
  • 在下载方法前先校验权限,确保有权限再执行保存操作

3. 注意事项

  • MANAGE_EXTERNAL_STORAGE权限在Google Play商店有审核限制,仅允许文件管理器、备份工具等特定类型应用使用。如果你的应用是普通工具类应用,建议优先考虑作用域存储(Scoped Storage),比如将文件保存到应用专属目录或媒体目录(若符合媒体类型)。
  • 低版本Android系统会自动兼容该权限逻辑,无需额外处理。

内容的提问来源于stack exchange,提问作者Mr Stranger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:27:28