How to obtain extensive battery info in iOS? - ios

I'm wondering is it possible to receive information about battery like: capacity (mA), voltage (V), cycle count within iOS?
I know UIDevice class, but battery level is not what I'm looking for.

Try UIDeviceListener, it basically steals the entire battery data dictionary from UIDevice without using any private APIs. It exposes tons of information:
{
AdapterDetails = {
Amperage = 1000;
Description = "usb host";
FamilyCode = "-536854528";
PMUConfiguration = 1000;
Watts = 5;
};
AdapterInfo = 16384;
Amperage = 1000;
AppleRawCurrentCapacity = 1279;
AppleRawMaxCapacity = 1275;
AtCriticalLevel = 0;
AtWarnLevel = 0;
BatteryData = {
BatterySerialNumber = REDACTED;
ChemID = 355;
CycleCount = 524;
DesignCapacity = 1420;
Flags = 640;
FullAvailableCapacity = 1325;
ManufactureDate = REDACTED;
MaxCapacity = 1273;
MfgData = REDACTED;
QmaxCell0 = 1350;
StateOfCharge = 100;
Voltage = 4194;
};
BatteryInstalled = 1;
BatteryKey = "0003-default";
BootBBCapacity = 52;
BootCapacityEstimate = 2;
BootVoltage = 3518;
CFBundleIdentifier = "com.apple.driver.AppleD1815PMU";
ChargerConfiguration = 990;
CurrentCapacity = 1275;
CycleCount = 524;
DesignCapacity = 1420;
ExternalChargeCapable = 1;
ExternalConnected = 1;
FullyCharged = 1;
IOClass = AppleD1815PMUPowerSource;
IOFunctionParent64000000 = <>;
IOGeneralInterest = "IOCommand is not serializable";
IOInterruptControllers = (
IOInterruptController34000000,
IOInterruptController34000000,
IOInterruptController34000000,
IOInterruptController34000000
);
IOInterruptSpecifiers = (
<03000000>,
<26000000>,
<04000000>,
<24000000>
);
IOMatchCategory = AppleD1815PMUPowerSource;
IOPowerManagement = {
CurrentPowerState = 2;
DevicePowerState = 2;
MaxPowerState = 2;
};
IOProbeScore = 0;
IOProviderClass = AppleD1815PMU;
InstantAmperage = 0;
IsCharging = 0;
Location = 0;
Manufacturer = A;
MaxCapacity = 1275;
Model = "0003-A";
Serial = REDACTED;
Temperature = 2590;
TimeRemaining = 0;
UpdateTime = 1461830702;
Voltage = 4182;
"battery-data" = {
"0003-default" = <...>;
"0004-default" = <...>;
"0005-default" = <...};
"built-in" = 1;
}

I might be wrong about this but using public APIs this is not possible. According to the UIDevice documentation, it appears the most you can do is get the battery charge level, its state, and enable battery monitoring.
Update 15th Feb 2019: Looks like iOS UIDevice API's now allow developers to get access to battery charge level for the device. Whooo! It currently exposes 4 different API's. By the looks of it these are not "private", in other words can be used safely by developers without Apple blocking your app from AppStore.
Getting the Device Battery State
var batteryLevel: Float (The battery charge level for the device).
var isBatteryMonitoringEnabled: Bool (A Boolean value indicating whether battery monitoring is enabled (true) or not (false)).
var batteryState: UIDevice.BatteryState (The battery state for the device).
enum UIDevice.BatteryState (The battery power state of the device).

Its possible to fetch Battery capacity and voltage using public API and which allowed in app store as well. Here is the link -
app store
:https://itunes.apple.com/us/app/system-monitor-ultimate/id740765454?mt=8
github : https://github.com/Asido/SystemMonitor

Yes it is possible..by using private framework iosDiagnosticsupport.Framework.
After doing some tests, i have certain data about battery rather overall logs for iDevice. Here are some links that might help you... iOS Diagnostics Part 3

Look at the JSystemInfoKit library.
You want to import the IOKit framework first (get the .framework file from here /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/IOKit.framework ) and IOKit headers (get those files from here) in your iOS project.
Here you can find the methods you need to use to get extensive battery information.
Plus, IOPSCopyPowerSourcesInfo (from IOPowerSources.h) returns a NSDictionary with more information like battery health.

Related

How to get the battery temperature details in iOS?

I am getting battery status and others .
UIDevice *myDevice = [UIDevice currentDevice];
[myDevice setBatteryMonitoringEnabled:YES];
float batLeft = [myDevice batteryLevel];
int i=[myDevice batteryState];
int batinfo=(batLeft*100);
NSLog(#"Battry Level is :%d and Battery Status is :%d",batinfo,i);
switch (i)
{
case UIDeviceBatteryStateUnplugged:
{
break;
}
case UIDeviceBatteryStateCharging:
{
break;
}
case UIDeviceBatteryStateFull:
{
break;
}
default:
{
break;
}
}
Now i am trying to get the temperature details is it possible to get the battery temperature from device .
That is not possible and there is no public API to find . but I found the some answers in here May be it helps you , see once. But some private API you can get this details.
sample app you cannot use this if you deploy your app on the Apple Store, but it can be useful when deploying to TestFlight
Brother I gone through the answer for your question and which indicates that you can get and generally it shows the following states
Battery design capacity
Battery current raw capacity (in mAh)
Battery cycle count
Current battery temperature
Current battery voltage
Current battery discharge rate (device power consumption), in mA
Also following shows the results of battery
{
AdapterDetails = {
Amperage = 1000;
Description = "usb host";
FamilyCode = "-536854528";
PMUConfiguration = 1000;
Watts = 5;
};
AdapterInfo = 16384;
Amperage = 1000;
AppleRawCurrentCapacity = 1279;
AppleRawMaxCapacity = 1275;
AtCriticalLevel = 0;
AtWarnLevel = 0;
BatteryData = {
BatterySerialNumber = REDACTED;
ChemID = 355;
CycleCount = 524;
DesignCapacity = 1420;
Flags = 640;
FullAvailableCapacity = 1325;
ManufactureDate = REDACTED;
MaxCapacity = 1273;
MfgData = REDACTED;
QmaxCell0 = 1350;
StateOfCharge = 100;
Voltage = 4194;
};
BatteryInstalled = 1;
BatteryKey = "0003-default";
BootBBCapacity = 52;
BootCapacityEstimate = 2;
BootVoltage = 3518;
CFBundleIdentifier = "com.apple.driver.AppleD1815PMU";
ChargerConfiguration = 990;
CurrentCapacity = 1275;
CycleCount = 524;
DesignCapacity = 1420;
ExternalChargeCapable = 1;
ExternalConnected = 1;
FullyCharged = 1;
IOClass = AppleD1815PMUPowerSource;
IOFunctionParent64000000 = <>;
IOGeneralInterest = "IOCommand is not serializable";
IOInterruptControllers = (
IOInterruptController34000000,
IOInterruptController34000000,
IOInterruptController34000000,
IOInterruptController34000000
);
IOInterruptSpecifiers = (
<03000000>,
<26000000>,
<04000000>,
<24000000>
);
IOMatchCategory = AppleD1815PMUPowerSource;
IOPowerManagement = {
CurrentPowerState = 2;
DevicePowerState = 2;
MaxPowerState = 2;
};
IOProbeScore = 0;
IOProviderClass = AppleD1815PMU;
InstantAmperage = 0;
IsCharging = 0;
Location = 0;
Manufacturer = A;
MaxCapacity = 1275;
Model = "0003-A";
Serial = REDACTED;
Temperature = 2590;
TimeRemaining = 0;
UpdateTime = 1461830702;
Voltage = 4182;
"battery-data" = {
"0003-default" = <...>;
"0004-default" = <...>;
"0005-default" = <...};
"built-in" = 1;
}
Above things are from UIDeviceListener
I run with sample code I got below temparature
in EEPowerInformation.m class I put the breakpoint and check that.It is called and brings all information about battery.
- (void) listenerDataUpdated: (NSNotification *) notification
{
latestPowerDictionary = notification.userInfo;
NSLog(#"The latest Power Dictionary is - %#",latestPowerDictionary);
NSLog(#"The battery Temperature is - %#",[latestPowerDictionary objectForKey:#"Temperature"]);
if (self.delegate != nil)
[self.delegate powerInformationUpdated: self];
}
The Printed Statements are
The latest Power Dictionary is - {
AdapterDetails = {
Amperage = 1000;
Description = "usb host";
FamilyCode = "-536854528";
PMUConfiguration = 970;
Watts = 5;
};
AdapterInfo = 16384;
Amperage = 1000;
AppleChargeRateLimitIndex = 0;
AppleRawBrickIDVoltages = (
(
39,
420
)
);
AppleRawCurrentCapacity = 1084;
AppleRawExternalConnected = 1;
AppleRawMaxCapacity = 1221;
AtCriticalLevel = 0;
AtWarnLevel = 0;
BatteryInstalled = 1;
BatteryKey = "0003-default";
BootBBCapacity = 673;
BootCapacityEstimate = 29;
BootVoltage = 3810;
CFBundleIdentifier = "com.apple.driver.AppleARMPlatform";
ChargerConfiguration = 900;
CurrentCapacity = 1222;
CycleCount = 343;
DesignCapacity = 1430;
ExternalChargeCapable = 1;
ExternalConnected = 1;
FullyCharged = 0;
IOClass = AppleARMPMUCharger;
IOFunctionParent5E000000 = <>;
IOGeneralInterest = "IOCommand is not serializable";
IOMatchCategory = IODefaultMatchCategory;
IONameMatch = charger;
IONameMatched = charger;
IOPowerManagement = {
CapabilityFlags = 32832;
CurrentPowerState = 2;
DevicePowerState = 2;
MaxPowerState = 2;
};
IOProbeScore = 1000;
IOProviderClass = IOService;
InstantAmperage = 198;
IsCharging = 1;
Location = 0;
Manufacturer = A;
MaxCapacity = 1300;
Model = "0003-A";
Temperature = 3120;
TimeRemaining = 67;
UpdateTime = 1470665642;
Voltage = 4188;
"built-in" = 1;
}
Finally the Printed result of battery Temperature is
The battery Temperature is - 3120
if you don't need temperature number then it is useful to use ThermalState api
https://developer.apple.com/documentation/foundation/nsprocessinfothermalstate?language=objc

iOS Strange log NETAWDManager

With iOS 9 i see in my iPhone console strange logs
These logs appears when the app connected to remote service,and maybe when the connection is slow, i use NSURLSession.
Someone has an idea about the meaning of this log, should I care of this:
-[NETAWDManager reportStats:metricID:] server 0x13cd19d70, container 0x13ce9dfe0, metrid 2686983, successfully reported:
<AWDLibnetcoreTCPConnectionReport: 0x13ce7af10> {
cellularFallbackReport = {
dataUsageSnapshotsAtNetworkEvents = (
{
bytesIn = 0;
bytesOut = 410;
}
);
"fallbackTimer_msecs" = 0;
fellback = 0;
networkEvents = (
"NETWORK_EVENT_DATA_STALL_AT_APP_LAYER"
);
"timeToNetworkEvents_msecs" = (
3325
);
};
clientIdentifier = "com.mydomain.myapp";
connectionStatisticsReport = {
DNSAnswersCached = 1;
"DNSResolvedTime_msecs" = 3;
RTTvariance = 169;
"appDataStallTimer_msecs" = 3;
appReportingDataStallCount = 1;
"bestRTT_msecs" = 359;
betterRouteEventCount = 0;
bytesDuplicate = 0;
bytesIn = 37000;
bytesOut = 410;
bytesOutOfOrder = 0;
bytesRetransmitted = 0;
cellularFallback = 0;
cellularRRCConnected = 0;
connected = 1;
connectedInterfaceType = "INTERFACE_TYPE_WIFI";
"connectionEstablishmentTime_msecs" = 308;
connectionReuseCount = 0;
"currentRTT_msecs" = 79;
"flowDuration_msecs" = 30750;
interfaceType = "INTERFACE_TYPE_WIFI";
kernelReportedStalls = 0;
kernelReportingConnectionStalled = 0;
kernelReportingReadStalled = 0;
kernelReportingWriteStalled = 0;
packetsDuplicate = 0;
packetsIn = 26;
packetsOut = 1;
packetsOutOfOrder = 0;
packetsRetransmitted = 0;
"smoothedRTT_msecs" = 275;
synRetransmissionCount = 0;
tcpFastOpen = 0;
"timeToConnectionEstablishment_msecs" = 315;
"timeToConnectionStart_msecs" = 7;
"timeToDNSResolved_msecs" = 7;
"timeToDNSStart_msecs" = 4;
trafficClass = 0;
};
delegated = 0;
reportReason = "REPORT_REASON_DATA_STALL_AT_APP_LAYER";
}
Based on the identifier cellularFallbackReport, this message may be related WiFi Assist. It's a new feature in iOS 9 that detects slow WiFi connections and automatically falls back to the phone's cellular radio.
This would be consistent with your observation that the log message occurs when you have a slow connection.
If you're able to reproduce the message reliably, try disabling WiFi Assist in settings and see if it disappears:
If that's really what it is, should you care about it? Probably not. The messages indicate the iOS system is dealing with network problems automatically on behalf of your app, and there's not much you can do about it.

ID3D11VideoDevice::CreateVideoDecoderOutputView fails

I'm developing an application able to decode H264 stream through DrectX11's ID3D11VideoDecoder interface ( https://msdn.microsoft.com/en-us/library/windows/desktop/hh447766(v=vs.85).aspx ) and I got stuck at ID3D11VideoDevice::CreateVideoDecoderOutputView method, it just fails returning E_INVALIDARG. Yes, I know, there can be millions of reasons,
but are there some exceptionally common maybe? Are there any samples available illustrating decoding through ID3D11VideoDecoder (I haven't found any) ?
The part of my code that I think is most likely to fail looks as follows:
// texture
D3D11_TEXTURE2D_DESC descT = { 0 };
descT.Width = 1024;
descT.Height = 768;
descT.MipLevels = 1;
descT.ArraySize = 1;
descT.Format = DXGI_FORMAT_NV12;
descT.SampleDesc.Count = 1;
descT.Usage = D3D11_USAGE_DEFAULT;
descT.BindFlags = D3D11_BIND_DECODER;
ID3D11Texture2D *pTex = nullptr;
pDX11VideoDevice->CreateTexture2D(&desc, 0, &pTex);
// decoder
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC desc;
desc.DecodeProfile = D3D11_DECODER_PROFILE_H264_VLD_NOFGT; // what is interesting it fails whatever decoder I choose
desc.Texture2D.ArraySlice = 1;
desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
HRESULT hr = pDX11VideoDevice->CreateVideoDecoderOutputView(pTex, &desc, &pVideoDecoderOutputView); // and here the fail occurs
Thank you
OK, solved the problem, there should be
desc.Texture2D.ArraySlice = 0;
in the snippet in post above. Still lots of work ahead

Wifi Signal strength in IOS8

My App used to measure the Wifi Signal strength . For that I have used a private API in iOS7
libHandle = dlopen("/System/Library/SystemConfiguration/IPConfiguration.bundle/IPConfiguration", RTLD_LAZY);
But now it seems that Apple has removed it to some other Location in iOS8. As i am not able to find these methods .
apple80211Open = dlsym(libHandle, "Apple80211Open");
apple80211Bind = dlsym(libHandle, "Apple80211BindToInterface");
apple80211Close = dlsym(libHandle, "Apple80211Close");
apple80211GetInfoCopy = dlsym(libHandle, "Apple80211GetInfoCopy");
So do Any one has any idea where it may have been removed/replaced.
Is there any other way of measuring the Wifi Strength. (value something like : - 47)
Earlier apple80211GetInfoCopy used to return
"AUTH_TYPE" = {
"AUTH_LOWER" = 1;
"AUTH_UPPER" = 8;
};
BSSID = "74:XX:XX:60:1b:XX”; // Value changed for security.
CHANNEL = {
CHANNEL = 149;
"CHANNEL_FLAGS" = 20;
};
NOISE = {
"NOISE_CTL_AGR" = "-85";
"NOISE_UNIT" = 0;
};
"OP_MODE" = 1;
POWER = (
1
);
POWERSAVE = 1;
RATE = 135;
RSSI = {
"RSSI_CTL_AGR" = "-47";
"RSSI_UNIT" = "-1";
};
SSID = <6d506f72 74616c20 4343>;
"SSID_STR" = “Wifi XX; //Value Changed for Security
STATE = 4;
Where RSSI_CTL_AGR is what i need to fetch .
PS:The App is not for APPStore . Its for adhoc distribution.

GSSendEvent - Inject Touch Event iOS

I want to inject touch event in iPhone. I get the coordinates of touch event via network socket. GSSendEvent seems to be good choice. However, it needs GSEventRecord as one of the inputs.
Does anyone know how to prepare GSEventRecord? I prepared it based on some examples but the app crashes after GSSendEvent call.
Appreciate any help.
-(void) handleMouseEventAtPoint:(CGPoint) point
{
static mach_port_t port_;
// structure of touch GSEvent
struct GSTouchEvent {
GSEventRecord record;
GSHandInfo handInfo;
} ;
struct GSTouchEvent *touchEvent = (struct GSTouchEvent *) malloc(sizeof(struct GSTouchEvent));
bzero(touchEvent, sizeof(touchEvent));
// set up GSEvent
touchEvent->record.type = kGSEventHand;
touchEvent->record.windowLocation = point;
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->handInfo.type = getHandInfoType(0, 1);
touchEvent->handInfo.pathInfosCount = 1;
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = 1 ? 0x03 : 0x00;
touchEvent->handInfo.pathInfos[0].pathLocation = point;
port_ = GSGetPurpleSystemEventPort();
GSSendEvent((GSEventRecord*)touchEvent ,port_);
}
static GSHandInfoType getHandInfoType(int touch_before, int touch_now){
if (!touch_before) {
return (GSHandInfoType) kGSHandInfoType2TouchDown;
}
if (touch_now) {
return (GSHandInfoType) kGSHandInfoType2TouchChange;
}
return (GSHandInfoType) kGSHandInfoType2TouchFinal;
}
Only tested on iOS 6
You are actually on the right track. The problem is you have to figure out what values you should assign to these variables.
First of all, you need to import GraphicsServices.h. Then, you can try the following code with the port which you can get from How to find the purple port for the front most application in IOS 5 and above?.
I am not an iOS expert and Apple doesn't provide any documentation so I can't explain much what's going on here. (It happens to work fine for me.)
Anyway, you can play with it using xcode debug mode to see what happens under the hood.
struct GSTouchEvent * touchEvent = (struct GSTouchEvent*) &gsTouchEvent;
bzero(touchEvent, sizeof(touchEvent));
touchEvent->record.type = kGSEventHand;
touchEvent->record.subtype = kGSEventSubTypeUnknown;
touchEvent->record.location = point;
touchEvent->record.windowLocation = point;
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.window = winRef;
touchEvent->record.senderPID = 919;
bzero(&touchEvent->handInfo, sizeof(GSHandInfo));
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
GSHandInfo touchEventHandInfo;
touchEventHandInfo._0x5C = 0;
touchEventHandInfo.deltaX = 0;
touchEventHandInfo.deltaY = 0;
touchEventHandInfo.height = 0;
touchEventHandInfo.width = 0;
touchEvent->handInfo = touchEventHandInfo;
touchEvent->handInfo.type = handInfoType;
touchEvent->handInfo.deltaX = 1;
touchEvent->handInfo.deltaY = 1;
touchEvent->handInfo.pathInfosCount = 0;
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03: 0x00;
touchEvent->handInfo.x52 = 1;
touchEvent->handInfo.pathInfos[0].pathLocation = point;
touchEvent->handInfo.pathInfos[0].pathWindow = winRef;
GSEventRecord* record = (GSEventRecord*) touchEvent;
record->timestamp = GSCurrentEventTimestamp();
GSSendEvent(record, port);
To use this code, you have to call it multiple times. For one tap, there are touch-down, touch-drag and then touch-up.
Also note that pathProximity is 0 when touch is up.
As far as I remember, the winRef doesn't matter.
Hope this helps.
Edit: From Bugivore's comment, the problem is:
The way I allocated touchEvent via malloc was wrong. It should be done as EntryLevelDev showed - "static uint8_t handJob[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];"
Answer from EntryLevelDev is correct, but some of the value is not so important. I got the below codes from somewhere else and have done some try and errors, here is my codes(worked for till latested ios6).
And is anyone working on this for IOS7 now? I could not get it to work. see my post here:With GSCopyPurpleNamedPort(appId) in GraphicsServices deprecated in IOS7, what is the alternative approach?
static int prev_click = 0;
if (!click && !prev_click)
{
//which should never enter
NSLog(#"***error, postHandEvent cancel");
return;
}
CGPoint location = CGPointMake(x, y);
struct GSTouchEvent {
GSEventRecord record;
GSHandInfo handInfo;
} * event = (struct GSTouchEvent*) &touchEvent;
bzero(touchEvent, sizeof(touchEvent));
event->record.type = kGSEventHand;
event->record.windowLocation = location;
event->record.timestamp = GSCurrentEventTimestamp();
//NSLog(#"Timestamp GSCurrentEventTimestamp: %llu",GSCurrentEventTimestamp());
event->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
event->handInfo.type = getHandInfoType(prev_click, click);
//must have the following line
event->handInfo.x52 = 1;
//below line is for ios4
//event->handInfo.pathInfosCount = 1;
bzero(&event->handInfo.pathInfos[0], sizeof(GSPathInfo));
event->handInfo.pathInfos[0].pathIndex = 2;
//following 2 lines, they are by default
event->handInfo.pathInfos[0].pathMajorRadius = 1.0;
event->handInfo.pathInfos[0].pathPressure = 1.0;
//event->handInfo.pathInfos[0].pathIdentity = 2;
event->handInfo.pathInfos[0].pathProximity = click ? 0x03 : 0x00;
//event->handInfo.pathInfos[0].pathProximity = action;
event->handInfo.pathInfos[0].pathLocation = location;
// send GSEvent
GSEventRecord *event1 = (GSEventRecord*) event;
sendGSEvent(event1);

Resources