使用Python/Kivy+Buildozer在Colab打包的APK无法在Android创建目录
Android应用无法创建外部存储目录的解决方案
问题情况
- 非专业开发者,此前正常运行半年的简易Android应用,重新打包APK后无法创建目录
/storage/emulated/0/MK_Eng - 已确认路径正确、权限已配置、所需模块导入完成,调试多日未解决
核心代码片段
import os if kivy.platform == 'win': dirname='C:/MK_Eng/' filename='C:/MK_Eng/eng-rus-new.txt' elif kivy.platform == 'android': from android.permissions import request_permissions, Permission from android.storage import primary_external_storage_path request_permissions([Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE]) dir = primary_external_storage_path() dirname = os.path.join(dir, 'MK_Eng') filename='/storage/emulated/0/MK_Eng/eng-rus-new.txt' if not os.path.isdir(dirname): # Create Directory os.mkdir(dirname)
Buildozer配置片段
#(list) Source files to include (let empty to include all the files) source.include_exts = py,png,jpg,kv,atlas,txt #(list) Application requirements #comma separated e.g. requirements = sqlite3,kivy requirements = python3,kivy,android.permissions #(list) Permissions android.permissions = INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE #(str) python-for-android branch to use, defaults to master p4a.branch = develop
解决步骤
处理权限请求的异步问题
request_permissions是异步操作,直接调用后立刻创建目录会导致权限未生效。需要等待权限请求结果返回后再执行操作:from android.permissions import request_permissions, Permission, check_permission def create_dir_after_permission(permission, results): if all(results): if not os.path.isdir(dirname): os.mkdir(dirname) # 权限被拒绝的情况可在此添加提示逻辑 if kivy.platform == 'android': # 先检查权限状态,已授权直接创建目录 if check_permission(Permission.WRITE_EXTERNAL_STORAGE) and check_permission(Permission.READ_EXTERNAL_STORAGE): if not os.path.isdir(dirname): os.mkdir(dirname) else: # 未授权则发起请求,指定回调函数 request_permissions([Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE], create_dir_after_permission)适配Android 10+的Scoped Storage政策
Android 10(API 29)及以上启用了Scoped Storage,直接操作外部存储根目录会受限。可以选择两种方案:- 降低API版本到28(避开Scoped Storage),在Buildozer配置中添加:
android.api = 28 android.target_sdk = 28 - 适配高版本,申请
MANAGE_EXTERNAL_STORAGE权限(需用户手动在设置中授权),配置如下:android.permissions = INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE,MANAGE_EXTERNAL_STORAGE android.target_sdk = 33
- 降低API版本到28(避开Scoped Storage),在Buildozer配置中添加:
统一路径拼接方式
代码中filename直接写死路径,建议和dirname保持一致,用os.path.join拼接,避免路径错误:filename = os.path.join(dirname, 'eng-rus-new.txt')调整Python-for-Android分支
p4a.branch = develop可能存在兼容性问题,尝试切换到稳定的master分支:p4a.branch = master
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

