adam
adam

Reputation: 22597

Detect if device is charging

I can't find anything definite using my favourite tool, however I thought I would put it out here...

Is there a way, using the iPhone SDK, for an app to detect if the device is in a state of receiving power (charging, dock, etc.)?

I would like to be able to disable the idleTimer automatically if the device is receiving power (otherwise it is a user-specified setting).

Upvotes: 34

Views: 20118

Answers (10)

Xaxxus
Xaxxus

Reputation: 1869

As many have said, you can detect this state using UIDevice.current.batteryState.

but you can go further than this, and see when the state changes using Notification Center.

here's an example for if you want the screen to stay awake when the app is plugged in:

Swift 5

    class BatteryManager {
        static let shared: BatteryManager = .init()

        private init() {
            UIDevice.current.isBatteryMonitoringEnabled = true
    
            NotificationCenter.default.addObserver(
                self,
                selector: #selector(batteryStateDidChange),
                name: UIDevice.batteryStateDidChangeNotification,
                object: nil
            )
        }
    
        deinit {    
            NotificationCenter.default.removeObserver(
                self,
                name: UIDevice.batteryStateDidChangeNotification,
                object: nil
            )
        }
    
        @objc private func batteryStateDidChange() {
            let state = UIDevice.current.batteryState
    
            UIApplication.shared.isIdleTimerDisabled = state == .full || state == .charging
        }
    }

Upvotes: 1

Peter Brockmann
Peter Brockmann

Reputation: 3704

... and @Brad's answer for Swift 5:

    UIDevice.current.isBatteryMonitoringEnabled = true
    if UIDevice.current.batteryState != .unplugged {
        UIApplication.shared.isIdleTimerDisabled = true
    }

Upvotes: 0

tBug
tBug

Reputation: 826

If you want to check on more than one place than something like this.

class Device {

    static let shared = Device()

    func checkIfOnCharcher() -> Bool {
        UIDevice.current.isBatteryMonitoringEnabled = true
        if (UIDevice.current.batteryState != .unplugged) {
            return true
        } else {
            return false
        }
    }
}

Usage:

if Device.shared.checkIfOnCharcher() == true { 
      //Some Code
} else { 
   // Some code
}

Upvotes: 0

bogdan.stratulat
bogdan.stratulat

Reputation: 1

func checkForCharging() {

UIDevice.current.isBatteryMonitoringEnabled = true

if UIDevice.current.batteryState != .unplugged {

print("Batery is charging")

} else if UIDevice.current.batteryState == .unplugged {

print("Check the cable")

}

Upvotes: 0

King
King

Reputation: 2035

Swift 4.2

Bool Value

    var batteryState: Bool {
        IDevice.current.isBatteryMonitoringEnabled = true
        let state = UIDevice.current.batteryState

        if state == .charging || state == .full {
            print("Device plugged in.")
            return true

        } else {
            return false
        }

    }

Upvotes: 1

Oded Regev
Oded Regev

Reputation: 4415

Swift 4

UIDevice.current.isBatteryMonitoringEnabled = true

if (UIDevice.current.batteryState != .unplugged) {
    print("Device is charging.")
}

Swift 3

UIDevice.currentDevice().batteryMonitoringEnabled = true;

if (UIDevice.currentDevice().batteryState != .Unplugged) {
    print("Device is charging.");
}

Upvotes: 12

UpSampler
UpSampler

Reputation: 399

Swift 3:

UIDevice.current.isBatteryMonitoringEnabled = true
let state = UIDevice.current.batteryState

if state == .charging || state == .full {
    print("Device plugged in.")
}

Upvotes: 8

OhadM
OhadM

Reputation: 4801

You can use darwin notification center and use the event name com.apple.springboard.fullycharged.

This way you will get a notification to your custom method, here is a code snip:

// Registering for a specific notification
NSString *notificationName = @"com.apple.springboard.fullycharged";
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                NULL,
                                yourCustomMethod,
                                (__bridge CFStringRef)notificationName,
                                NULL, 
                                CFNotificationSuspensionBehaviorDeliverImmediately);

// The custom method that will receive the notification
static void yourCustomMethod(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
  NSString *nameOfNotification = (__bridge NSString*)name;

  if([nameOfNotification isEqualToString:notificationName])
  {
    // Do whatever you want...
  }
} 

Upvotes: 3

Alastair Stuart
Alastair Stuart

Reputation: 4185

Yes, UIDevice is capable of telling you this:

[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];

if ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) {
    NSLog(@"Device is charging.");
}

See the UIDevice reference in the docs for more info, and for other values of batteryState.

Upvotes: 36

Brad
Brad

Reputation: 11515

You are better off using:

[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];

if ([[UIDevice currentDevice] batteryState] != UIDeviceBatteryStateUnplugged) {
      [UIApplication sharedApplication].idleTimerDisabled=YES;
    }

This is because you have to concern yourself with two different states - one is that the battery is charging, and the other when it is fully charged.

If you really wanted to be complete about it - you would register to receive battery monitoring notifications, so you could re-enable the idle timer if the user disconnected main power, etc.

Upvotes: 46

Related Questions