I want to get battery usage data from my iPhone. I used UIDevice currentDevice.batteryLevel code, but its returning -1.0000 in NSLog value.
Anyone please help me?
One more question, can I able to fetch other app battery usages in my app?
First, you must enable batteryStatus notification (in appDelegate.m for instance):
- (void)applicationDidBecomeActive:(UIApplication *)application {
...
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
// Now, the system will post UIDeviceBatteryStateDidChangeNotification notification when batteryStatus (or connection) will change
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(batteryStatusDidChange:) name:UIDeviceBatteryStateDidChangeNotification object:nil];
...
}
Then, you can check battery level calling:
[UIDevice currentDevice].batteryLevel;
that will return you a value between 0.0 (0% chareg) and 1.0 (100% charge).
Without calling first setBatteryMonitoringEnabled, battery state will return UIDeviceBatteryStateUnknown and the value of this property is –1.0. (from docs).
Related
I'm writing an IOS application which will record ( over time ) the current battery level of the iPhone device.
I have working code executing within the foreground using UIDeviceBatteryLevelDidChangeNotification, this fires a notification ( which is handled successfully ) when the app in in foreground mode.
Code is as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(batteryChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
return YES;
}
- (void)batteryChanged:(NSNotification *)notification
{
NSLog(#"Battery Changed From Observer");
[self UpdateBatteryStatus];
}
-(void)UpdateBatteryStatus
{
UIDevice *myDevice = [UIDevice currentDevice];
double batLeft = (float)[myDevice batteryLevel] * 100;
NSLog(#"Battery level: %f", batLeft);
// Do some stuff related to battery status
}
This executes ( output via log proves it ) every 1% increment ( or decrement ) on the battery status on the phone, which works exactly as expected.
When the app is moved to the background however, the events stop firing. Upon moving the app back to the foreground, the events fire ( it's almost like they are queued up until it reaches the foreground ).
I have searched stack overflow, and most answers are all the same, basically this is a background-mode permissions problem. So I ticked all the boxes:
I added everything just to make sure it wasn't a background persmission problem. Unfortunately, even after a clean, and rebuild ( also a shutdown of Xcode, and re-plugin of iPhone ) the events still do not fire.
Please bear in mind, I have no intention of releasing this to the app store, I'm aware that faking background-mode use cases is a quick and easy rejection. But I would like to get it working for personal usage.
Edit: ios target 11.3
Your app won't get NSNotificationCenter notifications while being in background/suspended. What you could try is to use fetch background mode to mimic remote downloads. Note however downsides of this approach - system itself will decide when to call the callback.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return YES;
}
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
UIDevice *myDevice = [UIDevice currentDevice];
double batLeft = (float)[myDevice batteryLevel] * 100;
NSLog(#"Battery level: %f", batLeft);
completionHandler(UIBackgroundFetchResultNewData);
}
If you as stated do not plan to release your app in AppStore you can try another hacks with background modes like infinite playing a muted sound in background.
on iPad ios 9+, with objective-c :
- lock the orientation outside of your app
- in code: how to detect when the device changes the orientation?
I have tried all possibilities:
1) try to catch UIDeviceOrientationDidChangeNotification event:
- (void)subscribeOrientationChangeEvent {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
}
- (void) orientationChanged:(NSNotification *)note {
NSLog("Device rotated");
}
2) override viewWillTransitionToSize method
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
NSLog("Device rotated");
}
3) use KVO to see if the value orientation of [UIDevice currentDevie]
4) use KVO to see if the value statusBarOrientation of [UIApplication sharedApplication]
5) set Require FullScreen for the setting StatusBarStyle
reference: link
apply this setting and combine with all above attempts, but all failed.
6) using Accelerometer (CMMotionManager)
Any advice? thanks a lot
If the device orientation is lock; your app will have to abide by it. You won't be able to detect orientation for obvious reasons. So the short answer is you can't.
I have implemented local notification for checking battery status. If the battery level is drop by 1% then local notification is received.This works for both i.e. app is in foreground or background for iOS version below 9.
When I update device OS to iOS 9,then I received local notification in foreground but unable to receive notification in background of the Application.
Following is the code which are used to implement.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Enable monitoring of battery status
**[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];**
// Request to be notified when battery charge or state changes
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkBatteryStatus) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkBatteryStatus) name:UIDeviceBatteryStateDidChangeNotification object:nil];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Request to be notified when battery charge or state changes
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
**[[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceBatteryLevelDidChangeNotification object:nil userInfo:nil];**
**[[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceBatteryStateDidChangeNotification object:nil userInfo:nil];**
}
- (void)checkBatteryStatus
{
notifyAlarm = [[UILocalNotification alloc] init];
notifyAlarm.alertBody = #“battery alert";
notifyAlarm.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notifyAlarm];
[self displayNotification];
}
In displayNotification method we display notification.
I also enable background mode of the app i.e. shown in screenshot.
enter image description here
Any help would be appreciated. Thanks in advance.
You have enabled background fetch mode, which means that your app can receive remote notifications and perform network requests while in the background.
Without using questionable and App Store rejectable methods, it is not possible to do what you want. Apple specifically doesn't want you to be able to run your application in the background unless you have one of their approved use cases.
I'm trying to track location using locationManager in the background every "time interval" when the app is in the background.
Its working great on iOS 8 iPhone 6 - but i keep getting terminated after 2.5 - 3 minutes, by the iOS in iOS 9 iPhone 6s.
My main question is - what can be the difference between iPhone 6 iOS 8 and 6s iOS 9? better watchdog timer for background tasks? if so how can i workaround that?
I sow solutions that includes decrease of accuracy to save battery life instead of time intervals, I don't want that because the user is seeing the location monitoring indication all the time(full arrow).
some of my code -
-(void)initialize
{
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = 5;
self.locationManager.delegate = self;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(addMonitorsBeforeWillTerminate)
name:UIApplicationWillTerminateNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
[[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:nil];
}];
[self.locationManager startUpdatingLocation];
}
thanks
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"9.0")){
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
More depth and breadth information could be found in the following link.
Two options I recommend.
When in background switch to kCLLocationAccuracyThreeKilometers. That will switch off GPS and won't drain the battery because it will use cell information only. Request permission for background location services and create an NSTimer callback (this will keep your app running in the BG). Inside the callback switch to the desired accuracy, make the update of the location then switch back to low accuracy again.
Sign up for significant location changes. With that however your app won't be notified every X minutes.
For however struggling with that in the future, the answer came from "technerd" by comment so i turned it in to an answer -
https://github.com/voyage11/Location
After some googling, I can understand that the "proximity sensor" which is used to on/off screen when the device is away/near from the user. I watched this video (watch from 30th sec) and surprised about this cool stuff. I want to implement it in my app.
But I come to know that there is no public API is available that can protect the screen lock when proximityMonitoringEnabled is YES. Then how can the above app did this?
For clear understanding, I'm copying some code.
Enable the proximity sensor:
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
Setup an observer for sensor change:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sensorStateMonitor:) name:#"UIDeviceProximityStateDidChangeNotification" object:nil];
Finally you can find the state of proximity sensor from this method:
- (void)sensorStateMonitor:(NSNotificationCenter *)notification
{
if ([[UIDevice currentDevice] proximityState] == YES)
{
NSLog(#"Device is close to user.");
}
else
{
NSLog(#"Device is not closer to user.");
}
}
Question:
I want to show some view when the "Device is close to user" state was called. And want to remove the view if "Device is not closer to user" state was called.
So I added a view and removed inside the sensorStateMonitor: method. But the view was visible only for some fraction of seconds and the screen goes off.
Can I prevent the screen from auto off?
Just confused!!
The screen lock can be enabled/disabled.
[UIApplication sharedApplication].idleTimerDisabled = YES;