Skip to content

Commit 530f99b

Browse files
tomaszrybakiewiczabhishek1508
authored andcommitted
Using view-less Fragment to request location permissions.
1 parent 6bf33fc commit 530f99b

2 files changed

Lines changed: 75 additions & 2 deletions

File tree

libnavui-dropin/src/main/java/com/mapbox/navigation/dropin/permission/LocationPermissionComponent.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Context
55
import androidx.activity.ComponentActivity
66
import androidx.activity.result.ActivityResultCallback
77
import androidx.activity.result.contract.ActivityResultContracts
8+
import androidx.fragment.app.FragmentActivity
89
import androidx.lifecycle.Lifecycle
910
import androidx.lifecycle.repeatOnLifecycle
1011
import com.mapbox.android.core.permissions.PermissionsManager
@@ -63,8 +64,12 @@ internal class LocationPermissionComponent(
6364
store.dispatch(TripSessionStarterAction.OnLocationPermission(true))
6465
}
6566
} else {
66-
launcher?.launch(LOCATION_PERMISSIONS)
67-
67+
val fragActivity = componentActivityRef.get() as? FragmentActivity
68+
if (fragActivity != null) {
69+
PermissionsLauncherFragment.create(fragActivity, LOCATION_PERMISSIONS, callback)
70+
} else {
71+
launcher?.launch(LOCATION_PERMISSIONS)
72+
}
6873
notifyGrantedOnForegrounded(mapboxNavigation.navigationOptions.applicationContext)
6974
}
7075
}
@@ -93,6 +98,9 @@ internal class LocationPermissionComponent(
9398
override fun onDetached(mapboxNavigation: MapboxNavigation) {
9499
super.onDetached(mapboxNavigation)
95100

101+
(componentActivityRef.get() as? FragmentActivity)?.also {
102+
PermissionsLauncherFragment.destroy(it)
103+
}
96104
launcher?.unregister()
97105
}
98106

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.mapbox.navigation.dropin.permission
2+
3+
import android.content.Context
4+
import android.content.pm.PackageManager.PERMISSION_GRANTED
5+
import androidx.activity.result.ActivityResultCallback
6+
import androidx.activity.result.ActivityResultCaller
7+
import androidx.activity.result.ActivityResultLauncher
8+
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
9+
import androidx.core.content.ContextCompat.checkSelfPermission
10+
import androidx.fragment.app.Fragment
11+
import androidx.fragment.app.FragmentActivity
12+
13+
/**
14+
* A view-less fragment that requests permissions using [ActivityResultCaller] interface.
15+
*/
16+
internal class PermissionsLauncherFragment(
17+
private val permissions: Array<String>,
18+
private val onResult: ActivityResultCallback<Map<String, Boolean>>
19+
) : Fragment() {
20+
21+
private var launcher: ActivityResultLauncher<Array<String>>? = null
22+
23+
override fun onAttach(context: Context) {
24+
super.onAttach(context)
25+
val areGranted = permissions.fold(false) { acc, permission ->
26+
acc && checkSelfPermission(context, permission) == PERMISSION_GRANTED
27+
}
28+
if (!areGranted) {
29+
launcher = registerForActivityResult(RequestMultiplePermissions(), onResult)
30+
launcher?.launch(permissions)
31+
}
32+
}
33+
34+
override fun onDetach() {
35+
super.onDetach()
36+
launcher?.unregister()
37+
}
38+
39+
companion object {
40+
const val TAG = "MapboxPermissionsLauncherFragment"
41+
42+
fun create(
43+
fragActivity: FragmentActivity,
44+
permissions: Array<String>,
45+
onResult: ActivityResultCallback<Map<String, Boolean>>
46+
) {
47+
fragActivity.supportFragmentManager.apply {
48+
val t = beginTransaction()
49+
findFragmentByTag(TAG)?.also { t.remove(it) }
50+
t.add(PermissionsLauncherFragment(permissions, onResult), TAG)
51+
t.commit()
52+
}
53+
}
54+
55+
fun destroy(fragActivity: FragmentActivity) {
56+
if (!fragActivity.isFinishing) {
57+
fragActivity.supportFragmentManager.apply {
58+
findFragmentByTag(TAG)?.also {
59+
beginTransaction().remove(it).commit()
60+
}
61+
}
62+
}
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)