Query the Battery State and Level of Charge

There are times when checking in on the battery status can be a good idea. The code that follows shows how to monitor battery states and levels (percent of charge) using methods in the UIDevice class.

Enable Battery Monitor

To query information regarding the iPhone battery status, you start by enabling battery monitoring through a call in the UIDevice class. With enabling active, you can then get the battery level and state (e.g. charging, discharging, etc):

[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
 
[[UIDevice currentDevice] batteryLevel];
[[UIDevice currentDevice] batteryState];
Notification of Battery Changes

You can monitor on going battery changes by registering to receive notifications of battery level and status updates:

// Request to be notified when battery charge or state changes
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryStateDidChangeNotification object:nil];

Changes in the battery level/state will result in a call to the method batteryStatus, where you can update a visual que or otherwise handle changes.

Display Battery Status

To test the battery status I’ve written a simply view controller that has nothing more than a textview, where the current status and level are displayed.

There are two relevant sections of code for this application, the first is within the loadView method where I setup a textview, enable battery monitoring and add observers for the two notifications I am interested in:

- (void)loadView 
{
  [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];
 
  // Setup the textview to display battery status
  textViewStatus = [[UITextView alloc] initWithFrame:CGRectMake	(20, 20, 280, 64)];
  [textViewStatus setFont:[UIFont boldSystemFontOfSize:18.0]];
  [textViewStatus setEditable:NO];
  [textViewStatus setTextAlignment:UITextAlignmentCenter];
  [[self view] addSubview:textViewStatus];
 
  // Round the corners and set border color  
  [textViewStatus setBackgroundColor:[UIColor whiteColor]];
  [[textViewStatus layer] setBorderColor:[[UIColor blueColor] CGColor]];
  [[textViewStatus layer] setBorderWidth:2.3];
  [[textViewStatus layer] setCornerRadius:15];
  [textViewStatus setClipsToBounds: YES];
 
  // Enable monitoring of battery status
  [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
 
  // Print current status
  [self batteryStatus];
 
  // Request to be notified when battery charge or state changes
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
 
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryStateDidChangeNotification object:nil];
 
}

The second method of interest is batteryStatus, which is the other end of the notification requests, that is, the method called via the OS when the battery status or level changes:

- (void)batteryStatus
{
 NSArray *batteryStatus = [NSArray arrayWithObjects: 
    @"Battery status is unknown.", 
    @"Battery is in use (discharging).", 
    @"Battery is charging.", 
    @"Battery is fully charged.", nil];
 
  if ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateUnknown)
  {
    [textViewStatus setText:[batteryStatus objectAtIndex:0]];  
    NSLog(@"%@", [batteryStatus objectAtIndex:0]);
  }
  else
  {  	
    NSString *msg = [NSString stringWithFormat:
      @"Battery charge level: %0.2f%%\n%@", [[UIDevice currentDevice] batteryLevel] * 100,
    [batteryStatus objectAtIndex:[[UIDevice currentDevice] batteryState]] ];
 
    [textViewStatus setText:msg];  
    NSLog(@"%@", msg);
  }
}
Notes

The battery status returned from the API’s above may not always be in sync with the status displayed on device – notice in the screenshot above that the device status is different than what is displayed in the textview (bug or feature, I’m not certain).

Also, Apple recommends that you enable battery monitoring only when your application needs to be notified of changes versus leaving enabling monitoring during the entire lifecycle of your app.

Xcode Project Source Code

Download Xcode Project: Battery Status Indicator