iOS Tutorial Location & GPS

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
The iLocation library allows you to get the current known location and to monitor location updates. You can also monitor the device heading direction.

As the location is considered a private information, you can only get the location if the user has allowed you to get the location. This type of authorization is different than Android permissions system. At runtime the user can decide whether to allow your app do use this service or not.



The AuthorizationStatusChanged event is raised after you initialize LocationManager. It will also be raised after the user has changed the authorization status from the device settings (Under Privacy - Location Services).

The authorization status can be in one of the following states:
- Not determined - This will be the status when the user first runs your app. You should call LocationManager.Start. The user will be asked to approve it.
- Authorized - The user has already allowed your app to use this service.
- Not authorized - You need to ask the user to go to the settings page and enabled this service.

B4X:
Private Sub LocManager_AuthorizationStatusChanged (Status As Int)
   lblEnable.Visible = (LocManager.AuthorizationStatus = LocManager.AUTHORIZATION_DENIED _
     OR LocManager.AuthorizationStatus = LocManager.AUTHORIZATION_RESTRICTED)
   StartLocationUpdates
End Sub

Private Sub StartLocationUpdates
   'if the user allowed us to use the location service or if we never asked the user before then we call LocationManager.Start.
   If LocManager.IsAuthorized OR LocManager.AuthorizationStatus = LocManager.AUTHORIZATION_NOT_DETERMINED Then
     LocManager.Start(0)
   End If
   LocManager.StartHeading
End Sub
Note that you can safely call Start multiple times.

Once we are authorized to use the location service we can start to work with the LocationChanged event.

It will fire once with the last known location and then whenever there is a new known location.



Notes
-
Monitoring the device heading doesn't require any special permission.
- If the heading accuracy is important then you need to handle the AllowCalibration event and return true:
B4X:
Sub LocManager_AllowCalibration As Boolean
   Return
End Sub
The device built-in calibration screen may show if calibration is required.
- You need to add the following two lines to your app:
B4X:
  #PlistExtra:<key>NSLocationWhenInUseUsageDescription</key><string>Used to display the current navigation data.</string>
   #PlistExtra:<key>NSLocationUsageDescription</key><string>Used to display the current navigation data.</string>
This message will be displayed to the user, explaining why the location services are required. The first line is for iOS 8+ and the second is for iOS 7.
 

Attachments

Filippo

Expert
Licensed User
This example not works for me, nothing is displayed and no error. :(
 

Filippo

Expert
Licensed User
The layout is not displayed?
After an estimated 50 times only once worked.
But I do not so bad, I have tested the example only because of the location-Library, and the work in my app.
 

marcel

Active Member
Licensed User
IOS has normally terms like kCLLocationAccuracyBest, kCLLocationAccuracyNearestTenMeters. Using this settings you can choose how often your app need updates. (To safe battery). I suppose the Start Method convert this to the correct constanse above.. correct?
 

marcel

Active Member
Licensed User
The library currently doesn't set the accuracy property at all. It only sets the distanceFilter.

I think that for most apps it should suffice as the GPS is only working when the app is running.

If you want to set the accuracy then it can be done with NativeObject. I can help you with this if you need it.
Yes, I need this because my app is running in the background. I am more then happy to extend the current library.
 
Last edited:

Filippo

Expert
Licensed User
+1
 

Erel

Administrator
Staff member
Licensed User
You can use this method to set the accuracy. Call it before you call Start:
B4X:
Sub SetAccuracty(lm As LocationManager, accuracy As Double)
   Dim no As NativeObject = lm
   no = no.GetField("manager")
   no.SetField("desiredAccuracy", accuracy)
End Sub
The supported values are:
Best (default): -1
Best for navigation: -2
10, 100, 1000 and 3000 (meters).
 

moster67

Expert
Licensed User
I read somewhere that iOS handles the location for you (including GPS, wifi hot spots and cell triangulation):
The locations service in iPhone works in one of the three ways, from cell triangulation, wifi hot spots or the GPS. They have varying accuracies(GPS being most accurate) but also varying battery consumption(GPS again consuming the most) so by forcing the horizontal accuracy to be KCLLH.A.
I guess what I wanted to ask is if user does not allow usage of GPS, will this library fall back using Wifi hot spots and/or cell triangulation to obtain and report location?
 

Turbo3

Active Member
Licensed User
Documentation says AuthorizationStatus returns one of four AUTHORIZATION status values. However, only three have been defined.

What is the fourth status which returns a value of 3? Why is it not defined as a constant?
 

Turbo3

Active Member
Licensed User
Sorry, but there seem to be 4 when using AuthorizationStatus. IsAuthorized just returns true or false.

You have constants defined for three values 0 through 2

0=AUTHORIZATION_NOT_DETERMINED
1=AUTHORIZATION_RESTRICTED
2=AUTHORIZATION_DENIED

The one you are missing:
3= ???? probably means authorized

When I run my app I get 2 if location not enabled for my app and 3 if enabled in Settings.

Sound like you are unaware of value 3 but it is there and should have a constant defined.
 

Turbo3

Active Member
Licensed User
I am only going by the example code which you provided above that uses both IsAuthorized and AuthorizationStatus. The comment in the below code say I need to look at both IsAuthorized and AuthorizationStatus before I call Start(0). Now you seem to be saying that is wrong and you only need to look at IsAuthorized. Why does the below code use AuthorizationStatus if it is not really needed?

B4X:
Private Sub StartLocationUpdates
    'if the user allowed us to use the location service or if we never asked the user before then we call LocationManager.Start.
    If LocManager.IsAuthorized OR LocManager.AuthorizationStatus = LocManager.AUTHORIZATION_NOT_DETERMINED Then
        LocManager.Start(0)
    End If
    LocManager.StartHeading
End Sub
 

Erel

Administrator
Staff member
Licensed User
This code is correct. There are two cases where you should call start:
1. The user has already allowed your app to use the location services (LocManager.IsAuthorized = True).
2. The user wasn't yet asked whether she wants to allow your app to use the location service (LocManager.AuthorizationStatus = LocManager.AUTHORIZATION_NOT_DETERMINED).
 

Turbo3

Active Member
Licensed User
AuthorizationStatus
0 = Not Determined (Blank) Calling Start will clause iOS to open permission msgbox)
1 = Restricted
2 = Denied (Never)
3 = Authorized (Depreciate in iOS 8)
4 = While Using App (new in iOS 8)
5 = Always (new in iOS 8)
 

MikeH

Well-Known Member
Licensed User
An odd thing, I`m getting speeds of -1 and -2 occasionally. My code is:

B4X:
Sub LocManager_LocationChanged (Location1 As Location)

Dim MPS As Int = Location1.speed
Log(MPS)
How can this be? It doesn`t mean I`m moving backwards :)
 

Turbo3

Active Member
Licensed User
Negative speed values indicate that the speed is not valid yet. GPS has not locked on to enough satellites to determine the speed.
 
Status
Not open for further replies.
Top