Я пытаюсь шаг за шагом перенести обработку разрешений камеры из основной активности во фрагмент, не перенося всю устаревшую логику.
После миграции камера открывается неправильно. Я бы хотел, чтобы камера запускалась сразу после нажатия «разрешить» в диалоговом окне разрешений.
ВОСПРОИЗВЕДЕНИЕ
(Смотрите пример кода фрагмента) Когда я нажимаю в первый раз, в консоли отображается журнал «noPermission», но после нажатия «Разрешить» ничего не происходит (то же самое, когда я нажимаю «Запретить»), хотя после второго нажатия камера запускается и я получаю журнал "hasPermission".
MainActivity.kt (устаревшая логика разрешений)
Код: Выделить всё
@SuppressLint("MissingSuperCall")
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array,
grantResults: IntArray
) {
if (requestCode == REQUEST_CODE_MAIN_ACTIVITY) {
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
alertDialog = localizationProvider.showManualLocationPickerDialog(
this,
REQUEST_CODE_MAIN_ACTIVITY
)
return
}
}
// I removed it
// if (requestCode == CameraPermissionHelper.CAMERA_REQUEST_CODE) {
// if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// handler.post {
// navigateToCamera()
// }
// } else {
// showCameraDialogPermission()
// }
// }
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host) as? NavHostFragment
navHostFragment?.childFragmentManager?.fragments?.forEach { frag ->
frag.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
Код: Выделить всё
class LocalizationProvider(private val application: Application) {
val requestCode = 99
fun checkIfPermissionIsGranted(): Boolean {
return if (VERSION.SDK_INT >= VERSION_CODES.M) {
application.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
} else {
ContextCompat.checkSelfPermission(
application.applicationContext,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
}
}
fun shouldShowRationale(activity: Activity): Boolean {
return if (VERSION.SDK_INT >= VERSION_CODES.M) {
activity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
ActivityCompat.shouldShowRequestPermissionRationale(
activity,
Manifest.permission.ACCESS_FINE_LOCATION
)
}
}
fun askForPermission(activity: Activity, requestCode: Int? = null) {
val requestCodeFinal = requestCode ?: MY_PERMISSIONS_REQUEST_LOCATION
if (VERSION.SDK_INT >= VERSION_CODES.M) {
activity.requestPermissions(
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
requestCodeFinal
)
} else {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
requestCodeFinal
)
}
}
...
}
Код: Выделить всё
private const val PERMISSION = Manifest.permission.CAMERA
// inside onViewCreated()
ViewModel.visibleFabs.observe(viewLifecycleOwner) { items ->
fabMenuView.submitItems(items) { item ->
when (item) {
is FabItem.Camera -> fabClick()
...
}
}
}
private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
Log.d("Church permission", "CALLBACK: granted=$granted")
if (granted) {
onTrailCameraFabClick()
}
}
private fun fabClick() {
if (requireContext().hasPermission(PERMISSION)) {
Log.d("Church permission", "hasPermission")
onTrailCameraFabClick()
} else {
Log.d("Church permission", "noPermission")
requestPermissionLauncher.launch(PERMISSION)
}
}
fun Context.hasPermission(permission: String) =
ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
- Я добавил разрешение камеры в AndroidManifest.xml
- Я добавляю следующие пакеты:и
Код: Выделить всё
"androidx.activity:activity-ktx:1.8.2"Код: Выделить всё
implementation "androidx.fragment:fragment-ktx:1.6.2"
Подробнее здесь: https://stackoverflow.com/questions/798 ... resultcont
Мобильная версия