Начать намерение из ViewModel

Я хотел бы запустить службу переднего плана и вызвать LauncherForActivityResult.

Насколько мне известно, я не могу ни запустить службу из ViewModel, ни вызвать LauncherForActivityResult.

Я работаю над приложением для Android, и вначале я просто писал код без реальных архитектурных решений. Но по мере того, как мое приложение росло, я хочу разделить его на отдельные модули. У меня есть BottomBar, где пользователь может ввести некоторую информацию и запустить службу переднего плана, которая просто отслеживает его местоположение. При нажатии кнопки я хочу проверить входные данные в ViewModel и, если они верны, запустить Службу. Но, насколько я знаю, ViewModel не должна знать о контексте Android.

Я хотел бы создать сервис запроса разрешения, который я мог бы использовать с любого экрана, возможно, передавая контекст. Или мой другой вариант заключался в создании функции обратного вызова в viewModel и передаче LocalContext.current, поскольку вы можете получить к ней доступ в Composables.

Мой текущий подход заключается в следующем:

Button(
     modifier = Modifier.align(Alignment.CenterHorizontally),
     onClick = {
          permissionsResultLauncher.launch(
               arrayOf(
                   Manifest.permission.ACCESS_COARSE_LOCATION,
                   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
                         Manifest.permission.POST_NOTIFICATIONS
                   else ""
               )
          )
     // TODO: Only start service if permissions are granted
     // TODO: Handle starting service in the ViewModel
     Intent(context, PatrolService::class.java).also {
          it.action = PatrolService.Actions.START.toString()
          context.startService(it)
     }
}) {
     Text(text = "Járőrözés kezdése")
}

Другая моя проблема заключалась в том, что я могу запросить разрешение, но как я могу проверить, были ли они приняты, поскольку вызов намерения для запуска службы приводит к сбою приложения, если разрешения на уведомления и определение местоположения не принимаются.

2
0
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Но, насколько я знаю, ViewModel не должна знать о контексте Android.

В частности, существует AndroidViewModel для предоставления синглтона Application в качестве Context. Или вы можете использовать предпочитаемую вами структуру инверсии зависимостей (Dagger/Hilt, Koin и т. д.), чтобы внедрить Application в вашу модель представления.

Я хотел бы сделать сервис для запроса разрешения

Во-первых, это непрактично. Служба не может запустить пользовательский интерфейс; запрос разрешения включает запуск пользовательского интерфейса.

Во-вторых, смысл обычного сервиса переднего плана заключается в том, чтобы делать что-то, когда у вас нет пользовательского интерфейса на переднем плане и вам нужно делать эти вещи постоянно. Запрос разрешения имеет смысл только в том случае, если у вас есть пользовательский интерфейс на переднем плане, поскольку пользователю необходимо ответить на пользовательский интерфейс для получения разрешения.

Конечно, есть сценарии, когда требуется услуга. Их гораздо меньше, чем могут подумать новички в Android.

который я мог бы использовать с любого экрана

Служба не является заменой стандартных шаблонов повторного использования, таких как наследование и композиция.

Мой текущий подход заключается в следующем

Запуск запроса разрешения из компонуемого объекта — это нормально. Если у вас есть законная потребность в сервисе и вы хотите управлять этим сервисом из модели представления, вы можете это сделать.

поскольку вызов намерения запустить службу приводит к сбою приложения, если разрешения на уведомление и местоположение не принимаются

Ваша служба должна проверить, были ли приняты разрешения, прежде чем выполнять работу, требующую этих разрешений. Если разрешение на уведомление предоставлено, а другие нет, служба может затем поднять Notification, чтобы вернуть пользователя в ваш пользовательский интерфейс, где пользователь может предоставить эти разрешения.

Ваш сервис или модель представления (или, возможно, ваш составной объект) может проверить, было ли предоставлено конкретное разрешение (используя checkSelfPermission() в Context IIRC).

Другие вопросы по теме