方法一:通过苹果官方文档里面UIDevice public API来获取,代码如下:
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
[[NSNotificationCenter defaultCenter]
addObserverForName:UIDeviceBatteryLevelDidChangeNotification
object:nil queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *notification) { // Level has changed
NSLog(@"Battery Level Change"); NSLog(@"电池电量:%.2f", [UIDevice currentDevice].batteryLevel);
}];@property(nonatomic,readonly) float batteryLevel NS_AVAILABLE_IOS(3_0);
// 0 .. 1.0. -1.0 if UIDeviceBatteryStateUnknown它返回的是0.00-1.00之间的浮点值。
但是经过测试发现,在iOS7 上 它是以0.05为单位的,但是在iOS9下测试,它是以0.01为单位的,虽然也是0.01为单位,但是测试多次也会出现偏差1%左右。也就是说, 这个办法是存在缺陷的, 最起码, 它不精确。
方法二:找到Mac下IOKit.framework,将IOKit.framework里面的IOPowerSources.h和IOPSKeys.h拷贝到你的iOS项目中。另外, 还需要把IOKit也导入到你的工程中去,此方法也会出现偏差,不精确。DEMO 地址:https://github.com/colin1994/batteryLevelTest.git
/** * Calculating the remaining energy * * @return Current batterylevel */ -(double)getCurrentBatteryLevel { //Returns a blob of Power Source information in an opaque CFTypeRef. CFTypeRef blob = IOPSCopyPowerSourcesInfo(); //Returns a CFArray of Power Source handles, each of type CFTypeRef. CFArrayRef sources = IOPSCopyPowerSourcesList(blob); CFDictionaryRef pSource = NULL; const void *psValue; //Returns the number of values currently in an array. int numOfSources = CFArrayGetCount(sources); //Error in CFArrayGetCount if (numOfSources == 0) { NSLog(@"Error in CFArrayGetCount"); return -1.0f; } //Calculating the remaining energy for (int i = 0 ; i < numOfSources ; i++) { //Returns a CFDictionary with readable information about the specific power source. pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i)); if (!pSource) { NSLog(@"Error in IOPSGetPowerSourceDescription"); return -1.0f; } psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey)); int curCapacity = 0; int maxCapacity = 0; double percent; psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey)); CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey)); CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); percent = ((double)curCapacity/(double)maxCapacity * 100.0f); return percent; } return -1.0f; }
方法三:通过runtime 获取StatusBar上电池电量控件类私有变量的值,此方法可精准获取iOS6以上电池电量
MRC: - (int)getCurrentBatteryLevel { if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive||[UIApplication sharedApplication].applicationState==UIApplicationStateInactive) { void *result = nil; object_getInstanceVariable([UIApplication sharedApplication], "_statusBar", &result); id status = result; for (id aview in [status subviews]) { for (id bview in [aview subviews]) { int batteryLevel = 0; if ([NSStringFromClass([bview class]) caseInsensitiveCompare:@"UIStatusBarBatteryItemView"] == NSOrderedSame&&[[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) { object_getInstanceVariable(bview, "_capacity", &result); batteryLevel = (int)result; NSLog(@"电池电量:%d",batteryLevel); if (batteryLevel > 0 && batteryLevel <= 100) { return batteryLevel; } else { return 0; } } } } return 0; } ARC: - (int)getCurrentBatteryLevel {UIApplication *app = [UIApplication sharedApplication];if (app.applicationState == UIApplicationStateActive||app.applicationState==UIApplicationStateInactive) { Ivar ivar= class_getInstanceVariable([app class],"_statusBar"); id status = object_getIvar(app, ivar); for (id aview in [status subviews]) { int batteryLevel = 0; for (id bview in [aview subviews]) { if ([NSStringFromClass([bview class]) caseInsensitiveCompare:@"UIStatusBarBatteryItemView"] == NSOrderedSame&&[[[UIDevice currentDevice] systemVersion] floatValue] >=6.0) { Ivar ivar= class_getInstanceVariable([bview class],"_capacity"); if(ivar) { batteryLevel = ((int (*)(id, Ivar))object_getIvar)(bview, ivar); //这种方式也可以 /*ptrdiff_t offset = ivar_getOffset(ivar); unsigned char *stuffBytes = (unsigned char *)(__bridge void *)bview; batteryLevel = * ((int *)(stuffBytes + offset));*/ NSLog(@"电池电量:%d",batteryLevel); if (batteryLevel > 0 && batteryLevel <= 100) { return batteryLevel; } else { return 0; } } } } } }return 0; }
本文转自 卓行天下 51CTO博客,原文链接:http://blog.51cto.com/9951038/1831743,如需转载请自行联系原作者