I'm making a Notification Center for jailbroken iPhones using the theos templates (so it runs on WeeApp). It's a weather widget, and I want it to be able to get the phone's current location so it can get weather from the closest station. I'm currently using the following code to start getting locations:
i_locationManager = [[CLLocationManager alloc] init];
i_locationManager.delegate = self;
i_locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
i_locationUpdated = NO;
[i_locationManager startUpdatingLocation];
and I have a didUpdateLocations method. All of that works fine. The problem is with the pop-up the phone uses to get permission to use the location. First of all, it says that SpringBoard wants to use the location. Is there any way to get it to say my widget's name instead?
More importantly, the saved permissions don't stick. They last as long as the phone is running, but every time I respring and open the Notification Center again, it re-asks for permission to use the location.
This isn't a fatal issue, of course, but it's irritating. Is there any way to get the phone to remember that the widget is allowed to use the current location?
This might help
[CLLocationManager setAuthorizationStatus:YES forBundleIdentifier:#"com.apple.springboard"];
This will authorize SpringBoard programmatically. First time you can display pop-up and save somewhere that user authorized you. Then you can do it yourself everytime you need location.
As for application name in pop-up. You can try hooking UIApplication, SBApplication, NSBundle methods that return application name. I don't think there is easier way to do it.
Related
I need to check for device location every one hour or so and if the location is outside a particular area ( say the device has been taken out of the office premises ), do some action (like show a local notification saying "Hey! The device is outside the office").
To do this, I need to keep checking for location every one hour even though the app is killed. How to keep the app stay alive like forever though it has been terminated by the user.
Yes you can do it but if your system is deployment target is greater then 7.0.
In ios7.1 there is method called startMonitoringSignificantLocationChanges. This method updates location in background and even if application is terminated as per apple document:
Starts the generation of updates based on significant location changes.
If you start this service and your app is subsequently terminated, the
system automatically relaunches the app into the background if a new
event arrives. In such a case, the options dictionary passed to the
application:willFinishLaunchingWithOptions: and
application:didFinishLaunchingWithOptions: methods of your app
delegate contains the key UIApplicationLaunchOptionsLocationKey to
indicate that your app was launched because of a location event. Upon
relaunch, you must still configure a location manager object and call
this method to continue receiving location events. When you restart
location services, the current event is delivered to your delegate
immediately. In addition, the location property of your location
manager object is populated with the most recent location object even
before you start location services.
I found one demo for this may this help you. look this link http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
Thanks for your answers. The best way do this is to use Geofencing.
It uses startMonitoringForRegion:(CLRegion *)region where we provide the latitude and longitude of the centre of the region and also the radius of the region.
When the device moves into this region, didEnterRegion gets called.
When the device moves out of this region, didExitRegion gets called.
And yes it works even when the app is terminated/backgrounded.
In addition, we have to set NSLocationAlwaysUsageDescription in the App's Info.plist file which you will find under the Supporting Files.
View this article for detailed information.
http://www.devfright.com/how-to-use-the-clregion-class-for-geofencing/
Inorder to test this in a simulator, I used local notifications when it enters and exits the region using UILocalNotification in the didEnterRegion and didExitRegion methods.
`UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [[NSDate date] dateByAddingTimeInterval:1];
notification.alertBody = #"You have entered the region";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];`
Now change the custom location of the iOS simulator (Debug -> Location -> Custom Location), and provide latitude and longitude within the region and you get a notification saying "You have entered the region" and change the custom location to latitude and longitude outside the region, you will get a notification saying "You have exited the region".
In my app, one of my input is to get the location of the user as well as the contacts of the user. This is done from the code.
When the user runs the app for the first time,they get a dialog
"AppName" would like to use your current location. I wish to avoid this dialog since this is an important data and dont want the users to accidently press "Dont Allow"
How to avoid this dialog. Could any one please let me know. Thanks
You cant make use of location services or contacts without explicit permission from the user.
However, you can check for these permissions and tell the user that these services need to be allowed for them to use it properly.
Try looking at this answer for how to do that:
Checking for iOS Location Services
You cann't do this. If you try to do this apple will reject your app. Check this Doc1, doc2
Update Read this topic Location-Based Services
You can not dude, app will have to display the dialog
I think it's not allowed in ios.
the prompt is useful for use to know what permission of the app.
like map, photo and so on.
Basically if you are using the CLLocationManager to get the user's location, you can't. The user must allow your app to use location services. I think you could go around this by just dropping a pin on the map. For instance when you want the user to pick the location, you show the map and let the user tap where their location is, but that is not really user friendly :)
I will elaborate the process above, so that even if the user doesn't allow location services, you can get the users location manually. First you set up your CLLocationManager
_manager = [[CLLocationManager alloc] init];
_manager.delegate = self;
[_manager startUpdatingLocation];
and then you can observe it's delegate method
-(void) locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (kCLAuthorizationStatusAuthorized == status) {
//the app is authorized to use GPS
}
else {
//show map for manual location picking.
}
}
Hope this helps you to make some decisions.
Suppose in the starting the location services are off in the default settings page. I have a button in the app to turn on the location services if first time I click on that it shows the default alert to change the settings to turn on
locationmanager = [[CLLocationManager alloc]init];
[locationmanager setDelegate:self];
[locationmanager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationmanager startUpdatingLocation];
It is working fine two times. but if it got third time location services are in off condition and click on on button it doesn't show any alert. I am unable to know the CLLocation behavior. May b its not a good question to ask but still I want to clear this concept. if anyone has some idea then please help me out.
Thank You.
Here's what Apple documentation says:
In addition to hardware not being available, the user has the option of denying an application’s access to location service data. During its initial uses by an application, the Core Location framework prompts the user to confirm that using the location service is acceptable. If the user denies the request, the CLLocationManager object reports an appropriate error to its delegate during future requests. You can also check the application’s explicit authorization status using the authorizationStatus method.
So the alert could or could not appear, based on authorizationStatus.
If we try to access the user's location, iOS will tell the user that our application wants to use their location.
If I do this
[locationManager startUpdatingLocation];
An alert will show.
However, that only happens once.
It looks like some variable or default must have been set up once that display pops out.
How do I reset those default so that next time my app wants to use location users will be asked again?
Google map can displays that again and again.
It's Apple that asks them for permission, not you
Translation: You don't have any control over that part of the process. The little popup:
is only shown by Apple when you first ask for it - so the user always feels in control. After they accept for the first time, Apple assumes they are OK with your app getting their location information from their device, and won't show it again*.
*Unless they specifically go into Settings and disable Location Services for you app.
It's only showed on the first time and there's nothing you can do to change that. What you can do is ask your users to allow it on settings.
You can check if your app has permissions by checking:
[CLLocationManager locationServicesEnabled]
From the docs:
The user can enable or disable location services from the Settings application by toggling the Location Services switch in General.
You should check the return value of this method before starting location updates to determine whether the user has location services enabled for the current device. If this method returns NO and you start location updates anyway, the Core Location framework prompts the user to confirm whether location services should be reenabled.
I have something like this:
CLLocationManager *locManager = [[CLLocationManager alloc] init];
locManager.delegate = self;
locManager.desiredAccuracy = kCLLocationAccuracyBest;
[locManager startUpdatingLocation];
But I need to get below the latitude and longitude user. Obviously, trying to obtain locManager.coordinate just below the startUpdatingLocation my application crashes.
How can I make a condition to perform a process after the user allows sharing of location and it has been found?
Thanks in advance.
After calling startUpdatingLocation it can take some time until you get a location. The system first checks if location services are enabled for the app and asks the user to allow location services. The GPS hardware first needs to be turned on. It takes some time until it can fix the position.
So you should update the UI to show the user that there is something going on in the background. Consider using a UIActivityIndicatorView and maybe set userInteractionEnabled of the view to NO. Also it is a good practice to give the user the option to cancel the operation.
In your delegate you must implement these 2 methods:
– locationManager:didUpdateToLocation:fromLocation:
– locationManager:didFailWithError:
Here you can remove the UIActivityIndicatorView and reenable user interaction.
In case of success you can use the coordinate of the CLLocationManager to do whatever you want. In case of failure show an error alert.
Call stopUpdatingLocation when you don't need location services anymore to save battery.