KivyMD 1.1.1安卓应用DeepL库调用失败及MDFileManager无响应问题求助
问题排查与解决方法
一、DeepL库安卓端IsADirectoryError问题
根本原因
从错误栈可知,deepl库的_generate_user_agent()方法调用了Python标准库的platform.libc_ver()函数,而Buildozer打包的安卓环境中,该函数误将应用私有目录/data/data/org.felixmortas.flasholatorapp/files/app当作文件路径访问,触发IsADirectoryError。本质是安卓环境下的libc路径逻辑与桌面端不同,导致platform.libc_ver()失效。
解决办法
方案1:手动设置用户代理,绕过问题逻辑
修改DeeplTranslator初始化代码,直接指定自定义用户代理,避免deepl库自动生成时调用有问题的函数:
class DeeplTranslator: def __init__(self): self.auth_key = "my_auth_key" self.translator = deepl.Translator(self.auth_key) # 手动覆盖用户代理,跳过自动生成流程 self.translator._http_client.user_agent = "FlasholatorApp/1.0 (Android; Python)"
方案2:降级deepl库或改用requests
- 降级deepl库到1.10.0版本(该版本之前的用户代理生成逻辑未依赖
platform.libc_ver()),修改buildozer.spec的requirements:requirements = python3,kivy==2.1.0,kivymd==1.1.1,deepl==1.10.0 - 继续使用requests库调用DeepL API(已验证安卓端可用),示例代码:
def translate(self, text_to_translate, target_lang, source_lang): try: params = { 'auth_key': self.auth_key, 'text': text_to_translate, 'target_lang': target_lang, 'source_lang': source_lang, 'formality': 'less' } response = requests.post(self.url, data=params) response.raise_for_status() result = response.json() translation = result['translations'][0]['text'] return source_lang, translation except Exception as e: traceback.print_exc() return None, None
二、MDFileManager安卓端无响应问题
根本原因
- 权限时机与分区存储限制:Android 10启用分区存储后,
WRITE_EXTERNAL_STORAGE不再授予全局读写权限,且on_start中请求权限的时机可能晚于MDFileManager的调用时间,导致权限未生效。 - 路径兼容性:直接使用
/storage/emulated/0可能存在设备兼容性问题,部分场景下应用无法直接访问该路径。 - KivyMD版本bug:kivymd 1.1.1的MDFileManager在Android 10环境下存在交互响应的已知缺陷。
解决办法
方案1:优化权限请求与路径处理
- 提前请求权限,确保MDFileManager调用时权限已授予:
def build(self): if platform == 'android': from android.permissions import request_permissions, Permission request_permissions([ Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE, Permission.INTERNET ], self.permissions_callback) return Builder.load_file("main.kv") def permissions_callback(self, permissions, grants): # 权限确认后初始化组件 self.deepl_translator = DeeplTranslator() if platform == 'android': from android.storage import primary_external_storage_path self.device_root_path = primary_external_storage_path() - 检查路径有效性,避免无效路径导致的无响应:
import os def open_save_database_folder_selector(self): if not os.path.exists(self.device_root_path): self.device_root_path = "/storage/emulated/0" # 后续MDFileManager代码不变
方案2:调整MDFileManager参数
- 移除
ext=[".db"]参数(与selector="folder"冲突,导致逻辑异常):file_manager = MDFileManager( exit_manager=lambda x: file_manager.close(), select_path=save_database, selector="folder" ) - 添加
preview=False参数,关闭预览逻辑减少响应冲突:file_manager = MDFileManager( exit_manager=lambda x: file_manager.close(), select_path=save_database, selector="folder", preview=False )
方案3:升级KivyMD版本
将kivymd升级到2.0.0及以上版本(修复了安卓端MDFileManager的多个兼容性问题),修改buildozer.spec:
requirements = python3,kivy==2.1.0,kivymd==2.0.0,deepl==1.14.0
内容的提问来源于stack exchange,提问作者felinx94
相关产品推荐
相关产品推荐

