@@ -425,6 +425,15 @@ class ArcGISArView : FrameLayout, DefaultLifecycleObserver, Scene.OnUpdateListen
425
425
cameraController.translationFactor = value
426
426
}
427
427
428
+ /* *
429
+ * List of permissions requested during this session.
430
+ *
431
+ * @since 100.6.1
432
+ */
433
+ private val requestedPermissions: MutableList <String > by lazy {
434
+ ArrayList <String >()
435
+ }
436
+
428
437
/* *
429
438
* Exposes an [Exception] should it occur when using this view.
430
439
*
@@ -559,9 +568,18 @@ class ArcGISArView : FrameLayout, DefaultLifecycleObserver, Scene.OnUpdateListen
559
568
// permission on Android M and above, now is a good time to ask the user for it.
560
569
// when the permission is requested and the user responds to the request from the OS this is executed again
561
570
// during onResume()
562
- if (isUsingARCore == ARCoreUsage .YES && renderVideoFeed && ! hasPermission(CAMERA_PERMISSION )) {
563
- requestPermission(context as Activity , CAMERA_PERMISSION , CAMERA_PERMISSION_CODE )
564
- return
571
+ if (isUsingARCore == ARCoreUsage .YES && ! hasPermission(CAMERA_PERMISSION )) {
572
+ if (permissionHasBeenPermanentlyDenied(context as Activity , CAMERA_PERMISSION )) {
573
+ error = Exception (
574
+ resources.getString(
575
+ R .string.arcgis_ar_view_exception_permission_permanently_denied,
576
+ CAMERA_PERMISSION
577
+ )
578
+ )
579
+ } else {
580
+ requestPermission(context as Activity , CAMERA_PERMISSION , CAMERA_PERMISSION_CODE )
581
+ return
582
+ }
565
583
}
566
584
567
585
if (isUsingARCore == ARCoreUsage .YES ) {
@@ -607,11 +625,20 @@ class ArcGISArView : FrameLayout, DefaultLifecycleObserver, Scene.OnUpdateListen
607
625
// Request location permission if user has provided a LocationDataSource
608
626
locationDataSource?.let {
609
627
if (! hasPermission(LOCATION_PERMISSION )) {
610
- requestPermission(
611
- context as Activity ,
612
- LOCATION_PERMISSION ,
613
- LOCATION_PERMISSION_CODE
614
- )
628
+ if (permissionHasBeenPermanentlyDenied(context as Activity , LOCATION_PERMISSION )) {
629
+ error = Exception (
630
+ resources.getString(
631
+ R .string.arcgis_ar_view_exception_permission_permanently_denied,
632
+ LOCATION_PERMISSION
633
+ )
634
+ )
635
+ } else {
636
+ requestPermission(
637
+ context as Activity ,
638
+ LOCATION_PERMISSION ,
639
+ LOCATION_PERMISSION_CODE
640
+ )
641
+ }
615
642
return
616
643
}
617
644
}
@@ -838,13 +865,36 @@ class ArcGISArView : FrameLayout, DefaultLifecycleObserver, Scene.OnUpdateListen
838
865
) == PackageManager .PERMISSION_GRANTED
839
866
}
840
867
868
+ /* *
869
+ * We use [ActivityCompat.shouldShowRequestPermissionRationale] as a workaround to detect whether
870
+ * the user has denied the permission permanently, i.e. has selected `Don't Ask Again`. There is
871
+ * no official API to detect that, so we use a variation of a workaround described here:
872
+ * https://blog.usejournal.com/method-to-detect-if-user-has-selected-dont-ask-again-while-requesting-for-permission-921b95ded536
873
+ *
874
+ * Checks [requestedPermissions] property for permission to determine if it has already been
875
+ * requested this session. Returns false if permission has never been requested and therefore the
876
+ * user has not selected `Don't Ask Again`. Returns true otherwise.
877
+ *
878
+ * @since 100.6.1
879
+ */
880
+ private fun permissionHasBeenPermanentlyDenied (
881
+ activity : Activity ,
882
+ permission : String
883
+ ): Boolean {
884
+ return requestedPermissions.contains(permission) && ActivityCompat .shouldShowRequestPermissionRationale(
885
+ activity,
886
+ permission
887
+ ).not ()
888
+ }
889
+
841
890
/* *
842
891
* Request a [permission] using the provided [activity] and [permissionCode].
843
892
*
844
893
* @since 100.6.0
845
894
*/
846
895
private fun requestPermission (activity : Activity , permission : String , permissionCode : Int ) {
847
896
ActivityCompat .requestPermissions(activity, arrayOf(permission), permissionCode)
897
+ requestedPermissions.add(permission)
848
898
}
849
899
850
900
/* *
0 commit comments