33

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).

Fish Below the Ice
  • 1,273
  • 13
  • 23
adam
  • 22,404
  • 20
  • 87
  • 119
  • Nice touch on linking Google, I laughed. Good question, saved me time. Thanks to you and the contributors. – serge-k Jul 19 '16 at 14:31

10 Answers10

46

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.

Brad
  • 11,262
  • 8
  • 55
  • 74
  • 1
    "You would register to receive battery monitoring notifications": Here's how to do that: https://stackoverflow.com/q/31391373/12484 – Jon Schneider Nov 08 '20 at 20:40
36

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.

RedBlueThing
  • 42,006
  • 17
  • 96
  • 122
Alastair Stuart
  • 4,165
  • 3
  • 36
  • 33
11

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.");
}
Oded Regev
  • 4,065
  • 2
  • 38
  • 50
8

Swift 3:

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

if state == .charging || state == .full {
    print("Device plugged in.")
}
Community
  • 1
  • 1
UpSampler
  • 399
  • 2
  • 6
3

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...
  }
} 
OhadM
  • 4,687
  • 1
  • 47
  • 57
  • 1
    The answer is iOS...you should try the snip code. I used it in a few projects of mine. Also, read the hyperlinks above. – OhadM Nov 25 '16 at 23:43
1

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
        }

    }
King
  • 1,885
  • 3
  • 27
  • 84
1

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
        }
    }
Xaxxus
  • 1,083
  • 12
  • 19
0
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")

}
Elio Lako
  • 1,333
  • 2
  • 16
  • 26
  • Hi welcome to Stack Overflow. There are some formatting issues with your post. I generally use markdown and surround my code with three ` characters. (```) – Glenn Watson Mar 15 '19 at 13:30
0

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
}
tBug
  • 789
  • 9
  • 13
0

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

    UIDevice.current.isBatteryMonitoringEnabled = true
    if UIDevice.current.batteryState != .unplugged {
        UIApplication.shared.isIdleTimerDisabled = true
    }
Peter Brockmann
  • 3,594
  • 3
  • 28
  • 28