The bulk of the fun occurs in the .Android project. The entire code that gets called when the battery state changes resides in the .Android project so this technique works for regular Xamarin too. However, iOS manages this functionality in it's own special way so you're on your own there.
I'm using Visual Studio version 16.6.1. Start a new Xamarin Forms project called BatteryMonitor. Deselect the iOS option.
Start a new Xamarin.Forms solution and call it BatteryMonitor |
Select the Blank option and deselect iOS. |
We need to make it look like this.
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Android.Content;
namespace BatteryMonitor.Droid
{
[Activity(Label = "BatteryMonitor", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher
= true, ConfigurationChanges =
ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle
savedInstanceState)
{
TabLayoutResource =
Resource.Layout.Tabbar;
ToolbarResource =
Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
this.RegisterReceiver(new BatteryReceiver(), new IntentFilter(Intent.ActionBatteryChanged));
}
public override void
OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[]
grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode,
permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
public class BatteryReceiver : BroadcastReceiver
{
public override void
OnReceive(Context context, Intent intent)
{
BatteryMonitor.MainPage mainPage =
Xamarin.Forms.Application.Current.MainPage as BatteryMonitor.MainPage;
mainPage.BatteryLevel =
intent.GetIntExtra(BatteryManager.ExtraLevel, 0);
}
}
}
As you can see, all we did was create the BatteryReceiver class which inherits BroadcastReceiver and implements the mandatory OnReceive method. Then we registered the class in the MainActivity.OnCreate method. As we registered it, we stated it should be called whenever the battery status changed. You can also provide a list of intents in the same registration. The receiver class would normally be in it's own class file, but I want to focus on functionality here.
When the application starts, and whenever the battery state changes, Android will call BatteryReceiver.OnReceive. The Intent parameter contains different information for different intents. We can easily get the current battery level from the intent.
Now we have to display it so we move to the BatteryMonitor project. Open MainPage.xaml and make it look like this.
<?xml
version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="This"
x:Class="BatteryMonitor.MainPage">
<ContentPage.BindingContext>
<x:Reference Name="This"/>
</ContentPage.BindingContext>
<StackLayout>
<Label Text="{Binding Path=BatteryLevel}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="Header"/>
</StackLayout>
</ContentPage>
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
namespace BatteryMonitor
{
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
private int _BatteryLevel
= 0;
public int
BatteryLevel
{
get { return
_BatteryLevel; }
set { SetProperty(ref _BatteryLevel, value); }
}
public MainPage()
{
InitializeComponent();
}
public bool
SetProperty<T>(ref T Storage, T value,
[CallerMemberName] string
propertyName = null)
{
if (Object.Equals(Storage, value)) return false;
Storage = value;
OnPropertyChanged(propertyName);
return true;
}
}
}
If you run this using an emulator you can open the extended controls by clicking on the ellipsis at the bottom of the vertical control strip. Then you can move the Charge level slider and watch BatteryReceiver get called.
No comments:
Post a Comment