Xamarin Forms Android端如何检查REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限设置
问题原因
你当前自定义权限的实现存在逻辑偏差:REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 属于特殊权限,Android 没有将它纳入普通运行时权限的校验逻辑,用默认的 CheckSelfPermission 方法查询永远会返回 PERMISSION_GRANTED,和实际的电池优化豁免状态无关,这就是你校验结果和系统设置不一致的核心原因。
正确实现方案
你需要重写自定义权限类的状态查询、权限请求两个核心方法,直接调用系统电源管理的专属接口校验状态,跳转专属申请页请求权限:
共享层接口无需修改,沿用你已定义的 IRequestIgnoreBatteryOptimizationPermission 即可
Android端自定义权限类修改后的完整代码:
[assembly: Xamarin.Forms.Dependency(typeof(RequestIgnoreBatteryOptimizationPermission))] namespace MyAndroidProject { public class RequestIgnoreBatteryOptimizationPermission : Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizationPermission { public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new (string, bool)[] { (Android.Manifest.Permission.RequestIgnoreBatteryOptimizations, true) }; public override async Task<PermissionStatus> CheckStatusAsync() { // Android 6.0以下不存在电池优化机制,直接返回已授权 if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.M) return PermissionStatus.Granted; var powerManager = Android.App.Application.Context.GetSystemService(Android.Content.Context.PowerService) as PowerManager; if (powerManager == null) return PermissionStatus.Unknown; // 调用系统专属接口校验电池优化豁免状态 return powerManager.IsIgnoringBatteryOptimizations(Android.App.Application.Context.PackageName) ? PermissionStatus.Granted : PermissionStatus.Denied; } public override async Task<PermissionStatus> RequestAsync() { var currentStatus = await CheckStatusAsync(); if (currentStatus == PermissionStatus.Granted) return currentStatus; if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M) { // 跳转到系统专属的电池优化豁免申请页 var intent = new Intent(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations); intent.SetData(Android.Net.Uri.Parse($"package:{Android.App.Application.Context.PackageName}")); intent.AddFlags(Android.Content.ActivityFlags.NewTask); Android.App.Application.Context.StartActivity(intent); } // 跳转用户操作完成后,回到应用可重新调用本方法确认最终授权状态 return await CheckStatusAsync(); } } }
调用逻辑优化
你当前用 .Result 同步调用异步方法容易引发主线程死锁,建议改成异步调用:
var batteryPerm = DependencyService.Get<IRequestIgnoreBatteryOptimizationPermission>(); var status = await batteryPerm.CheckStatusAsync(); if (status != PermissionStatus.Granted) { status = await batteryPerm.RequestAsync(); }
注意事项
- 如果你计划上架Google Play,该权限的使用受政策限制,只有应用核心功能必须后台持续运行(如实时导航、健康监测类应用)才能申请,否则会被拒审。
- 三星、小米等定制ROM存在额外的后台管控机制,就算获得系统原生的电池优化豁免,仍可能被厂商自定义的休眠策略杀死,这类限制无法通过代码强制突破,只能引导用户手动到厂商专属的电池设置页将应用加入后台活动白名单。
内容的提问来源于stack exchange,提问作者user2209634
相关产品推荐
相关产品推荐

