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

Android如何程序化检查后台启动权限是否已被用户授予?

检查Android后台启动权限的可行方案

首先得跟你说清楚:原生Android并没有提供像Settings.canDrawOverlays(context)这样统一的API来直接检查后台启动权限——毕竟这个权限大多是国内安卓厂商基于原生系统额外定制的(比如小米、华为、OPPO等),不同厂商的实现逻辑和判断方式差异很大。不过我们可以通过以下几种思路来间接判断或适配:

一、利用Android 10+系统的后台限制API做参考

从Android 10(API 29)开始,系统新增了后台活动限制的相关判断,虽然不完全等同于厂商的「后台启动权限」,但可以作为通用层面的参考:

val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    // 检查应用是否处于后台受限状态
    val isRestricted = activityManager.isBackgroundRestricted
    // 或者查看应用的待机桶级别,RESTRICTED_BUCKET代表后台活动被严格限制
    val bucket = activityManager.getAppStandbyBucket()
    if (bucket == ActivityManager.STANDBY_BUCKET_RESTRICTED) {
        // 后台启动大概率被限制
    }
}

二、针对主流厂商做单独适配(反射/读取系统设置)

由于各厂商的后台启动权限存储在不同的系统设置项中,咱可以针对常用厂商做单独适配,不过要注意这类方法依赖厂商的系统实现,随时可能因版本更新失效,一定要做好异常捕获:

小米/红米设备示例

fun isBackgroundStartAllowedXiaomi(context: Context): Boolean {
    return try {
        val settingsClass = Class.forName("android.provider.MiuiSettings\$Security")
        val field = settingsClass.getField("BACKGROUND_START_ALLOWED")
        val uri = field.get(null) as Uri
        Settings.Secure.getInt(context.contentResolver, uri.toString().split("/").last(), 1) == 1
    } catch (e: Exception) {
        // 反射失败时默认返回true,或者根据你的需求处理
        true
    }
}

华为/荣耀设备示例

fun isBackgroundStartAllowedHuawei(context: Context): Boolean {
    return try {
        Settings.System.getInt(context.contentResolver, "hw_background_launch_allowed", 1) == 1
    } catch (e: Exception) {
        true
    }
}

三、间接验证法(实际执行后台启动操作)

如果不想做繁琐的厂商适配,你可以在用户从设置页返回后,尝试执行一个需要后台启动的操作,根据操作是否成功来判断权限是否开启:

// 先替换掉已废弃的startActivityForResult,改用ActivityResultLauncher更规范
private val startSettingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == RESULT_OK) {
        // 在这里执行后台启动验证,比如尝试启动后台服务
        val serviceIntent = Intent(this, YourBackgroundService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(serviceIntent)
        } else {
            startService(serviceIntent)
        }
        // 后续可以通过监听服务的启动状态,或者用Handler延迟检查Activity是否能被后台唤起
    }
}

// 跳转设置页的代码改成这样:
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", packageName, null)
intent.data = uri
startSettingsLauncher.launch(intent)

总结

因为后台启动权限的碎片化问题,目前没有完美的通用检查方案。最稳妥的方式是:

  • 引导用户进入设置页开启权限
  • 用户返回后,通过实际执行后台操作来验证权限是否生效
  • 针对主流厂商做单独适配,提升判断准确性

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

火山引擎 最新活动