{"_id":"5c6b5f95f0fee50222702ffe","project":"55e67aaa9cc7c62b00c4a1ea","version":{"_id":"5b720760c44b7600034b7a08","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"forked_from":"5b1f2cbdfd653400031d8d9f","createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z","categories":["5b720760c44b7600034b79a7","5b720760c44b7600034b79a8","5b720760c44b7600034b79a9","5b720760c44b7600034b79aa","5b720760c44b7600034b79ab","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","5b720760c44b7600034b79ac","5b720760c44b7600034b79ad","5af0fe494ca2730003cbc98a","5af0fe55ec80af0003804ca2"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"API V6","version_clean":"1.4.0","version":"1.4"},"category":{"_id":"5b720760c44b7600034b79ac","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"version":"5b720760c44b7600034b7a08","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-02-08T21:31:11.878Z","from_sync":false,"order":6,"slug":"advanced-techniques","title":"Advanced Techniques"},"user":"5b0b7a46a26e6400036604fd","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2019-02-19T01:44:53.475Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":14,"body":"Android location updates can be requested using the `FusedLocationProviderClient` class. You will need to add the play services location library to your app.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"implementation \\\"com.google.android.gms:play-services-location:16.0.0\\\"\",\n      \"language\": \"groovy\"\n    }\n  ]\n}\n[/block]\n## Location Permissions\nIn order to receive location updates you will need to have the correct permissions. These should be added to the `AndroidManifest.xml` for your app.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<uses-permission android:name=\\\"android.permission.ACCESS_COARSE_LOCATION\\\"/>\\n<uses-permission android:name=\\\"android.permission.ACCESS_FINE_LOCATION\\\"/>\",\n      \"language\": \"xml\"\n    }\n  ]\n}\n[/block]\nThese permissions are not granted automatically and will also need to be requested while your app is running. You can check and request permissions like so:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"if(ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {\\n  int requestCode = 123; // Define your request code\\n  \\n  // request permissions\\n  ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, requestCode);\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nRequesting permissions will show a popup to the user asking for their permission to use location services. It is recommended to first introduce locations to the user within the app and explain why you are using them before showing the permissions popup.\n\n## Requesting Location Updates\nOnce you have received permission, the calling activity will be informed of the result in the `onRequestPermissionsResult` method. You can now register for location updates. One option for receiving these is in a `BroadcastReceiver`. We will be using this method for our guide.\n\nFirst you should create the `BroadcastReceiver`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class LocationBroadcastReceiver extends BroadcastReceiver {\\n    :::at:::Override\\n    public void onReceive(Context context, Intent intent) {\\n        if(LocationResult.hasResult(intent)) {\\n            LocationResult locationResult = LocationResult.extractResult(intent);\\n            Location location = locationResult.getLastLocation();\\n            Carnival.updateLocation(location);\\n        }\\n    }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nThis will pass the location to Sailthru Mobile using the `Carnival.updateLocation` method when it is received. You should then add the `LocationBroadcastReceiver` to the manifest. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<receiver android:name=\\\".LocationBroadcastReceiver\\\"\\n          android:exported=\\\"false\\\"/>\",\n      \"language\": \"xml\"\n    }\n  ]\n}\n[/block]\nYou can then request location updates to this receiver through the `FusedLocationProviderClient` (once you have permission).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// setup intent for BroadcastReceiver\\nIntent locationServiceIntent = new Intent(this, LocationBroadcastReceiver.class);\\n\\n// create pending intent for location services\\nPendingIntent locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);\\n\\n// get FusedLocationProviderClient\\nFusedLocationProviderClient locationProviderClient = LocationServices.getFusedLocationProviderClient(this);\\n\\n// setup location request\\nlong locationUpdateInterval = 180000; // update interval in milliseconds\\nlong locationMaxUpdateInterval = 300000; // max update interval in milliseconds\\n\\nLocationRequest locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(locationUpdateInterval).setMaxWaitTime(locationMaxUpdateInterval);\\n\\n// request updates\\nlocationProviderClient.requestLocationUpdates(locationRequest, locationIntent);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nThe broadcast receiver will receive updates until the updates are removed:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// setup intent for BroadcastReceiver\\nIntent locationServiceIntent = new Intent(this, LocationBroadcastReceiver.class);\\n\\n// create pending intent for location services\\nPendingIntent locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);\\n\\n// remove location updates\\nlocationProviderClient.removeLocationUpdates(locationIntent);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Note\",\n  \"body\": \"Android throttles location updates for apps that are in the background or terminated to \\\"a few updates per hour\\\".\"\n}\n[/block]","excerpt":"A guide to location updates on the Android platform","slug":"android-location-updates","type":"basic","title":"Android: Location Updates"}

Android: Location Updates

A guide to location updates on the Android platform

Android location updates can be requested using the `FusedLocationProviderClient` class. You will need to add the play services location library to your app. [block:code] { "codes": [ { "code": "implementation \"com.google.android.gms:play-services-location:16.0.0\"", "language": "groovy" } ] } [/block] ## Location Permissions In order to receive location updates you will need to have the correct permissions. These should be added to the `AndroidManifest.xml` for your app. [block:code] { "codes": [ { "code": "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>\n<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", "language": "xml" } ] } [/block] These permissions are not granted automatically and will also need to be requested while your app is running. You can check and request permissions like so: [block:code] { "codes": [ { "code": "if(ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {\n int requestCode = 123; // Define your request code\n \n // request permissions\n ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, requestCode);\n}", "language": "java" } ] } [/block] Requesting permissions will show a popup to the user asking for their permission to use location services. It is recommended to first introduce locations to the user within the app and explain why you are using them before showing the permissions popup. ## Requesting Location Updates Once you have received permission, the calling activity will be informed of the result in the `onRequestPermissionsResult` method. You can now register for location updates. One option for receiving these is in a `BroadcastReceiver`. We will be using this method for our guide. First you should create the `BroadcastReceiver`: [block:code] { "codes": [ { "code": "public class LocationBroadcastReceiver extends BroadcastReceiver {\n @Override\n public void onReceive(Context context, Intent intent) {\n if(LocationResult.hasResult(intent)) {\n LocationResult locationResult = LocationResult.extractResult(intent);\n Location location = locationResult.getLastLocation();\n Carnival.updateLocation(location);\n }\n }\n}", "language": "java" } ] } [/block] This will pass the location to Sailthru Mobile using the `Carnival.updateLocation` method when it is received. You should then add the `LocationBroadcastReceiver` to the manifest. [block:code] { "codes": [ { "code": "<receiver android:name=\".LocationBroadcastReceiver\"\n android:exported=\"false\"/>", "language": "xml" } ] } [/block] You can then request location updates to this receiver through the `FusedLocationProviderClient` (once you have permission). [block:code] { "codes": [ { "code": "// setup intent for BroadcastReceiver\nIntent locationServiceIntent = new Intent(this, LocationBroadcastReceiver.class);\n\n// create pending intent for location services\nPendingIntent locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);\n\n// get FusedLocationProviderClient\nFusedLocationProviderClient locationProviderClient = LocationServices.getFusedLocationProviderClient(this);\n\n// setup location request\nlong locationUpdateInterval = 180000; // update interval in milliseconds\nlong locationMaxUpdateInterval = 300000; // max update interval in milliseconds\n\nLocationRequest locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(locationUpdateInterval).setMaxWaitTime(locationMaxUpdateInterval);\n\n// request updates\nlocationProviderClient.requestLocationUpdates(locationRequest, locationIntent);", "language": "java" } ] } [/block] The broadcast receiver will receive updates until the updates are removed: [block:code] { "codes": [ { "code": "// setup intent for BroadcastReceiver\nIntent locationServiceIntent = new Intent(this, LocationBroadcastReceiver.class);\n\n// create pending intent for location services\nPendingIntent locationIntent = PendingIntent.getBroadcast(this, requestCode, locationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);\n\n// remove location updates\nlocationProviderClient.removeLocationUpdates(locationIntent);", "language": "java" } ] } [/block] [block:callout] { "type": "info", "title": "Note", "body": "Android throttles location updates for apps that are in the background or terminated to \"a few updates per hour\"." } [/block]