You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 6.0.1小米设备请求WRITE_EXTERNAL_STORAGE权限弹窗不显示排查

解决小米Android 6.0.1设备不显示WRITE_EXTERNAL_STORAGE权限弹窗问题

我来帮你分析下这个问题,小米Android 6.0.1设备上权限弹窗不显示的情况确实比较特殊,主要和MIUI的自定义权限机制以及你的代码逻辑有关,下面是具体的诊断和解决方案:

问题核心原因

  1. MIUI的权限管理特殊性:Android 6.0时期的MIUI对危险权限做了额外限制,可能默认将WRITE_EXTERNAL_STORAGE权限设为"拒绝",甚至直接屏蔽系统权限弹窗,需要用户手动在系统设置中开启。
  2. 权限申请时机不当:你在onStart()中发起权限申请,但此时Activity可能还未完全初始化完成,导致弹窗无法正常渲染显示。
  3. 重复申请逻辑的误区:当用户拒绝权限并勾选"不再询问"后,你用Handler.postDelayed重复申请的行为不会触发弹窗,系统会直接返回拒绝结果,反而造成无效操作。

具体解决方案

1. 调整权限申请时机

将权限申请逻辑移到onCreate()onResume()中(确保在super调用之后,Activity处于稳定的可交互状态):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.your_activity_layout)

    // 初始化按钮状态
    btn_submit_t.isEnabled = Singleton.isPermissionGranted(this)

    if (!Singleton.isPermissionGranted(this)) {
        // 先判断是否需要向用户解释权限用途
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(this, "需要存储权限来保存您的数据,请允许", Toast.LENGTH_SHORT).show()
        }
        // 发起权限请求
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
    }
}

2. 正确处理"不再询问"的场景

onRequestPermissionsResult中,判断用户是否勾选了"不再询问",如果是,引导用户到应用设置页面手动开启权限:

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
        1 -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.i("m", "permission_is_granted")
                btn_submit_t.isEnabled = true
            } else {
                val shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                if (!shouldShowRationale) {
                    // 用户勾选了"不再询问",引导到应用设置页面
                    Toast.makeText(this, "请在系统设置中开启存储权限", Toast.LENGTH_LONG).show()
                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
                        data = Uri.fromParts("package", packageName, null)
                    }
                    startActivity(intent)
                } else {
                    // 用户仅拒绝权限,未勾选不再询问,可提示后等待下次触发
                    Toast.makeText(this, "存储权限被拒绝,部分功能无法使用", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}

3. 适配小米MIUI的特殊设置

对于Android 6.0.1的小米设备,需要告知用户手动开启权限的路径:

  • 打开安全中心 > 权限管理 > 应用权限
  • 找到你的应用,找到"存储"权限,设置为"允许"

同时检查你的应用是否被MIUI的"纯净模式"或"后台限制"功能限制,这些也可能影响权限弹窗的正常显示。

4. 验证权限检查工具类

确保Singleton.isPermissionGranted的逻辑正确,避免因权限状态判断错误导致跳过申请流程:

object Singleton {
    fun isPermissionGranted(context: Context): Boolean {
        return ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        ) == PackageManager.PERMISSION_GRANTED
    }
}

总结

这个问题的核心是MIUI 6.0时期的自定义权限机制与标准Android权限流程的差异,结合代码中申请时机和拒绝场景处理的不足。通过调整申请时机、正确处理"不再询问"场景,并引导用户手动适配MIUI设置,就能解决权限弹窗不显示的问题。

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

火山引擎 最新活动