{"id":150,"date":"2017-10-09T06:32:41","date_gmt":"2017-10-09T06:32:41","guid":{"rendered":"http:\/\/www.creativesparksolutions.com\/blog\/?p=150"},"modified":"2018-03-12T14:39:31","modified_gmt":"2018-03-12T14:39:31","slug":"how-to-handle-location-when-developing-an-android-app-fused-location-updated-2017","status":"publish","type":"post","link":"https:\/\/www.creativesparksolutions.com\/blog\/how-to-handle-location-when-developing-an-android-app-fused-location-updated-2017\/","title":{"rendered":"How to Handle Location when Developing an Android App [Fused Location, Nougat]"},"content":{"rendered":"<p>Hi Mobile App Developers, Lets take a quick Look at :<\/p>\n<div class=\"su-box su-box-style-soft su_box_width\" id=\"\" style=\"border-color:#c13b03;border-radius:2px;\"><div class=\"su-box-title\" style=\"background-color:#f46e36;color:#FFFFFF;border-top-left-radius:0px;border-top-right-radius:0px\">Handling Permissions and Location Updated in Android Apps using Fused Location<\/div><div class=\"su-box-content su-u-clearfix su-u-trim\" style=\"border-bottom-left-radius:0px;border-bottom-right-radius:0px\"><strong>Scope:<\/strong> Handling of Permission and getting updates. We&#8217;ll talk about this strictly <u>in the context of FUSED location API<\/u><\/p>\n<p><strong>Background:<\/strong> We found that Location handling was really one of the areas in android app development where there was some persistent confusion. Trainee staff in our own team had to be explained how to map user requirements to a workable location strategy.<\/p>\n<p><strong>Excluded:<\/strong> Actual code for implementing the fused location which we will look into in a subsequent article.<\/p>\n<p><strong>LEVEL:<\/strong> BEGINNER TO INTERMEDIATE<\/div><\/div>\n<strong>Background:<\/strong> We found that Location handling was really one of the areas in android app development where there was some persistent confusion. Trainee staff in our own team had to be explained how to map user requirements to a workable location strategy.<\/p>\n<p><strong>COVERAGE:<\/strong>  Code snippets provided without full working code.<\/p>\n<p><strong>LEVEL:<\/strong> BEGINNER TO INTERMEDIATE<\/p>\n<p>Lets Assume the  following use cases for the application of this article:<br \/>\nThe client requires that your mobile app show the nearest service provider to him &#8211;  it could be<br \/>\na) A Cab Hailing App<br \/>\nb) A Trucking \/ Commercial Vehicle app<br \/>\nc) A Delivery and Logistic app<br \/>\nd)  A Service provider such as a Carpenter \/ Electrician, Beauty Salon<\/p>\n<div id=\"attachment_157\" style=\"width: 760px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-157\" src=\"http:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/mainimage.jpg\" alt=\"Handling Location Permissions in Android\" width=\"750\" height=\"343\" class=\"size-full wp-image-157\" srcset=\"https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/mainimage.jpg 750w, https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/mainimage-300x137.jpg 300w, https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/mainimage-400x183.jpg 400w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><p id=\"caption-attachment-157\" class=\"wp-caption-text\">Tackling Location Permissions in Android<\/p><\/div>\n<p>If you see carefully, case a), b) , c) are somewhat similar in the sense that a periodic tracking is required whereas case d) is mainly that of retail shops \/offices at a single point where periodic tracking of the service provider is not required to know of his location. Just a user initiated update is enough.<\/p>\n<p><strong>How to provide periodic Tracking from the Mobile Phone itself?<\/strong><br \/>\nSo, in the above scenarios a), b), c) a periodic updating of the location &#8211; latitude and longitude is required by the app. We&#8217;ve generally seen this done by an API which saves the provider&#8217;s location periodically into the database and the android activity can retrieve the lat, long of the chosen provider in the activity&#8217;s view from the database. The trick is to do this with proper permissions (chosen either on opening app or install etc.) , and with only the required battery consumption.<\/p>\n<p>And this brings us to an important Question, which is: <\/p>\n<h3>What is the best way to provide location permissions when developing your Android App?<\/h3>\n<p>First up, location was earlier requested through <strong>android.location API<\/strong> but <strong>since 2014, Fused Location through Google Play Services<\/strong> has been available to get location updates. This is compatible Android 2.3 onwards, so pretty much covers all devices.<\/p>\n<p>Fused location has many advantages and is a recommended way of getting location details according to Google. We assume here that you would know it&#8217;s background but if you don&#8217;t <a href=\"https:\/\/developers.google.com\/location-context\/fused-location-provider\/\" rel=\"nofollow\" target=\"_blank\">check out the details here<\/a>.<\/p>\n<p>So coming back, lets look at how location permission is saved in a typical android phone (Nougat, Marshmallow included).<\/p>\n<h3>Situations your Android app must tackle when seeking location updates<\/h3>\n<p>A) Either the location is completely off.<br \/>\nOR<br \/>\nB)if the Location setting is on &#8211; then<br \/>\n1) Whether GPS option is on (High Accuracy)<br \/>\n2) Whether Networking or Wifi (Low Battery setting) use is On<\/p>\n<p><strong>Fused location provider<\/strong> API (now FusedLocationProviderClient) actually takes care of all these situations and removes the guesswork by automatically changing the appropriate system settings based on desired accuracy and available options \/permissions.<\/p>\n<div class=\"bk_onehalfs bk-shortcode clearfix\"><div class=\"column one_half halfsc\">             \n                    <div id=\"attachment_161\" style=\"width: 368px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-161\" src=\"http:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/runtimelocationexample.jpg\" alt=\"Typical runtime Location Permission Popup in Android\" width=\"358\" height=\"379\" class=\"size-full wp-image-161\" srcset=\"https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/runtimelocationexample.jpg 358w, https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/runtimelocationexample-283x300.jpg 283w\" sizes=\"auto, (max-width: 358px) 100vw, 358px\" \/><p id=\"caption-attachment-161\" class=\"wp-caption-text\">Typical run-time Location Permission Popup in Android<\/p><\/div>\n                <\/div><div class=\"column one_half halfsc\">             \n                    <div id=\"attachment_160\" style=\"width: 401px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-160\" src=\"http:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/location_services_screenshot1.png\" alt=\"Power consumption for Location Service\" width=\"391\" height=\"329\" class=\"size-full wp-image-160\" srcset=\"https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/location_services_screenshot1.png 391w, https:\/\/www.creativesparksolutions.com\/blog\/wp-content\/uploads\/2017\/10\/location_services_screenshot1-300x252.png 300w\" sizes=\"auto, (max-width: 391px) 100vw, 391px\" \/><p id=\"caption-attachment-160\" class=\"wp-caption-text\">Power Consumption options when choosing Location in Android app<\/p><\/div>\n                <\/div><\/div>\n<h3> Settings and Permissions Strategy<\/h3>\n<p>Keep in mind that many a times networking or low power or what is denoted by COARSE_LOCATION Permission will SUFFICE for your needs. According to Google the accuracy is 50-100 metres for COARSE_LOCATION. If you are in suburb or city in India, i think we can take a worse case scenario of 75-100 metres accuracy.<\/p>\n<p>I would say that this is sufficient for most logistics and delivery app situations such as b) and c) and definitely acceptable for case d). <span>Another aspect that we found was that in many cases, developers had made GPS usage mandatory<\/span> even when unnecessary. <\/p>\n<p>GPS is mainly necessary for Taxi or Cab hailing apps: where a more frequent update of location as well as direction and speed calculations are required. Practically, one should set Limits of accuracy  and \/ or update as per the business requirements. More frequent or more accurate location settings will lead to greater battery drain.<\/p>\n<p>The App may also provide the user, options to change his \/ her location settings if he or she wants to &#8211; taking full benefit of the location feature. Ideally, it should work with the low power setting also, except where GPS is compulsorily required &#8211; such as a cab hailing App.<br \/>\n<i>Therefore, do not restrict the user to use GPS only; unless it&#8217;s a business requirement.<\/i> <\/p>\n<p>As a far as permissions are concerned if location is required regularly, it would be better to take permission on install but switch location services off whenever not needed.  If it is infrequent or based on a specific activity or event then you can give permissions at Runtime.  In order to use the location services provided by Google Play Services Fused Location Provider, connect your app using the Settings Client, check the current location settings and prompt the user to enable the required settings if needed.<\/p>\n<h3>Steps in getting Location Updates in Fused Location (Location services Android Tutorial)<\/h3>\n<h4>1. Setting the Permission<\/h4>\n<p>Import Google Play services from Android SDK (..\/sdk\/extras\/google\/google_play_service\/libproject\/google-play-services_lib) as a library in your application<\/p>\n<p><code><br \/>\n{<br \/>\nmanifest xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"<br \/>\n  package=\"com.google.android.gms.location.sample.locationupdates\"<br \/>\n  <uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"\/><br \/>\n\/manifest<br \/>\n}<br \/>\n<\/code><\/p>\n<h4>2. Create a Location Services Client<\/h4>\n<p><code><br \/>\nprivate FusedLocationProviderClient mFusedLocationClient;<br \/>\n\/\/ ..<br \/>\n@Override<br \/>\nprotected void onCreate(Bundle savedInstanceState) {<br \/>\n    \/\/ ...<br \/>\n    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);<br \/>\n}<br \/>\n<\/code><\/p>\n<h4>3. Getting the Last known Location <\/h4>\n<p><code><br \/>\nmFusedLocationClient.getLastLocation()<br \/>\n        .addOnSuccessListener(this, new OnSuccessListener<Location>() {<br \/>\n            @Override<br \/>\n            public void onSuccess(Location location) {<br \/>\n                \/\/ Got last known location. In some rare situations this can be null.<br \/>\n                if (location != null) {<br \/>\n                    \/\/ Logic to handle location object<br \/>\n                }<br \/>\n            }<br \/>\n        });<br \/>\n<\/code><br \/>\nNote that null handling has to be done as in some scenario location may not be returned. Also, the above step is not really necessary if we&#8217;re requiring periodic location updates.<br \/>\nTo get periodic location updates, and in our own control <strong>we need to set up a Location request client and get location requests from it at pre-configured periodic intervals. <\/strong><br \/>\nAnd to do this you have to define all these configuration settings.  <i>Which brings us to Step 4.<i><\/p>\n<h4>4. Set Update interval, Fastest update interval and Priority Configuration for Location Updates.<\/h4>\n<p>In this case lets assume we have a case where infrequent location updates are fine &#8211; say every 10 minutes is more than enough. Also lets assume a very high accuracy is not required and we can do with 100 metre error. Typical settings in such as scenario would probably be like this:<br \/>\n<code><br \/>\nprotected void createLocationRequest() {<br \/>\n    LocationRequest mLocationRequest = new LocationRequest();<br \/>\n    mLocationRequest.setInterval(900000);<br \/>\n    mLocationRequest.setFastestInterval(600000);<br \/>\n    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);<br \/>\n}<br \/>\n<\/code><br \/>\nSo as you can see  &#8211; we&#8217;re defining these settings in the <strong>LocationRequest<\/strong> object just created. We have the setFastestInterval as upper limit for any location update (which other apps may also be getting ) to be used by you. So for us since 10 mins is the minimum and we can do with 15 minutes as well &#8211; we&#8217;ve kept the values accordingly (measured in milliseconds).<\/p>\n<p>After creating the locationRequest &#8211; get the current location to begin with:<br \/>\n<code><br \/>\nLocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()<br \/>\n     .addLocationRequest(mLocationRequest);<br \/>\n<\/code><\/p>\n<p>Apart from this, you can also get the Current Location Settings, prompt user to change settings if required (an optional step in most cases) as explained <a href=\"https:\/\/developer.android.com\/training\/location\/change-location-settings.html\" target=\"_blank\">here<\/a>. NOW you are ready to get the regular Location updates which is required for Tracking.<\/p>\n<h4>5. Getting Regular Location updates from Fused Location.<\/h4>\n<p>The API updates your app periodically with the best available location, based on the currently-available location providers such as WiFi and GPS (Global Positioning System). The accuracy of the location is determined by the providers, the location permissions you&#8217;ve requested, and the options you set in the location request. <\/p>\n<p><code><br \/>\n@Override<br \/>\nprotected void onResume() {<br \/>\n    super.onResume();<br \/>\n    if (mRequestingLocationUpdates) {<br \/>\n        startLocationUpdates();<br \/>\n    }<br \/>\n}<\/p>\n<p>private void startLocationUpdates() {<br \/>\n    mFusedLocationClient.requestLocationUpdates(mLocationRequest,<br \/>\n            mLocationCallback,<br \/>\n            null \/* Looper *\/);<br \/>\n}<br \/>\n<\/code><\/p>\n<p>So startLocationUpdates is the main method which is passing the LocationRequest object and Callback.<br \/>\nmRequestingLocationUpdates is a boolean flag which is used to indicate if location requests are ON or OFF by the user of the App.<br \/>\nNow the LocationCallback interface also needs to be implemented which actually gets the Latitude and Longtitude.<\/p>\n<p><code><br \/>\nprivate LocationCallback mLocationCallback;<br \/>\n\/\/ ...<br \/>\n@Override<br \/>\nprotected void onCreate(Bundle savedInstanceState) {<br \/>\n    \/\/ ...<\/p>\n<p>    mLocationCallback = new LocationCallback() {<br \/>\n        @Override<br \/>\n        public void onLocationResult(LocationResult locationResult) {<br \/>\n            for (Location location : locationResult.getLocations()) {<br \/>\n                \/\/ Update UI with location data<br \/>\n                \/\/ ...<br \/>\n            }<br \/>\n        };<br \/>\n    };<br \/>\n}<br \/>\n<\/code><\/p>\n<p><strong>Stopping or Pausing a Location Request <\/strong><br \/>\nThis is an important option which can help reduce power consumption to stop getting location updates when not needed. For example, if it&#8217;s a regular saving of location in database but when your vehicle is stopping or in rest  &#8211; on click of your Rest \/ Shift Completed button, the location updates could stop as there is no need to track you. This could even be time based.<br \/>\n<code><br \/>\n@Override<br \/>\nprotected void onPause() {<br \/>\n    super.onPause();<br \/>\n    stopLocationUpdates();<br \/>\n}<\/p>\n<p>private void stopLocationUpdates() {<br \/>\n    mFusedLocationClient.removeLocationUpdates(mLocationCallback);<br \/>\n}<br \/>\n<\/code><\/p>\n<p><span style=\"color:red;font-weight:bold;\">Note:<\/span> The important thing to be kept in mind is that the above examples show location requests based on a specific activity but if your requirement is such that tracking continues even if application is in background then you need to use a background service and get the current location. In that scenario , you do NOT need to request Location updates as the background service itself can be run periodically and just get the current location. Further , here the settings need not be configured to Reflect the Fastest interval and just the Accuracy to BALANCED POWER would be enough.<\/p>\n<p>Another option could be to use PendingIntent as explained <a href=\"https:\/\/developers.google.com\/android\/reference\/com\/google\/android\/gms\/location\/FusedLocationProviderClient#requestLocationUpdates(com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationCallback)\">here<\/a> to get location in background cases.<\/p>\n<p>If you&#8217;re looking to build a Location, GPS tracking, Logistics or Cab hailing app , maybe our <a href=\"http:\/\/www.creativesparksolutions.com\" title=\"Android, ios and hybrid mobile app development from Delhi, India\">mobile app development company based out of Delhi<\/a>, can help you. Just reach out to us and we&#8217;ll be happy to provide a free consultation.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content --><!-- AddThis Related Posts generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Hi Mobile App Developers, Lets take a quick Look at : Background: We found that Location handling was really one of the areas in android app development where there was some persistent confusion. Trainee staff in our own team had to be explained how to map user requirements to a workable location strategy. COVERAGE: Code snippets provided without full working code. LEVEL: BEGINNER TO INTERMEDIATE Lets Assume the following use cases for the application of this article: The client requires that your mobile app show the nearest service provider to him &#8211; it could be a) A Cab Hailing App [&hellip;]<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><!-- AddThis Related Posts generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":3,"featured_media":174,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[22,21,23,24],"class_list":["post-150","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android-tutorials-tips","tag-android-location","tag-android-tutorial","tag-fusedlocation","tag-gps-tracking"],"_links":{"self":[{"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/posts\/150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=150"}],"version-history":[{"count":23,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/posts\/150\/revisions"}],"predecessor-version":[{"id":494,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/posts\/150\/revisions\/494"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/media\/174"}],"wp:attachment":[{"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.creativesparksolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}