Xamarin Forms - 如何检查 Android 上的 RequestIgnoreBatteryOptimizations 权限设置
Xamarin Forms - How to check setting of RequestIgnoreBatteryOptimizations permission on Android
(请参阅下面的更新)
我在 Android 上有一个 Xamarin Forms 应用程序,它使用 Xamarin.Essentials 库。
该应用程序需要在后台 运行 提供位置数据(与手头的问题不是特别相关,但包含在上下文中),因此不得通过任何电池优化进入睡眠状态OS 可能会尝试。
我知道用户可以手动选择退出电池优化的特定应用程序,但由于它对应用程序的成功运行至关重要,我希望应用程序能够:
- 检查电池优化选择退出权限状态以确保其设置正确,
and/or
- 强制Android选择任何电池优化的应用程序。
我在 AndroidManifest.xml 中添加了一个条目,但它似乎没有帮助,新安装的应用程序默认为电池优化。
AndroidManifest.xml
清单包含以下条目:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Xamarin.Essentials
此库提供了对设备上许多与权限相关的信息的访问权限,但电池优化似乎不是其中之一。
正在使用的设备
我不知道它是否相关,但我正在三星 Galaxy S20 Ultra 上进行测试。
谁能给点建议?
2021 年 8 月 28 日更新
遵循贡献者的建议并参考 https://docs.microsoft.com/en-us/xamarin/essentials/permissions?tabs=android#extending-permissions 中的文档 ...
在我的共享代码中
public interface IRequestIgnoreBatteryOptimizationPermission
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
在我的 Android 项目中
[assembly: Xamarin.Forms.Dependency(typeof(RequestIgnoreBatteryOptimizationPermission))]
namespace MyAndroidProject
{
public class RequestIgnoreBatteryOptimizationPermission : Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizationPermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.RequestIgnoreBatteryOptimizations, true)
}.ToArray();
}
}
关于共享应用初始化
// Ensure Required Permissions have been granted
var requestIgnoreBatteryOptimizationPermission = DependencyService.Get<IRequestIgnoreBatteryOptimizationPermission>();
var status = requestIgnoreBatteryOptimizationPermission.CheckStatusAsync().Result;
if (status != PermissionStatus.Granted)
{
status = requestIgnoreBatteryOptimizationPermission.RequestAsync().Result;
}
结果...
调用 CheckStatusAsync
时,返回的结果为 Granted
。
但应用程序设置仍然另有说明...
我在物理设备 (Samsung Galaxy S20 Ultra) 和 Android 模拟器 (Pixel 2 API 28) 上都试过了,两者的结果相同。
在您的 MainActivity
中添加两个属性:
private const int RequestPermissionsId = 0
和
private readonly string[] ManifestPermissions =
{
Manifest.Permission.RequestIgnoreBatteryOptimizations
// Add here other permissions you want to check
}
然后覆盖 OnStart 方法并在那里强制进行权限检查:
public override void OnStart()
{
base.OnStart();
if ((int)Build.VERSION.SdkInt >= 23)
{
if (CheckSelfPermission(Manifest.Permission.RequestIgnoreBatteryOptimizations != Permission.Granted)
RequestPermissions(ManifestPermissions, RequestPermissionsId);
}
}
当然,请记住您必须实施 OnRequestPermissionsResult
方法:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
嗯,我猜你是想通过共享代码直接检查它
最简单的方法是使用 essentials 在本机中扩展所需的权限。
通过接口查看状态和请求权限:
public interface IRequestIgnoreBatteryOptimizations
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
实现相同的原生部分:
public class IgnoreBatteryOptimizationsPlatformPermission : Xamarin.Essentials.Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizations
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions =>
new (string, bool)[] { (Manifest.Permission.RequestIgnoreBatteryOptimizations, true) };
}
然后在你的 Native XF caller 中注册它 class(MainActivity, Appdelegate(for some other permission))
DependencyService.Register<IRequestIgnoreBatteryOptimizations, IgnoreBatteryOptimizationsPlatformPermission>();
然后在您的 XF class 中使用此方法:
public static async Task<PermissionStatus> CheckAndRequestBatteryOptimizations()
{
var batteryOptimizationsPermission = DependencyService.Get<IRequestIgnoreBatteryOptimizations>();
var status = await batteryOptimizationsPermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await batteryOptimizationsPermission.RequestAsync();
}
return status;
}
然后随时索取:
var status= await CheckAndRequestBatteryOptimizations();
这里有更多信息:https://docs.microsoft.com/en-us/xamarin/essentials/permissions?tabs=android#extending-permissions
从this document开始,有两种设置电池优化的方法
应用程序可以触发 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
意图,将用户直接带到 Battery Optimization
,他们可以在其中添加应用程序。
持有REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
权限的应用程序可以触发系统对话框,让用户直接将应用程序添加到豁免列表,而无需进入设置。该应用会触发 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Intent 以触发对话框。
我使用 PowserManager.isIgnoringBatteryOptimizations 检查电池优化。
首先,在AndroidManifest.xml
中添加RequestIgnoreBatteryOptimizations
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
然后在共享代码中创建接口。
public interface IBattery
{
void getbattery();
}
在 Android 平台中实现此接口。
[assembly: Dependency(typeof(ImplementBattery))]
namespace FormsSample.Droid
{
public class ImplementBattery : IBattery
{
public void getbattery()
{
Intent intent = new Intent();
String packageName = MainActivity.mac.PackageName;
PowerManager pm = (PowerManager)MainActivity.mac.GetSystemService(Context.PowerService);
if (pm.IsIgnoringBatteryOptimizations(packageName))
intent.SetAction(Android.Provider.Settings.ActionIgnoreBatteryOptimizationSettings);
else
{
intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
}
MainActivity.mac.StartActivity(intent);
}
}
}
正在 Mainactivity.cs 中创建静态 Mainactivity 字段。
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static MainActivity mac;
protected override void OnCreate(Bundle savedInstanceState)
{
initFontScale();
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
mac = this;
现在,使用 DependencyService 触发。
private void Button_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IBattery>().getbattery();
}
(请参阅下面的更新)
我在 Android 上有一个 Xamarin Forms 应用程序,它使用 Xamarin.Essentials 库。
该应用程序需要在后台 运行 提供位置数据(与手头的问题不是特别相关,但包含在上下文中),因此不得通过任何电池优化进入睡眠状态OS 可能会尝试。
我知道用户可以手动选择退出电池优化的特定应用程序,但由于它对应用程序的成功运行至关重要,我希望应用程序能够:
- 检查电池优化选择退出权限状态以确保其设置正确,
and/or
- 强制Android选择任何电池优化的应用程序。
我在 AndroidManifest.xml 中添加了一个条目,但它似乎没有帮助,新安装的应用程序默认为电池优化。
AndroidManifest.xml
清单包含以下条目:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Xamarin.Essentials
此库提供了对设备上许多与权限相关的信息的访问权限,但电池优化似乎不是其中之一。
正在使用的设备
我不知道它是否相关,但我正在三星 Galaxy S20 Ultra 上进行测试。
谁能给点建议?
2021 年 8 月 28 日更新
遵循贡献者的建议并参考 https://docs.microsoft.com/en-us/xamarin/essentials/permissions?tabs=android#extending-permissions 中的文档 ...
在我的共享代码中
public interface IRequestIgnoreBatteryOptimizationPermission
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
在我的 Android 项目中
[assembly: Xamarin.Forms.Dependency(typeof(RequestIgnoreBatteryOptimizationPermission))]
namespace MyAndroidProject
{
public class RequestIgnoreBatteryOptimizationPermission : Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizationPermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.RequestIgnoreBatteryOptimizations, true)
}.ToArray();
}
}
关于共享应用初始化
// Ensure Required Permissions have been granted
var requestIgnoreBatteryOptimizationPermission = DependencyService.Get<IRequestIgnoreBatteryOptimizationPermission>();
var status = requestIgnoreBatteryOptimizationPermission.CheckStatusAsync().Result;
if (status != PermissionStatus.Granted)
{
status = requestIgnoreBatteryOptimizationPermission.RequestAsync().Result;
}
结果...
调用 CheckStatusAsync
时,返回的结果为 Granted
。
但应用程序设置仍然另有说明...
我在物理设备 (Samsung Galaxy S20 Ultra) 和 Android 模拟器 (Pixel 2 API 28) 上都试过了,两者的结果相同。
在您的 MainActivity
中添加两个属性:
private const int RequestPermissionsId = 0
和
private readonly string[] ManifestPermissions =
{
Manifest.Permission.RequestIgnoreBatteryOptimizations
// Add here other permissions you want to check
}
然后覆盖 OnStart 方法并在那里强制进行权限检查:
public override void OnStart()
{
base.OnStart();
if ((int)Build.VERSION.SdkInt >= 23)
{
if (CheckSelfPermission(Manifest.Permission.RequestIgnoreBatteryOptimizations != Permission.Granted)
RequestPermissions(ManifestPermissions, RequestPermissionsId);
}
}
当然,请记住您必须实施 OnRequestPermissionsResult
方法:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
嗯,我猜你是想通过共享代码直接检查它
最简单的方法是使用 essentials 在本机中扩展所需的权限。
通过接口查看状态和请求权限:
public interface IRequestIgnoreBatteryOptimizations
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
实现相同的原生部分:
public class IgnoreBatteryOptimizationsPlatformPermission : Xamarin.Essentials.Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizations
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions =>
new (string, bool)[] { (Manifest.Permission.RequestIgnoreBatteryOptimizations, true) };
}
然后在你的 Native XF caller 中注册它 class(MainActivity, Appdelegate(for some other permission))
DependencyService.Register<IRequestIgnoreBatteryOptimizations, IgnoreBatteryOptimizationsPlatformPermission>();
然后在您的 XF class 中使用此方法:
public static async Task<PermissionStatus> CheckAndRequestBatteryOptimizations()
{
var batteryOptimizationsPermission = DependencyService.Get<IRequestIgnoreBatteryOptimizations>();
var status = await batteryOptimizationsPermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await batteryOptimizationsPermission.RequestAsync();
}
return status;
}
然后随时索取:
var status= await CheckAndRequestBatteryOptimizations();
这里有更多信息:https://docs.microsoft.com/en-us/xamarin/essentials/permissions?tabs=android#extending-permissions
从this document开始,有两种设置电池优化的方法
应用程序可以触发 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
意图,将用户直接带到 Battery Optimization
,他们可以在其中添加应用程序。
持有REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
权限的应用程序可以触发系统对话框,让用户直接将应用程序添加到豁免列表,而无需进入设置。该应用会触发 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Intent 以触发对话框。
我使用 PowserManager.isIgnoringBatteryOptimizations 检查电池优化。
首先,在AndroidManifest.xml
中添加RequestIgnoreBatteryOptimizations
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
然后在共享代码中创建接口。
public interface IBattery
{
void getbattery();
}
在 Android 平台中实现此接口。
[assembly: Dependency(typeof(ImplementBattery))]
namespace FormsSample.Droid
{
public class ImplementBattery : IBattery
{
public void getbattery()
{
Intent intent = new Intent();
String packageName = MainActivity.mac.PackageName;
PowerManager pm = (PowerManager)MainActivity.mac.GetSystemService(Context.PowerService);
if (pm.IsIgnoringBatteryOptimizations(packageName))
intent.SetAction(Android.Provider.Settings.ActionIgnoreBatteryOptimizationSettings);
else
{
intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
}
MainActivity.mac.StartActivity(intent);
}
}
}
正在 Mainactivity.cs 中创建静态 Mainactivity 字段。
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static MainActivity mac;
protected override void OnCreate(Bundle savedInstanceState)
{
initFontScale();
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
mac = this;
现在,使用 DependencyService 触发。
private void Button_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IBattery>().getbattery();
}