Kivy安卓应用如何在用户未授予权限时不执行后续操作?
问题原因
Android 端的权限申请是异步非阻塞操作,调用request_permissions方法后系统只会弹出授权弹窗,不会等待用户操作完成就会继续执行后续代码,因此会出现「还没点击同意就开始执行扫描逻辑」的问题,最终因为缺少权限导致应用崩溃。
解决思路
- 给权限申请绑定结果回调,在用户完成授权操作后再执行需要权限的业务逻辑
- 把原本写在
on_start中的文件扫描逻辑抽为独立方法,仅在确认所有必要权限都已授予后再调用 - 补充权限被拒绝的兜底处理,避免应用直接闪退
修改后完整代码
import os from plyer import storagepath from kivy.lang import Builder from kivy.utils import platform from kivymd.app import MDApp from kivymd.toast import toast class MainApp(MDApp): def __init__(self, **kwargs): super(MainApp, self).__init__(**kwargs) self.kv = Builder.load_string(''' #:kivy 2.0.0 # 其余KV布局代码 ''') # 统一维护所需权限列表 self.required_permissions = [] def build(self): if platform == "android": from android.permissions import request_permissions, Permission, check_permission self.required_permissions = [ Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE, Permission.INTERNET ] # 先校验是否已经获得全部权限 has_all_permissions = all([check_permission(perm) for perm in self.required_permissions]) if not has_all_permissions: # 申请权限,绑定结果回调 request_permissions(permissions=self.required_permissions, callback=self.on_permission_result) else: # 已获得全部权限,直接执行扫描 self.scan_audio_files() else: # 非安卓平台无需申请权限,直接执行扫描 self.scan_audio_files() return self.kv def on_permission_result(self, permissions, grant_results): """权限申请结果回调,grant_results为对应权限的授权结果,True表示授权通过""" all_granted = all(grant_results) if all_granted: self.scan_audio_files() else: toast("缺少必要权限,无法扫描音频文件") # 可在此处补充权限拒绝后的处理逻辑,比如引导用户到系统设置开启权限,或退出应用 def scan_audio_files(self): """抽离独立的音频扫描逻辑,确保仅在有权限时执行""" for file in os.listdir(storagepath.get_downloads_dir()): if file.endswith("mp3"): # 原有音频处理业务逻辑 pass def on_start(self): # 此处不要放置需要权限的逻辑,原有扫描逻辑已移至scan_audio_files方法 pass if __name__ == '__main__': MainApp().run()
注意事项
- 如果需要适配Android 13及以上系统,读取媒体音频的权限需要替换为
READ_MEDIA_AUDIO,原有READ_EXTERNAL_STORAGE权限在安卓13+版本已经失效 - 可以根据产品需求完善权限拒绝后的交互逻辑,避免用户拒绝权限后应用功能异常无提示
内容的提问来源于stack exchange,提问作者Omid Ketabollahi
相关产品推荐
相关产品推荐

