Getting user Location in SUSI Android App and using it for various SUSI Skills
Using user location in skills is a very common phenomenon among various personal assistant like Google Assistant, Siri, Cortana etc. SUSI is no different. SUSI has various skills which uses user’s current location to implement skills. Though skills like “restaurant nearby” or “hotels nearby” are still under process but skills like “Where am I” works perfectly indicating SUSI has all basic requirements to create more advance skills in near future.
So let’s learn about how the SUSI Android App gets location of a user and sends it to SUSI Server where it is used to implement various location based skills.
Sources to find user location in an Android app
There are three sources from which android app gets users location :
- GPS
- Network
- Public IP Address
All three of these have various advantages and disadvantages. The SUSI Android app uses cleverly each of them to always get user location so that it can be used anytime and anywhere.
Some factors for comparison of these three sources :
Factors | GPS | Network | IP Address |
Source | Satellites | Wifi/Cell Tower | Public IP address of user’s mobile |
Accuracy | Most Accurate (20ft) | Moderately Accurate (200ft) | Least Accurate (5000+ ft) |
Requirements | GPS in mobile | Wifi or sim card | Internet connection |
Time taken to give location | Takes long time to get location | Fastest way to get location | Fast enough (depends on internet speed) |
Battery Consumption | High | Medium | Low |
Permission Required | User permission required | User permission required | No permission required |
Location Factor | Works in outdoors. Does not work near tall buildings | Works everywhere | Works everywhere |
Implementation of location finding feature in SUSI Android App
SUSI Android app very cleverly uses all the advantages of each location finding source to get most accurate location, consume less power and find location in any scenario.
The /susi/chat.json endpoint of SUSI API requires following 7 parameters :
Sno. | Parameter | Type | Requirement |
1 | q | String | Compulsory |
2 | timezoneOffset | int | Optional |
3 | longitude | double | Optional |
4 | latitude | double | Optional |
5 | geosource | String | Optional |
6 | language | Language code | Optional |
7 | access_token | String | Optional |
In this blog we will be talking about latitude , longitude and geosource. So, we need these three things to pass as parameters for location related skills. Let’s see how we do that.
Finding location using IP Address: At the starting of app, user location is found by making an API call to ipinfo.io/json . This results in following JSON response having a field “loc” giving location of user (latitude and longitude.
{ "ip": "YOUR_IP_ADDRESS", "city": "YOUR_CITY", "region": "YOUR_REGION", "country": "YOUR_COUNTRY_CODE", "loc": "YOUR_LATITUDE,YOUR_LONGITUDE", "org": "YOUR_ISP" }
By this way we got latitude, longitude and geosource will be “ip” . We find location using IP address only once the app is started because there is no need of finding it again and again as making network calls takes time and drains battery.
So, now we have user’s location but this is not accurate. So, we will now proceed to check if we can find location using network is more accurate than location using IP address.
Finding location using Network Service Provider : To actually use the network provider and find out location requires ACCESS_COARSE_LOCATION permission from user which can be asked during the run time. Also, the location can only be found out using this if user has his location setting is enabled. So, we check following condition.
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { }
If permission is granted by user to find location using network provider, we use following code snippet to find location. It updates location of user after every 5 minutes or 10 meters (whichever is achieved first).
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5 * 60 * 1000, 10, this); location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { source = "network"; canGetLocation = true; latitude = location.getLatitude(); longitude = location.getLongitude(); }
So, whenever we are about to send query to SUSI Server, we take location from Network services, thus updating previous values of latitude, longitude and geosource (found using IP address) with the new values (found using Network Provider), provided the user has granted permission. So, we now have location is from Network Provider which is more accurate than location from IP address. Now we will check if we can find location from GPS or not.
Finding location using GPS Service Provider : Finding location from GPS Provider is almost same as Network Provider. To find location using GPS Provider user must give ACCESS_FINE_LOCATION permission. We just check if GPS of user is enabled and user has given permission to use GPS and also if GPS can actually provide location. Sometimes, GPS can not provide location because user is indoor. In that cases we leave location from GPS.
So, now if we update previous values of latitude, longitude and geosource (found using Network Provider) with the new values (found using GPS Provider) and send query to SUSI Server.
Summary
To send location to server for location skills, we need latitude, longitude and geosource. We first find these 3 things using IP address (no that accurate). So, geosource will be “ip” for now. Then check if we can find values using network provider. If yes, we update those 3 values with the ones got from network Provider (more accurate). Geosource will change to “network”. Finally, we check if we can find values using GPS provider. If yes, we update those 3 values with the ones got from GPS Provider (most accurate). Geosource will change to “gps”. So, by this way we can find location of user in any circumstance possible. If you want to use location in your app too. Just follow the above steps and you are good to go.
Resources
- https://developer.android.com/guide/topics/location/strategies.html
- https://github.com/fossasia/susi_android/blob/development/app/src/main/java/org/fossasia/susi/ai/helper/LocationHelper.java
You must be logged in to post a comment.