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

Kivy安卓应用存储访问权限被拒问题求助

Kivy访问安卓存储权限拒绝问题

问题详情

之前使用Kivy 2.0.0及Buildozer 1.5以下版本时,访问安卓存储功能正常。现在通过android.storage库的primary_external_storage_path()方法获取存储路径/storage/emulated/0/,调用os.mkdir(os.path.join(self.primary_ext_storage, "TestKivy"))创建文件夹时,即使应用首次启动已授权存储访问,点击按钮仍崩溃,报错:

PermissionError: [Errno 13] Permission denied: '/storage/emulated/0/TestKivy'

尝试在Downloads等公共目录创建文件夹也出现相同错误。

设备参数

  • 小米Mi 9T
  • MIUI Global 12.0.5 Stable
  • Android 10 QKQ1.190825.002
  • Buildozer 1.5.0

buildozer.spec配置

[app]

# (str) Title of your application
title = My Application

# (str) Package name
package.name = myapp

# (str) Package domain (needed for android/ios packaging)
package.domain = org.test

# (str) Source code where the main.py live
source.dir = .

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas

# (str) Application versioning (method 1)
version = 0.1

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy

# (list) Supported orientations
# Valid options are: landscape, portrait, portrait-reverse or landscape-reverse
orientation = portrait

#
# OSX Specific
#

#
# author = © Copyright Info

# change the major version of python used by the app
osx.python_version = 3

# Kivy version to use
osx.kivy_version = 1.9.1

#
# Android specific
#

# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0

# (list) Permissions
android.permissions = android.permission.WRITE_EXTERNAL_STORAGE, android.permission.READ_EXTERNAL_STORAGE

# (list) The Android archs to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
android.archs = arm64-v8a, armeabi-v7a

# (bool) enables Android auto backup feature (Android API >=23)
android.allow_backup = True

#
# iOS specific
#

# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.10.0

# (bool) Whether or not to sign the code
ios.codesign.allowed = false

[buildozer]

# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1

main.py代码

import os
from kivy.utils import platform


# Import kivy modules
from kivy.app import App
from kivy.uix.button import Button

# Create app
class HelloApp(App):
    def build(self):
        self.btn = Button(text="Hello World")
        self.btn.bind(on_press=self.on_press_button)
        return self.btn
    
    def on_start(self):
        if platform == "android":

            # Import necessary modules for Android permissions
            from android.storage import primary_external_storage_path
            from android.permissions import request_permissions, Permission

            # Request storage access permissions
            request_permissions([
                Permission.WRITE_EXTERNAL_STORAGE,
                Permission.READ_EXTERNAL_STORAGE
            ])

        # Set the default storage path depending on the device
        self.primary_ext_storage = primary_external_storage_path() if platform == "android" else os.environ["HOME"]


    def on_press_button(self, instance):
        # Create folder in the default storage path
        os.mkdir(os.path.join(self.primary_ext_storage, "TestKivy"))
    
# Run app
if __name__ == "__main__":
    HelloApp().run()

解决办法

  1. 适配Android 10存储策略
    Android 10引入了分区存储机制,即使申请了WRITE_EXTERNAL_STORAGE权限,也无法直接在根目录创建文件夹。需要在buildozer.spec的Android配置区域添加:

    android.extra_manifest_placeholders = android:requestLegacyExternalStorage="true"
    

    让应用使用旧版存储访问模式。

  2. 等待权限授权完成再操作
    原代码中request_permissions是异步执行的,可能权限还未通过就触发了文件夹创建操作。修改代码监听权限申请结果,确认授权后再执行存储操作:

    def on_start(self):
        if platform == "android":
            from android.storage import primary_external_storage_path
            from android.permissions import request_permissions, Permission
    
            def on_permission_result(permissions, grants):
                if all(grants):
                    self.primary_ext_storage = primary_external_storage_path()
                else:
                    # 处理权限被拒绝的逻辑
                    pass
    
            request_permissions([
                Permission.WRITE_EXTERNAL_STORAGE,
                Permission.READ_EXTERNAL_STORAGE
            ], on_permission_result)
        else:
            self.primary_ext_storage = os.environ["HOME"]
    
    def on_press_button(self, instance):
        if not hasattr(self, 'primary_ext_storage'):
            return
        folder_path = os.path.join(self.primary_ext_storage, "TestKivy")
        if not os.path.exists(folder_path):
            os.mkdir(folder_path)
    
  3. 检查MIUI特殊权限
    小米MIUI系统可能存在额外存储权限限制,进入手机设置-应用管理-目标应用-权限管理,确认“存储”权限已完全开启,无其他限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:57:23