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
相关产品推荐
相关产品推荐

