{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","params":[],"results":{"codes":[]},"settings":""},"next":{"description":"","pages":[]},"title":"Location Permission Implementation","type":"basic","slug":"android-permissions","excerpt":"","body":"The Pulsate SDK requires an Android system permission, Location which is required for beacon scans, geofencing and location updates. Different Android versions require different permissions and must be asked for in the proper way or the App not operate in the most efficient way or problems could emerge. \n\n[block:api-header]\n{\n  \"title\": \"Android 11\"\n}\n[/block]\nGoogle has introduced new guidelines for “Sensitive app permissions”, inluding android.permission.BACKGROUND_LOCATION, which the Pulsate SDK automatically adds to your app’s AndroidManifest. While submitting your app, you may find your app being rejected by Google Play Console. In order to mitigate this, we recommend that you follow the below steps to mitigate this risk.\n\nMore information related to the new changes related to Location Permissions is located here: \nhttps://developer.android.com/about/versions/11/privacy/location\n\n\nWhen you install the Pulsate SDK, the location following permission settings will automatically be added to the AndroidManifest file.  \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<uses-permission android:name=\\\"android.permission.ACCESS_FINE_LOCATION\\\" />\\n<uses-permission android:name=\\\"android.permission.ACCESS_COARSE_LOCATION\\\" />\\n<uses-permission android:name=\\\"android.permission.ACCESS_BACKGROUND_LOCATION\\\" />\",\n      \"language\": \"xml\"\n    }\n  ]\n}\n[/block]\nThere are two approaches to requesting background location within the new Android eco-system: \n\n1) Two separate priming screens. The first priming screen will gather foreground permissions, and the subsequent will gather background permissions. \n\n2) A single priming screen which you will use to obtain both Foreground and Background Permissions\n\nThe 1st approach is preferred to make it clear to the end user that you are gathering Background permissions, why you are gathering them and ensuring they know what to do when they are brought to the system location permissions screen. \n\nOn your initial priming screen you should specify why the app needs foreground permissions. You should clearly identify why you need these permissions on this priming screen. Use cases may include:\n\n- Customer Service\n- Marketing Communications\n- Improved Engagement experience\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/010264f-Screenshot_20201120-171047.png\",\n        \"Screenshot_20201120-171047.png\",\n        1080,\n        2280,\n        \"#333\"\n      ]\n    }\n  ]\n}\n[/block]\nOnce the user clicks on the action button to Accept the Permissions, they must be prompted to allow foreground permission \"While using the app\"\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/60d7923-Screenshot_20201120-161236.png\",\n        \"Screenshot_20201120-161236.png\",\n        1080,\n        2280,\n        \"#333\"\n      ]\n    }\n  ]\n}\n[/block]\nYou should include the code below to request foreground location permissions (as pictured above) \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// On Foreground Location Priming Screen\\nif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\\n  int foregroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);\\n  if (foregroundCheck != PackageManager.PERMISSION_GRANTED) {\\n    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);\\n  }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nNext up, you will create the priming screen which will request background permissions. \n\nTwo pieces of content are important on this screen:\n\n**1) To clearly specify why you need the sensitive \"Background\" location permission.** \n\nUse cases may include: \n\n- To Receive location based support\n- Save you time at the Drive-thru \n- Get notified of exclusive in-Branch/in-store Services.\n\n**2) To explain to the end user that they must click \"Allow all the time\" on the following screen**\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/cf58da7-Screenshot_20201120-171633.png\",\n        \"Screenshot_20201120-171633.png\",\n        1080,\n        2280,\n        \"#333\"\n      ]\n    }\n  ]\n}\n[/block]\nOnce the user accepts allowing background permissions, you will present them with the system background permission screen. Here, they must select \"Allow all the time\"\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/9f45447-Screenshot_20201120-161306.png\",\n        \"Screenshot_20201120-161306.png\",\n        1080,\n        2280,\n        \"#333\"\n      ]\n    }\n  ]\n}\n[/block]\nYou should include the code below to request background location permissions. (as pictured above) \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Background Location Priming Screen\\nif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\\n  int backgroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION);\\n  if (backgroundCheck != PackageManager.PERMISSION_GRANTED) {\\n    requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1);\\n  }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n\n\n\nShould you wish to skip the two step process above (which is not recommended) here is a code example to carry out the request permission checks in a single step. As part of your priming screen you must clearly define:\n\n1) All of your use cases as to why you need background permission\n2) You also must make it clear to the user that they must \"Allow all the time\" when brought to the location permission screen. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Example Permission callback identifier, can be a different number\\nint mLocationCode = 1;\\nif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\\n\\tint foregroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);\\n\\tint backgroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION);\\n\\tif (foregroundCheck != PackageManager.PERMISSION_GRANTED) {\\n\\t\\trequestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, mLocationCode);\\n\\t} else if (backgroundCheck != PackageManager.PERMISSION_GRANTED) {\\n\\t\\trequestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, mLocationCode);\\n\\t}\\n}\\n\\n:::at:::Override\\npublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {\\n\\tsuper.onRequestPermissionsResult(requestCode, permissions, grantResults);\\n  if (requestCode == mLocationCode) {\\n  \\tif (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\\n    \\tif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\\n      \\tint backgroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION);\\n        if (backgroundCheck != PackageManager.PERMISSION_GRANTED) {\\n        \\trequestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, mLocationCode);\\n        }\\n      }\\n    }\\n  }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Android 10\"\n}\n[/block]\n\nIn Android Manifest add -\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<uses-permission android:name=\\\"android.permission.ACCESS_FINE_LOCATION\\\" />\\n<uses-permission android:name=\\\"android.permission.ACCESS_COARSE_LOCATION\\\" />\\n<uses-permission android:name=\\\"android.permission.ACCESS_BACKGROUND_LOCATION\\\" />\",\n      \"language\": \"xml\"\n    }\n  ]\n}\n[/block]\nWhen asking for location permission ask for it like this -\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.Q) {\\n\\tActivityCompat.requestPermissions(activity,\\n        new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1);\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Android 9 and under\"\n}\n[/block]\n\nIn Android Manifest add -\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<uses-permission android:name=\\\"android.permission.ACCESS_FINE_LOCATION\\\" />\\n<uses-permission android:name=\\\"android.permission.ACCESS_COARSE_LOCATION\\\" />\",\n      \"language\": \"xml\"\n    }\n  ]\n}\n[/block]\nWhen asking for location permission ask for it like this -\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ActivityCompat.requestPermissions(activity,\\n        new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]","updates":[],"order":3,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"5f2ab2b34eb4a30057fc71f5","createdAt":"2020-08-05T13:22:59.608Z","user":"57bc3654b9c7f0220009c77b","category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"SDK Quick Start","slug":"sdk-quick-start","order":1,"from_sync":false,"reference":false,"_id":"5f2ab0dfbf70f7063ad0c4f3","createdAt":"2020-08-05T13:15:11.164Z","version":"5e5019b49e8f240011cc6ade","project":"54aa7f773b56130b0056c86e","__v":0},"version":{"version":"2.8","version_clean":"2.8.0","codename":"Android SDK","is_stable":false,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["5e5019b49e8f240011cc6a47","55781fe35129590d003ff4f9","55781fe35129590d003ff4fa","5e5019b49e8f240011cc6a48","5e5019b49e8f240011cc6a49","5e5019b49e8f240011cc6a4a","5e5019b49e8f240011cc6a4b","5e5019b49e8f240011cc6a4c","565b66c446118c0d00dcb0bb","56898269f8dc340d00308c13","5e5019b49e8f240011cc6a4d","5e5019b49e8f240011cc6a4e","5c73dd27e8fdc000572a206a","5e5019b49e8f240011cc6a4f","5e501b7e7c8bdc00450ea66a","5e53daa9884b750025b5cad4","5f2ab0dfbf70f7063ad0c4f3","5f2ab1e9448d87068b348f9c","5f2ab1f9c1644603559149ac","5f2ab205bc35e507e8cead35"],"_id":"5e5019b49e8f240011cc6ade","project":"54aa7f773b56130b0056c86e","forked_from":"5e4fbbbda8fb41028f1861fe","__v":6,"createdAt":"2015-06-10T11:30:42.700Z","releaseDate":"2015-06-10T11:30:42.700Z"},"project":"54aa7f773b56130b0056c86e","__v":0,"parentDoc":null}

Location Permission Implementation


The Pulsate SDK requires an Android system permission, Location which is required for beacon scans, geofencing and location updates. Different Android versions require different permissions and must be asked for in the proper way or the App not operate in the most efficient way or problems could emerge. [block:api-header] { "title": "Android 11" } [/block] Google has introduced new guidelines for “Sensitive app permissions”, inluding android.permission.BACKGROUND_LOCATION, which the Pulsate SDK automatically adds to your app’s AndroidManifest. While submitting your app, you may find your app being rejected by Google Play Console. In order to mitigate this, we recommend that you follow the below steps to mitigate this risk. More information related to the new changes related to Location Permissions is located here: https://developer.android.com/about/versions/11/privacy/location When you install the Pulsate SDK, the location following permission settings will automatically be added to the AndroidManifest file. [block:code] { "codes": [ { "code": "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />\n<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />\n<uses-permission android:name=\"android.permission.ACCESS_BACKGROUND_LOCATION\" />", "language": "xml" } ] } [/block] There are two approaches to requesting background location within the new Android eco-system: 1) Two separate priming screens. The first priming screen will gather foreground permissions, and the subsequent will gather background permissions. 2) A single priming screen which you will use to obtain both Foreground and Background Permissions The 1st approach is preferred to make it clear to the end user that you are gathering Background permissions, why you are gathering them and ensuring they know what to do when they are brought to the system location permissions screen. On your initial priming screen you should specify why the app needs foreground permissions. You should clearly identify why you need these permissions on this priming screen. Use cases may include: - Customer Service - Marketing Communications - Improved Engagement experience [block:image] { "images": [ { "image": [ "https://files.readme.io/010264f-Screenshot_20201120-171047.png", "Screenshot_20201120-171047.png", 1080, 2280, "#333" ] } ] } [/block] Once the user clicks on the action button to Accept the Permissions, they must be prompted to allow foreground permission "While using the app" [block:image] { "images": [ { "image": [ "https://files.readme.io/60d7923-Screenshot_20201120-161236.png", "Screenshot_20201120-161236.png", 1080, 2280, "#333" ] } ] } [/block] You should include the code below to request foreground location permissions (as pictured above) [block:code] { "codes": [ { "code": "// On Foreground Location Priming Screen\nif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\n int foregroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);\n if (foregroundCheck != PackageManager.PERMISSION_GRANTED) {\n requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);\n }\n}", "language": "java" } ] } [/block] Next up, you will create the priming screen which will request background permissions. Two pieces of content are important on this screen: **1) To clearly specify why you need the sensitive "Background" location permission.** Use cases may include: - To Receive location based support - Save you time at the Drive-thru - Get notified of exclusive in-Branch/in-store Services. **2) To explain to the end user that they must click "Allow all the time" on the following screen** [block:image] { "images": [ { "image": [ "https://files.readme.io/cf58da7-Screenshot_20201120-171633.png", "Screenshot_20201120-171633.png", 1080, 2280, "#333" ] } ] } [/block] Once the user accepts allowing background permissions, you will present them with the system background permission screen. Here, they must select "Allow all the time" [block:image] { "images": [ { "image": [ "https://files.readme.io/9f45447-Screenshot_20201120-161306.png", "Screenshot_20201120-161306.png", 1080, 2280, "#333" ] } ] } [/block] You should include the code below to request background location permissions. (as pictured above) [block:code] { "codes": [ { "code": "// Background Location Priming Screen\nif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\n int backgroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION);\n if (backgroundCheck != PackageManager.PERMISSION_GRANTED) {\n requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1);\n }\n}", "language": "java" } ] } [/block] Should you wish to skip the two step process above (which is not recommended) here is a code example to carry out the request permission checks in a single step. As part of your priming screen you must clearly define: 1) All of your use cases as to why you need background permission 2) You also must make it clear to the user that they must "Allow all the time" when brought to the location permission screen. [block:code] { "codes": [ { "code": "// Example Permission callback identifier, can be a different number\nint mLocationCode = 1;\nif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\n\tint foregroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);\n\tint backgroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION);\n\tif (foregroundCheck != PackageManager.PERMISSION_GRANTED) {\n\t\trequestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, mLocationCode);\n\t} else if (backgroundCheck != PackageManager.PERMISSION_GRANTED) {\n\t\trequestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, mLocationCode);\n\t}\n}\n\[email protected]\npublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {\n\tsuper.onRequestPermissionsResult(requestCode, permissions, grantResults);\n if (requestCode == mLocationCode) {\n \tif (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n \tif (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {\n \tint backgroundCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION);\n if (backgroundCheck != PackageManager.PERMISSION_GRANTED) {\n \trequestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, mLocationCode);\n }\n }\n }\n }\n}", "language": "java" } ] } [/block] [block:api-header] { "title": "Android 10" } [/block] In Android Manifest add - [block:code] { "codes": [ { "code": "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />\n<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />\n<uses-permission android:name=\"android.permission.ACCESS_BACKGROUND_LOCATION\" />", "language": "xml" } ] } [/block] When asking for location permission ask for it like this - [block:code] { "codes": [ { "code": "if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.Q) {\n\tActivityCompat.requestPermissions(activity,\n new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1);\n}", "language": "java" } ] } [/block] [block:api-header] { "title": "Android 9 and under" } [/block] In Android Manifest add - [block:code] { "codes": [ { "code": "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />\n<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />", "language": "xml" } ] } [/block] When asking for location permission ask for it like this - [block:code] { "codes": [ { "code": "ActivityCompat.requestPermissions(activity,\n new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);", "language": "java" } ] } [/block]