Использование BroadcastReceiver на уровне данных приложения AndroidAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Использование BroadcastReceiver на уровне данных приложения Android

Сообщение Anonymous »

Я новичок в мобильной разработке и пытаюсь создать свое первое приложение для Android, используя Kotlin и Jetpack Compose. Настоящее приложение должно просто сканировать видимые точки доступа и отображать их в списке. Даже если приложение очень простое, я хочу следовать рекомендуемой архитектуре приложения, поэтому я следую следующему руководству из официальной документации. Это означает, что у меня есть уровень пользовательского интерфейса с компонуемыми объектами и ViewModel (держатель состояния), а также уровень данных с бизнес-логикой.
Проблема, с которой я сталкиваюсь, заключается в том, что Мне нужно зарегистрировать прослушиватель широковещательной передачи, а затем запросить сканирование (см. это), но для этого мне нужно использовать контекст, который недоступен ни в моей ViewModel, ни в моем классе репозитория. Также я не могу найти лучший способ передать результаты сканирования в ViewModel.
Это мой простой пользовательский интерфейс (MainActivity):

Код: Выделить всё

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
MyTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
AccessPointsListScreen()
}
}
}
}

@Composable
fun AccessPointsListScreen(
accessPointsViewModel: AccessPointsViewModel = viewModel())
) {
// State to hold the scan results
val accessPointsUiState by accessPointsViewModel.uiState.collectAsState()

AccessPoints(
accessPointsList = accessPointsUiState.accessPointsList
)
}

@Composable
private fun AccessPoints(
accessPointsList: List
) {
// Omit implementation of UI
}
Вот мой класс ViewModel:

Код: Выделить всё

/**
* UI state for the Access Points
*/
data class AccessPointsUiState(
val accessPointsList: List = emptyList()
)

/**
* ViewModel that handles the logic of the access points screen
*/
class AccessPointsViewModel(
private val accessPointsRepository: AccessPointsRepository
): ViewModel() {
private val _uiState = MutableStateFlow(AccessPointsUiState())
val uiState: StateFlow = _uiState.asStateFlow()

init {
refreshAccessPoints()
}

/**
* Refresh access points and update the UI state
*/
fun refreshAccessPoints() {
viewModelScope.launch {
val result = accessPointsRepository.scanAccessPoints()
// Omit logic to update state
}
}
}

и, наконец, мой класс репозитория (уровень данных):

Код: Выделить всё

class AccessPointsRepository {
suspend fun scanAccessPoints(): List {
// How do I proceed here??
val wifiScanReceiver: BroadcastReceiver = WifiScanReceiver() // Should I instantiate this here??

// Register a broadcast listener for SCAN_RESULTS_AVAILABLE_ACTION, which is called when scan requests are completed
registerReceiver(wifiScanReceiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) // This is incorrect, I need the context

val success = wifiManager.startScan() // This won't work without initializing wifiManager, for which I need the context
}
}

class WifiScanReceiver: BroadcastReceiver() {
var scanResultList = mutableListOf()
lateinit var wifiManager: WifiManager // Where do I initialize this if I need the context??

override fun onReceive(context: Context, intent: Intent) {
val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
if (!success) {
// Omit
}

scanResultList = wifiManager.scanResults // wifiManager is not initialized
// Where and how do I return the scanResultList??
}
}
Итак, как мне использовать/создать приемник широковещательной рассылки в классе AccessPointsRepository, если у меня нет контекста? Хорошо ли он там расположен или лучше вписывается в ViewModel? Мне удалось заставить его работать, когда я писал все в файле MainActivity, так что проблема не в самой реализации, а скорее в том, какой подход лучше всего использовать в чистой архитектуре, сохраняющей разделение задач. увидел, что AndroidViewModel имеет ссылку на контекст приложения, но похоже, что ее использование не является хорошей практикой.
Я также не понимаю, как мне следует передать List из метода onReceive до моего класса ViewModel. Такое ощущение, что я делаю некоторые вещи в корне неправильно.
Может ли кто-нибудь дать какие-либо рекомендации о том, как мне действовать, следуя лучшим архитектурным принципам? Заранее спасибо, ребята!

Подробнее здесь: https://stackoverflow.com/questions/791 ... data-layer
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»