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

Kivy安卓应用如何在用户未授予权限时不执行后续操作?

问题原因

Android 端的权限申请是异步非阻塞操作,调用request_permissions方法后系统只会弹出授权弹窗,不会等待用户操作完成就会继续执行后续代码,因此会出现「还没点击同意就开始执行扫描逻辑」的问题,最终因为缺少权限导致应用崩溃。

解决思路
  1. 给权限申请绑定结果回调,在用户完成授权操作后再执行需要权限的业务逻辑
  2. 把原本写在on_start中的文件扫描逻辑抽为独立方法,仅在确认所有必要权限都已授予后再调用
  3. 补充权限被拒绝的兜底处理,避免应用直接闪退
修改后完整代码
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:45:07