The indigitall SDK can manage the user's location. This allows you to use the location filters on the send push campaign screen ( Campaigns> Push> New push campaign > Filters> Geographical Filters)
Once we have enabled this functionality, the end user will have to give their consent to the location permission and enable the location services of their smartphone, so that the application can obtain the exact location of the user.
x
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
You can find the AndroidManifest.xml file in the following path:
Options to keep in mind
There are two ways to manage location permissions:
- Manual: It is the default option and the developer is in charge of managing the location permissions.
- Automatic: It is the SDK that manages the location permissions.
Here we explain how to configure location permissions in automatic mode.
The AutoRequestPermissionLocation parameter must be added when the SDK is initialized. This is done using the following code excerpt:
//When you want to initialize indigitall
Configuration config = new Configuration
.Builder("<YOUR-APP-KEY>", "<YOUR-SENDER-ID>")
.setAutoRequestPermissionLocation(true)
.build();
Indigitall.init(context, config);
In Android there is a class where the status of the permissions is received after the user has changed them through the configuration. The following piece of code should be added to capture the status of the permissions:
//In the class you use to receive the results of asking for the permissions
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Indigitall.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
Request background location: Android 11 and higher
When a feature in your app requests background location on a device that runs Android 10 (API level 29), the system permissions dialog includes an option named Allow all the time. If the user selects this option, the feature in your app gains background location access.
On Android 11 (API level 30) and higher, however, the system dialog doesn't include the Allow all the time option. Instead, users must enable background location on a settings page, as shown in following figure.
App targets Android 11 or higher
If your app hasn't been granted the ACCESS_BACKGROUND_LOCATION permission, and shouldShowRequestPermissionRationale() returns true, show an educational UI to users that includes the following:
- A clear explanation of why your app's feature needs access to background location.
- The user-visible label of the settings option that grants background location (for example, Allow all the time in previous figure). You can call getBackgroundPermissionOptionLabel() to get this label. The return value of this method is localized to the user's device language preference.
- An option for users to decline the permission. If users decline background location access, they should be able to continue using your app.
Simple Example code without explanation background access
class MainActivity : AppCompatActivity() {
[...]
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
Indigitall.onRequestPermissionsResult(this, requestCode, permissions, grantResults)
if (requestCode == Constants.REQUEST_PERMISSION_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Location permission granted")
// Show info about background permissions
requestBackgroundPermission(this)
} else {
Log.e(TAG, "Location permission denied")
Toast.makeText(
this,
"Location permission is required for this feature",
Toast.LENGTH_SHORT
).show()
}
} else if (requestCode == BACKGROUND_LOCATION_REQUEST_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Background location permission granted")
} else {
Log.e(TAG, "Background location permission denied")
}
}
}
// go to location permission menu
fun requestBackgroundPermission(activity: Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
BACKGROUND_LOCATION_REQUEST_CODE
)
}
}
Complete example code
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
// Pass the result to the SDK
Indigitall.onRequestPermissionsResult(this, requestCode, permissions, grantResults)
when (requestCode) {
Constants.REQUEST_PERMISSION_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Fine location granted")
// Ask for background permission after fine location is granted
requestBackgroundPermissionWithRationale()
} else {
Log.e(TAG, "Fine location denied")
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show rationale before asking again
showRationaleDialog(
"We need your location to send you personalized notifications. Without this permission, some features will not be available."
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
Constants.REQUEST_PERMISSION_CODE
)
}
} else {
Toast.makeText(
this,
"Permission is required. Enable it in Settings if you have permanently denied it.",
Toast.LENGTH_LONG
).show()
}
}
}
BACKGROUND_LOCATION_REQUEST_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Background location granted")
} else {
Log.e(TAG, "Background location denied")
}
}
}
}
private fun requestBackgroundPermissionWithRationale() {
val permission = Manifest.permission.ACCESS_BACKGROUND_LOCATION
when {
ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED -> {
Log.d(TAG, "Background location already granted")
}
shouldShowRequestPermissionRationale(permission) -> {
// Show rationale before requesting background location
showRationaleDialog(
"To continue receiving notifications even when the app is closed, we need background location access."
) {
requestBackgroundPermission(this)
}
}
else -> {
// Request directly if no rationale is needed
requestBackgroundPermission(this)
}
}
}
fun requestBackgroundPermission(activity: Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
BACKGROUND_LOCATION_REQUEST_CODE
)
}
}
private fun showRationaleDialog(message: String, onPositive: () -> Unit) {
AlertDialog.Builder(this)
.setTitle("Permission required")
.setMessage(message)
.setPositiveButton("Allow") { _, _ -> onPositive() }
.setNegativeButton("Cancel", null)
.show()
}