I need to start an activity to ask the user to grant the app battery saving exemption. The user must respond yes to be able to continue:
Here is the -buggy- code I have so far:
PowerManager pm = (PowerManager)Android.App.Application.Context.GetSystemService(Context.PowerService);
while (!pm.IsIgnoringBatteryOptimizations(this.ApplicationContext.PackageName))
{
IPopupService popupService = Locator.GetSharedInstance<IPopupService>();
await popupService.DisplayAlertAsync(
BusinessResources.GoToPowerSettingsTitle,
BusinessResources.GoToPowerSettingsMessage,
BusinessResources.Ok).ConfigureAwait(true);
using (var intent = new Intent(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations, Android.Net.Uri.Parse("package:" + Forms.Context.PackageName)))
{
Forms.Context.StartActivity(intent);
}
}
Because StartActivity won't wait, I'll ask the user once more than needed.
Now I've searched for a possible solution and found ActivityTask and ActivityController.
I am confused right now. Which one should I use, provided that Xamarin Forms is on the way?
All right, I solved my problem by awaiting an AsyncAutoResetEvent after launching the activity:
An event is defined as well as a handshake value:
private AsyncAutoResetEvent dozeStandby;
private int dozeStandbyHandshake = nameof(dozeStandbyHandshake).GetHashCode(StringComparison.InvariantCultureIgnoreCase);
During the activity creation, I'm prompting the user to allow the settings. Because I'm using StartActivityForResult, OnActivityResult will be called when the prompt activity finishes:
protected override async void OnCreate(Bundle bundle)
{
dozeStandby = new AsyncAutoResetEvent();
PowerManager pm = (PowerManager)Android.App.Application.Context.GetSystemService(Context.PowerService);
while (!pm.IsIgnoringBatteryOptimizations(this.ApplicationContext.PackageName))
{
IPopupService popupService = Locator.GetSharedInstance<IPopupService>();
await popupService.DisplayAlertAsync(
BusinessResources.GoToPowerSettingsTitle,
BusinessResources.GoToPowerSettingsMessage,
BusinessResources.Ok).ConfigureAwait(true);
using (var intent = new Intent(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations, Android.Net.Uri.Parse("package:" + Android.App.Application.Context.PackageName)))
{
this.StartActivityForResult(intent, dozeStandbyHandshake);
await this.dozeStandby.WaitAsync().ConfigureAwait(true);
}
}
}
In here I check the handshake to set the event.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (requestCode == dozeStandbyHandshake)
{
this.dozeStandby.Set();
}
}