Skip to content

Commit 54b2e49

Browse files
authored
Show geofencing user consent dialog (#2795)
1 parent b641e4a commit 54b2e49

File tree

27 files changed

+695
-171
lines changed

27 files changed

+695
-171
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ Mapbox welcomes participation and contributions from everyone.
1212
* Dispatch view annotations update before rendering, so that view annotations and map layers are rendered simultaneously and thus decreasing the view annotations latency when using `ViewAnnotationUpdateMode.MAP_FIXED_DELAY` mode.
1313
* Overscale composited tile components in offline.
1414
* Skip rendering landmarks when the camera is inside them.
15+
* Introduce experimental Geofencing API. Implementation example: [GeofencingActivity.kt](app/src/main/java/com/mapbox/maps/testapp/examples/geofence/GeofencingActivity.kt)
1516
* [compose] Deprecate all `Annotation` and `AnnotationGroup` composables that take `onClick` parameter. Now all annotation interactions could be set with appropriate `AnnotationInteractionsState` or `AnnotationGroupInteractionsState` stored in `AnnotationGroupState`.
1617
* [compose] Introduce `AnnotationInteractionsState` and `AnnotationGroupInteractionsState` states that allow to set callbacks for annotation interactions via `onClicked()` and `onLongClicked()`.`PointAnnotationGroupInteractionsState` and `CircleAnnotationGroupInteractionsState` also provide ability to set callbacks for interactions with clusters via `onClusterClicked` and `onClusterLongClicked`.
1718
* [compose] Introduce `remember` (e.g. `rememberPolylineAnnotationGroupInteractionsState` and `rememberPolylineAnnotationInteractionsState`) composable functions to create, init and remember all types of `AnnotationInteractionsState` and `AnnotationGroupInteractionsState`.
1819
* [compose] Introduce `<AnnotationType>InteractionsState.isDraggable` / `<AnnotationType>GroupInteractionsState.isDraggable` API for all annotation types allowing to drag annotations. Callbacks `onDragStarted()`, `onDragged()`,`onDragFinished()` are added as well.
20+
* [compose] Introduce experimental `Attribution(..., geofencingDialog)` compose function to customize Geofencing consent dialog.
21+
* Introduce experimental `MapView.attribution..getMapAttributionDelegate().extraAttributions` to add custom attributions to the attribution dialog.
1922

2023
## Bug fixes 🐞
2124
* Improve zooming performance on dynamic Standard terrain and optimize terrain re-rendering performance on e.g routeline `line-trim-offset` change.

app/src/main/java/com/mapbox/maps/testapp/examples/CustomAttributionActivity.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ class CustomAttributionActivity : AppCompatActivity() {
4949
binding.customAttributionFab.setOnClickListener {
5050
Toast.makeText(this, R.string.custom_attribution_custom, Toast.LENGTH_LONG).show()
5151
val config = AttributionParserConfig(
52-
checkBoxes[0].isChecked,
53-
checkBoxes[1].isChecked,
54-
checkBoxes[2].isChecked,
55-
checkBoxes[3].isChecked,
56-
checkBoxes[4].isChecked,
52+
withImproveMap = checkBoxes[0].isChecked,
53+
withCopyrightSign = checkBoxes[1].isChecked,
54+
withTelemetryAttribution = checkBoxes[2].isChecked,
55+
withMapboxAttribution = checkBoxes[3].isChecked,
56+
withMapboxPrivacyPolicy = checkBoxes[4].isChecked,
57+
withMapboxGeofencingConsent = false // This custom dialog does not support geofencing user consent
5758
)
5859
attributionPlugin.setCustomAttributionDialogManager(
5960
CustomAttributionDialog(this, config)

app/src/main/java/com/mapbox/maps/testapp/examples/geofence/GeofencingActivity.kt

Lines changed: 6 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,15 @@ package com.mapbox.maps.testapp.examples.geofence
22

33
import android.Manifest
44
import android.annotation.SuppressLint
5-
import android.app.Activity
6-
import android.app.AlertDialog
75
import android.app.NotificationChannel
86
import android.app.NotificationManager
97
import android.app.PendingIntent
10-
import android.content.ActivityNotFoundException
118
import android.content.Context
12-
import android.content.DialogInterface
139
import android.content.Intent
1410
import android.content.pm.PackageManager
15-
import android.net.Uri
1611
import android.os.Build
1712
import android.os.Bundle
1813
import android.view.View
19-
import android.widget.ArrayAdapter
2014
import android.widget.Toast
2115
import androidx.activity.result.ActivityResultLauncher
2216
import androidx.activity.result.contract.ActivityResultContracts
@@ -54,10 +48,7 @@ import com.mapbox.maps.logD
5448
import com.mapbox.maps.logW
5549
import com.mapbox.maps.plugin.PuckBearing
5650
import com.mapbox.maps.plugin.attribution.Attribution
57-
import com.mapbox.maps.plugin.attribution.AttributionDialogManager
58-
import com.mapbox.maps.plugin.attribution.AttributionParserConfig
5951
import com.mapbox.maps.plugin.attribution.attribution
60-
import com.mapbox.maps.plugin.delegates.MapAttributionDelegate
6152
import com.mapbox.maps.plugin.locationcomponent.OnIndicatorPositionChangedListener
6253
import com.mapbox.maps.plugin.locationcomponent.createDefault2DPuck
6354
import com.mapbox.maps.plugin.locationcomponent.location
@@ -362,8 +353,12 @@ class GeofencingActivity : AppCompatActivity() {
362353
return@ClickInteraction true
363354
}
364355
)
365-
binding.mapView.attribution.setCustomAttributionDialogManager(CustomAttributionDialog(this))
366-
356+
binding.mapView.attribution.getMapAttributionDelegate().extraAttributions = listOf(
357+
Attribution(
358+
"Geofence boundaries courtesy Helsingin seuden liiken HSL (CC-BY)",
359+
"https://hri.fi/data/en_GB/dataset/hsl-n-taksavyohykkeet"
360+
)
361+
)
367362
handleGeofenceIntent(intent)
368363
}
369364

@@ -603,78 +598,6 @@ class GeofencingActivity : AppCompatActivity() {
603598
}
604599
}
605600

606-
/***
607-
* Custom attribution to show the link to HSL public dataset
608-
*/
609-
inner class CustomAttributionDialog(
610-
private val context: Context,
611-
) : AttributionDialogManager, DialogInterface.OnClickListener {
612-
613-
private lateinit var attributionList: MutableList<Attribution>
614-
private var dialog: AlertDialog? = null
615-
private var mapAttributionDelegate: MapAttributionDelegate? = null
616-
617-
override fun showAttribution(mapAttributionDelegate: MapAttributionDelegate) {
618-
this.mapAttributionDelegate = mapAttributionDelegate
619-
attributionList =
620-
mapAttributionDelegate.parseAttributions(
621-
context,
622-
AttributionParserConfig()
623-
).toMutableList()
624-
625-
// HSL Attribution
626-
attributionList.add(
627-
0,
628-
Attribution(
629-
"Geofence boundaries courtesy Helsingin seuden liiken HSL (CC-BY)",
630-
"https://hri.fi/data/en_GB/dataset/hsl-n-taksavyohykkeet"
631-
)
632-
)
633-
var isActivityFinishing = false
634-
if (context is Activity) {
635-
isActivityFinishing = context.isFinishing
636-
}
637-
if (!isActivityFinishing) {
638-
val attributionTitles = attributionList.map { it.title }.toTypedArray()
639-
val builder = AlertDialog.Builder(context)
640-
builder.setTitle(com.mapbox.maps.plugin.attribution.R.string.mapbox_attributionsDialogTitle)
641-
builder.setAdapter(
642-
ArrayAdapter(
643-
context,
644-
com.mapbox.maps.plugin.attribution.R.layout.mapbox_attribution_list_item,
645-
attributionTitles
646-
),
647-
this
648-
)
649-
dialog = builder.show()
650-
}
651-
}
652-
653-
override fun onStop() {
654-
dialog?.takeIf { it.isShowing }?.dismiss()
655-
}
656-
657-
override fun onClick(dialog: DialogInterface?, which: Int) {
658-
showWebPage(attributionList[which].url)
659-
}
660-
661-
private fun showWebPage(url: String) {
662-
if (context is Activity) {
663-
try {
664-
val intent = Intent(Intent.ACTION_VIEW)
665-
intent.data = Uri.parse(url)
666-
context.startActivity(intent)
667-
} catch (exception: ActivityNotFoundException) {
668-
Toast.makeText(
669-
context,
670-
com.mapbox.maps.plugin.attribution.R.string.mapbox_attributionErrorNoBrowser,
671-
Toast.LENGTH_LONG
672-
).show()
673-
}
674-
}
675-
}
676-
}
677-
678601
companion object {
679602
private const val TAG = "GeofencingActivity"
680603

extension-compose/api/Release/metalava.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,9 @@ package com.mapbox.maps.extension.compose.ornaments.attribution {
992992

993993
@androidx.compose.runtime.Immutable @com.mapbox.maps.extension.compose.MapboxMapScopeMarker public final class MapAttributionScope {
994994
method @androidx.compose.runtime.Composable public void Attribution(androidx.compose.ui.Modifier modifier = Modifier, androidx.compose.foundation.layout.PaddingValues contentPadding = PaddingValues(92.dp, 4.dp, 4.dp, 4.dp), androidx.compose.ui.Alignment alignment = androidx.compose.ui.Alignment.Companion.BottomStart, long iconColor = Color(4280192171), kotlin.jvm.functions.Function3<? super java.util.List<com.mapbox.maps.plugin.attribution.Attribution>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function1<? super com.mapbox.maps.plugin.attribution.Attribution,kotlin.Unit>,kotlin.Unit> attributionDialog = { attributions, onDismissRequest, onAttributionClick -> AttributionDialog(attributions, onDismissRequest, onAttributionClick) }, kotlin.jvm.functions.Function4<? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> telemetryDialog = { onDismissRequest, onMoreInfo, onDisagree, onAgree -> TelemetryDialog(onDismissRequest, onMoreInfo, onDisagree, onAgree) });
995+
method @androidx.compose.runtime.Composable @com.mapbox.maps.MapboxExperimental public void Attribution(androidx.compose.ui.Modifier modifier = Modifier, androidx.compose.foundation.layout.PaddingValues contentPadding = PaddingValues(92.dp, 4.dp, 4.dp, 4.dp), androidx.compose.ui.Alignment alignment = androidx.compose.ui.Alignment.Companion.BottomStart, long iconColor = Color(4280192171), kotlin.jvm.functions.Function3<? super java.util.List<com.mapbox.maps.plugin.attribution.Attribution>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function1<? super com.mapbox.maps.plugin.attribution.Attribution,kotlin.Unit>,kotlin.Unit> attributionDialog = { attributions, onDismissRequest, onAttributionClick -> AttributionDialog(attributions, onDismissRequest, onAttributionClick) }, kotlin.jvm.functions.Function4<? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> telemetryDialog = { onDismissRequest, onMoreInfo, onDisagree, onAgree -> TelemetryDialog(onDismissRequest, onMoreInfo, onDisagree, onAgree) }, kotlin.jvm.functions.Function4<? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super kotlin.jvm.functions.Function0<kotlin.Unit>,? super java.lang.Boolean,kotlin.Unit> geofencingConsentDialog = { onDismissRequest, onDisagree, onAgree, currentUserConsent -> GeofencingConsentDialog(onDismissRequest, onDisagree, onAgree, currentUserConsent) });
995996
method @androidx.compose.runtime.Composable public void AttributionDialog(java.util.List<com.mapbox.maps.plugin.attribution.Attribution> attributions, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function1<? super com.mapbox.maps.plugin.attribution.Attribution,kotlin.Unit> onAttributionClick);
997+
method @androidx.compose.runtime.Composable public void GeofencingConsentDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> onDisagree, kotlin.jvm.functions.Function0<kotlin.Unit> onAgree, boolean currentUserConsent);
996998
method @androidx.compose.runtime.Composable public void TelemetryDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> onMoreInfo, kotlin.jvm.functions.Function0<kotlin.Unit> onDisagree, kotlin.jvm.functions.Function0<kotlin.Unit> onAgree);
997999
}
9981000

extension-compose/api/extension-compose.api

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -782,24 +782,18 @@ public final class com/mapbox/maps/extension/compose/ornaments/attribution/Compo
782782
public static final field INSTANCE Lcom/mapbox/maps/extension/compose/ornaments/attribution/ComposableSingletons$MapAttributionScopeKt;
783783
public static field lambda-1 Lkotlin/jvm/functions/Function2;
784784
public static field lambda-2 Lkotlin/jvm/functions/Function2;
785-
public static field lambda-3 Lkotlin/jvm/functions/Function3;
786-
public static field lambda-4 Lkotlin/jvm/functions/Function3;
787-
public static field lambda-5 Lkotlin/jvm/functions/Function3;
788-
public static field lambda-6 Lkotlin/jvm/functions/Function2;
789-
public static field lambda-7 Lkotlin/jvm/functions/Function2;
785+
public static field lambda-3 Lkotlin/jvm/functions/Function4;
790786
public fun <init> ()V
791787
public final fun getLambda-1$extension_compose_release ()Lkotlin/jvm/functions/Function2;
792788
public final fun getLambda-2$extension_compose_release ()Lkotlin/jvm/functions/Function2;
793-
public final fun getLambda-3$extension_compose_release ()Lkotlin/jvm/functions/Function3;
794-
public final fun getLambda-4$extension_compose_release ()Lkotlin/jvm/functions/Function3;
795-
public final fun getLambda-5$extension_compose_release ()Lkotlin/jvm/functions/Function3;
796-
public final fun getLambda-6$extension_compose_release ()Lkotlin/jvm/functions/Function2;
797-
public final fun getLambda-7$extension_compose_release ()Lkotlin/jvm/functions/Function2;
789+
public final fun getLambda-3$extension_compose_release ()Lkotlin/jvm/functions/Function4;
798790
}
799791

800792
public final class com/mapbox/maps/extension/compose/ornaments/attribution/MapAttributionScope {
801793
public final fun Attribution-fWhpE4E (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/ui/Alignment;JLkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function6;Landroidx/compose/runtime/Composer;II)V
794+
public final fun Attribution-hYmLsZ8 (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/ui/Alignment;JLkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function6;Lkotlin/jvm/functions/Function6;Landroidx/compose/runtime/Composer;II)V
802795
public final fun AttributionDialog (Ljava/util/List;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
796+
public final fun GeofencingConsentDialog (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;ZLandroidx/compose/runtime/Composer;I)V
803797
public final fun TelemetryDialog (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
804798
}
805799

0 commit comments

Comments
 (0)